<commit_before>/*
 * TODO: smooth snapping
 * TODO: aria
 * TODO: refactoring
 * TODO: more refactoring
 */
var H5P = H5P || {};

H5P.Agamotto = function ($) {
  /**
   * Constructor function.
   *
   * @param {object} options from semantics.json.
   * @param {number} content id.
   */
  function C(options, id) {
    if (!options.items) {
      return;
    }

    // Remove items with missing image
    for (var i = 0; i < options.items.length; i++) {
      if (options.items[i].image === undefined) {
        console.log('An image is missing. I will continue without it, but please check your settings.');
        options.items.splice(i, 1);
        i--;
      }
    }
    // Restrict to 50 images
    options.items = options.items.splice(0, 50);
    this.options = options;

    this.maxItem = this.options.items.length - 1;
    if (this.maxItem > 100) {
      console.log('You have more than 100 images. This will not work well.');
    }

    this.image1, this.image2 = undefined;
    this.description1, this.description2 = undefined;

    // TODO: include other variables

    this.sliderTrackWidth = 0;
    this.sliderThumbPosition = 0;

    this.index = 0;
    this.opacity = 1;

    // Set hasDescription = true if at least one item has a description
    this.hasDescription = false;
    for (var i = 0; i < this.maxItem + 1; i++) {
      if (this.options.items[i].description !== '') {
        this.hasDescription = true;
        break;
      }
    }
    this.id = id;

    /**
     * Get maximum height of all descriptions.
     * Expects the DOM to be already setup.
     *
     * @return {number} - The maximum height of all descriptions.
     */
    this.getMaxDescriptionHeight = function() {
      var maxDescriptionHeight = 0;
      for (var i = 0; i < this.maxItem + 1; i++) {
        this.description2.innerHTML = this.options.items[i].description;
        maxDescriptionHeight = Math.max(maxDescriptionHeight, this.description2.offsetHeight);
      }
      return maxDescriptionHeight;
    };

    /**
     * Map a value from one range to another.
     *
     * @param {number} value - the value to me remapped.
     * @param {number} lo1 - lower boundary of first range.
     * @param {number} hi1 - upper boundary of first range.
     * @param {number} lo2 - lower boundary of second range.
     * @param {number} hi2 - upper boundary of second range.
     * @return {number} - remapped value.
     */
    this.map = function (value, lo1, hi1, lo2, hi2) {
      return lo2 + (hi2 - lo2) * (value - lo1) / (hi1 - lo1);
    };

    /**
     * Constrain a number value within a range.
     *
     * @param {number} value - value to be constrained.
     * @param {number} lo - lower boundary of the range.
     * @param {number} hi - upper boundary of the range.
     * @returns {number} - constrained value.
     */
    this.constrain = function (value, lo, hi) {
      return Math.min(hi, Math.max(lo, value));
    };

    /**
     * Update images and descriptions.
     *
     * @param {Number} index - index of top image.
     * @param {Number} opacity - opacity of top image.
     */
    this.update = function (index, opacity) {
      bottomIndex = this.constrain(index + 1, 0, this.maxItem);

      // Update images
      this.image1.src = H5P.getPath(this.options.items[index].image.path, this.id);
      this.image2.src = H5P.getPath(this.options.items[bottomIndex].image.path, this.id);
      this.image1.style.opacity = opacity;

      // Update descriptions
      if (this.hasDescription) {
        this.description1.innerHTML = this.options.items[index].description;
        this.description2.innerHTML = this.options.items[bottomIndex].description;
        this.description1.style.opacity = opacity;
        this.description2.style.opacity = 1 - opacity;
      }
    };

    // Initialize event inheritance
    H5P.EventDispatcher.call(this);
  }

  // Extends the event dispatcher
  C.prototype = Object.create(H5P.EventDispatcher.prototype);
  C.prototype.constructor = C;

  /**
   * Attach function called by H5P framework to insert H5P content into page.
   *
   * @param {jQuery} container to attach to.
   */
  C.prototype.attach = function ($container) {
    var self = this;

    // Setup HTML DOM
    $container.addClass("h5p-agamotto");
    if (!self.options.items || self.maxItem < 1) {
      $container.append('
I really need at least two images :-)
');
      self.trigger('resize');
      return;
    }

    // Title, images and slider
    if (self.options.title) {
      $container.append('

' + self.options.title + '

');
    }
    $container.append('

');
    $container.append('

');

    self.sliderContainer = document.getElementById('h5p-agamotto-slider-container');
    self.sliderContainer.setAttribute('role', 'slider');
    self.sliderContainer.setAttribute('aria-valuenow', 0);
    self.sliderContainer.setAttribute('aria-valuemin', 0);
    self.sliderContainer.setAttribute('aria-valuemax', 100);

    self.sliderTrack = document.getElementById('h5p-agamotto-slider-track');
    self.sliderTrackWidth = parseInt(self.sliderContainer.offsetWidth) - 32;
    self.sliderTrack.style.width = self.sliderTrackWidth + 'px';
    self.sliderThumb = document.getElementById('h5p-agamotto-slider-thumb');
    self.sliderThumb.setAttribute('tabindex', 0);

    // Descriptions
    if (self.hasDescription) {
      $container.append('

');

      self.description1 = document.getElementById('h5p-agamotto-description1');
      self.description1.style.opacity = 1;
      self.description1.innerHTML = self.options.items[0].description;

      self.description2 = document.getElementById('h5p-agamotto-description2');
      self.description2.style.opacity = 0;
      self.description2.innerHTML = self.options.items[1].description;

      document.getElementById('h5p-agamotto-descriptions').style.height = self.getMaxDescriptionHeight() + 'px';
      self.trigger('resize');
    }

    // We trust the user here and believe that all images have the same height
    self.image1 = document.getElementById('h5p-agamotto-image1');
    self.image1.onload = function () {
      document.getElementById('h5p-agamotto-images').style.height = window.getComputedStyle(self.image1).height;
      self.trigger('resize');
    }
    self.image1.src = H5P.getPath(self.options.items[0].image.path, self.id);
    self.image2 = document.getElementById('h5p-agamotto-image2');
    self.image2.src = H5P.getPath(self.options.items[1].image.path, self.id);

    self.sliderThumb.addEventListener('mousedown', startSlide, false);
    document.getElementsByClassName('h5p-agamotto')[0].addEventListener('mouseup', stopSlide, false);

    // Event Listeners for Touch Interface
    this.sliderContainer.addEventListener('touchstart', function (e) {
      e = e || window.event;
      e.preventDefault();
      e.stopPropagation();
      moveThumb(e);

      this.addEventListener('touchmove', function (e) {
        e = e || window.event;
        e.preventDefault();
        e.stopPropagation();
        moveThumb(e);
      });
    });
    this.sliderContainer.addEventListener('touchend', function (e) {
      e = e || window.event;
      e.preventDefault();
      e.stopPropagation();
      snap();
    });

    // Event Listeners for Keyboard on handle
    this.sliderThumb.addEventListener('keydown', function (e) {
      e = e || window.event;
      var key = e.which || e.keyCode;

      // handler left
      if (key === 37) {
        var position = Math.max(0, parseInt(self.sliderThumb.style.left) - 1);
        moveThumb(position);
      }

      // handler right
      if (key === 39) {
        var position = Math.min(parseInt(self.sliderThumb.style.left) + 1, self.sliderTrack.offsetWidth);
        moveThumb(position);
      }
    });

    function getPointerX (e) {
      var pointerX = 0;
      if (e.touches) {
        pointerX = e.touches[0].pageX;
      } else {
        pointerX = e.clientX;
      }
      return pointerX;
    };

    function startSlide (e) {
      e = e || window.event;
      moveThumb(e);
      document.getElementsByClassName('h5p-agamotto')[0].addEventListener('mousemove', moveThumb, false);
    };

    function stopSlide (e) {
      e = e || window.event;
      document.getElementsByClassName('h5p-agamotto')[0].removeEventListener('mousemove', moveThumb, false);
      snap();
    };

    function snap () {
      // TODO: Decide whether to snap to the closest position or the image that's visible the most
      if (self.options.snap === true) {
        var snapIndex = Math.round(self.index + 1 - self.opacity);
        self.sliderThumbPosition = snapIndex * parseInt(self.sliderTrack.offsetWidth) / self.maxItem;
        updateThumb(true);
        //self.sliderThumb.style.left = self.sliderThumbPosition + 8 + 'px';
        self.update(snapIndex, 1);
      }
    }

    function updateThumb(animate) {
      if (animate) {
        self.sliderThumb.classList.add('h5p-agamotto-transition');
      } else {
        self.sliderThumb.classList.remove('h5p-agamotto-transition');
      }
      self.sliderThumb.style.left = self.sliderThumbPosition + 8 + 'px';
      self.sliderContainer.setAttribute('aria-valuenow', Math.round(self.sliderThumbPosition / self.sliderTrack.offsetWidth * 100));
    }

    function moveThumb (to) {
      if ((typeof to === 'string') || (typeof to === 'number')) {
        to = parseInt(to) + 32 - 8;
      } else if (typeof to === 'object') {
        to = getPointerX(to);
      } else {
        to = 0;
      }
      self.sliderThumbPosition = self.constrain(to - 32, 0, self.sliderTrack.offsetWidth);
      updateThumb(false);
      //self.sliderThumb.style.left = self.sliderThumbPosition + 8 + 'px';
      /*
       * Map the slider value to the image indexes. Since we might not
       * want to initiate opacity shifts right away, we can add a margin to
       * the left and right of the slider where nothing happens
       */
      var margin = 5;
      var mappedValue = self.map(
        self.sliderThumbPosition,
        (parseInt(this.min) || 0) + margin,
        (parseInt(this.max) || self.sliderTrack.offsetWidth) - margin,
        0,
        self.maxItem
      );
      // Account for margin change and mapping outside the image indexes
      var topIndex = self.constrain(Math.floor(mappedValue), 0, self.maxItem);

      // Using a power value will allow the actual image to be displayed a little longer before blending
      var topOpacity = Math.pow(1 - self.constrain(mappedValue - topIndex, 0, 1), 2);

      self.index = topIndex;
      self.opacity = topOpacity;
      self.update(topIndex, topOpacity);
    }

    window.addEventListener('resize', function (e) {
      document.getElementById('h5p-agamotto-images').style.height = window.getComputedStyle(self.image1).height;
      var ratio = self.sliderThumbPosition / self.sliderTrackWidth;

      self.sliderTrackWidth = parseInt(self.sliderContainer.offsetWidth) - 32;
      self.sliderThumbPosition = self.sliderTrackWidth * ratio;

      self.sliderThumb.style.left = self.sliderThumbPosition + 8 + 'px';
      self.sliderTrack.style.width = self.sliderTrackWidth + 'px';
    });

    // This is needed for Chrome to detect the mouseup outside the iframe
    window.addEventListener('mouseup', function () {
      document.getElementsByClassName('h5p-agamotto')[0].dispatchEvent(new CustomEvent('mouseup'));
    });
  };

  return C;
}(H5P.jQuery);
<commit_msg>harmonize snapping and transitions<commit_after>/*
 * TODO: clean up variable mess
 * TODO: refactoring
 * TODO: more refactoring
 * TODO: proper commenting
 * TODO: think about optional ticks
 */
var H5P = H5P || {};

H5P.Agamotto = function ($) {
  /**
   * Constructor function.
   *
   * @param {object} options from semantics.json.
   * @param {number} content id.
   */
  function C(options, id) {
    if (!options.items) {
      return;
    }

    // Remove items with missing image
    for (var i = 0; i < options.items.length; i++) {
      if (options.items[i].image === undefined) {
        console.log('An image is missing. I will continue without it, but please check your settings.');
        options.items.splice(i, 1);
        i--;
      }
    }
    // Restrict to 50 images
    options.items = options.items.splice(0, 50);
    this.options = options;

    this.maxItem = this.options.items.length - 1;
    if (this.maxItem > 100) {
      console.log('You have more than 100 images. This will not work well.');
    }

    this.image1, this.image2 = undefined;
    this.description1, this.description2 = undefined;

    // TODO: include other variables

    this.sliderTrackWidth = 0;
    this.sliderThumbPosition = 0;

    this.index = 0;
    this.opacity = 1;

    // Set hasDescription = true if at least one item has a description
    this.hasDescription = false;
    for (var i = 0; i < this.maxItem + 1; i++) {
      if (this.options.items[i].description !== '') {
        this.hasDescription = true;
        break;
      }
    }
    this.id = id;

    /**
     * Get maximum height of all descriptions.
     * Expects the DOM to be already setup.
     *
     * @return {number} - The maximum height of all descriptions.
     */
    this.getMaxDescriptionHeight = function() {
      var maxDescriptionHeight = 0;
      for (var i = 0; i < this.maxItem + 1; i++) {
        this.description2.innerHTML = this.options.items[i].description;
        maxDescriptionHeight = Math.max(maxDescriptionHeight, this.description2.offsetHeight);
      }
      return maxDescriptionHeight;
    };

    /**
     * Map a value from one range to another.
     *
     * @param {number} value - the value to me remapped.
     * @param {number} lo1 - lower boundary of first range.
     * @param {number} hi1 - upper boundary of first range.
     * @param {number} lo2 - lower boundary of second range.
     * @param {number} hi2 - upper boundary of second range.
     * @return {number} - remapped value.
     */
    this.map = function (value, lo1, hi1, lo2, hi2) {
      return lo2 + (hi2 - lo2) * (value - lo1) / (hi1 - lo1);
    };

    /**
     * Constrain a number value within a range.
     *
     * @param {number} value - value to be constrained.
     * @param {number} lo - lower boundary of the range.
     * @param {number} hi - upper boundary of the range.
     * @returns {number} - constrained value.
     */
    this.constrain = function (value, lo, hi) {
      return Math.min(hi, Math.max(lo, value));
    };

    /**
     * Update images and descriptions.
     *
     * @param {Number} index - index of top image.
     * @param {Number} opacity - opacity of top image.
     */
    this.update = function (index, opacity) {
      bottomIndex = this.constrain(index + 1, 0, this.maxItem);

      // Update images
      this.image1.src = H5P.getPath(this.options.items[index].image.path, this.id);
      this.image2.src = H5P.getPath(this.options.items[bottomIndex].image.path, this.id);
      this.image1.style.opacity = opacity;

      // Update descriptions
      if (this.hasDescription) {
        this.description1.innerHTML = this.options.items[index].description;
        this.description2.innerHTML = this.options.items[bottomIndex].description;
        this.description1.style.opacity = opacity;
        this.description2.style.opacity = 1 - opacity;
      }
    };

    // Initialize event inheritance
    H5P.EventDispatcher.call(this);
  }

  // Extends the event dispatcher
  C.prototype = Object.create(H5P.EventDispatcher.prototype);
  C.prototype.constructor = C;

  /**
   * Attach function called by H5P framework to insert H5P content into page.
   *
   * @param {jQuery} container to attach to.
   */
  C.prototype.attach = function ($container) {
    var self = this;

    // Setup HTML DOM
    $container.addClass("h5p-agamotto");
    if (!self.options.items || self.maxItem < 1) {
      $container.append('
I really need at least two images :-)
');
      self.trigger('resize');
      return;
    }

    // Title, images and slider
    if (self.options.title) {
      $container.append('

' + self.options.title + '

');
    }
    $container.append('

');
    $container.append('

');

    self.sliderContainer = document.getElementById('h5p-agamotto-slider-container');
    self.sliderContainer.setAttribute('role', 'slider');
    self.sliderContainer.setAttribute('aria-valuenow', 0);
    self.sliderContainer.setAttribute('aria-valuemin', 0);
    self.sliderContainer.setAttribute('aria-valuemax', 100);

    self.sliderTrack = document.getElementById('h5p-agamotto-slider-track');
    self.sliderTrackWidth = parseInt(self.sliderContainer.offsetWidth) - 32;
    self.sliderTrack.style.width = self.sliderTrackWidth + 'px';
    self.sliderThumb = document.getElementById('h5p-agamotto-slider-thumb');
    self.sliderThumb.setAttribute('tabindex', 0);

    // Descriptions
    if (self.hasDescription) {
      $container.append('

');

      self.description1 = document.getElementById('h5p-agamotto-description1');
      self.description1.style.opacity = 1;
      self.description1.innerHTML = self.options.items[0].description;

      self.description2 = document.getElementById('h5p-agamotto-description2');
      self.description2.style.opacity = 0;
      self.description2.innerHTML = self.options.items[1].description;

      document.getElementById('h5p-agamotto-descriptions').style.height = self.getMaxDescriptionHeight() + 'px';
      self.trigger('resize');
    }

    // We trust the user here and believe that all images have the same height
    self.image1 = document.getElementById('h5p-agamotto-image1');
    self.image1.onload = function () {
      document.getElementById('h5p-agamotto-images').style.height = window.getComputedStyle(self.image1).height;
      self.trigger('resize');
    }
    self.image1.src = H5P.getPath(self.options.items[0].image.path, self.id);
    self.image2 = document.getElementById('h5p-agamotto-image2');
    self.image2.src = H5P.getPath(self.options.items[1].image.path, self.id);

    self.sliderThumb.addEventListener('mousedown', startSlide, false);
    document.getElementsByClassName('h5p-agamotto')[0].addEventListener('mouseup', stopSlide, false);

    // Event Listeners for Touch Interface
    this.sliderContainer.addEventListener('touchstart', function (e) {
      e = e || window.event;
      e.preventDefault();
      e.stopPropagation();
      moveThumb(e);

      this.addEventListener('touchmove', function (e) {
        e = e || window.event;
        e.preventDefault();
        e.stopPropagation();
        moveThumb(e);
      });
    });
    this.sliderContainer.addEventListener('touchend', function (e) {
      e = e || window.event;
      e.preventDefault();
      e.stopPropagation();
      snap();
    });

    // Event Listeners for Keyboard on handle
    this.sliderThumb.addEventListener('keydown', function (e) {
      e = e || window.event;
      var key = e.which || e.keyCode;

      // handler left
      if (key === 37) {
        var position = Math.max(0, parseInt(self.sliderThumb.style.left) - 1);
        moveThumb(position);
      }

      // handler right
      if (key === 39) {
        var position = Math.min(parseInt(self.sliderThumb.style.left) + 1, self.sliderTrack.offsetWidth);
        moveThumb(position);
      }
    });

    function getPointerX (e) {
      var pointerX = 0;
      if (e.touches) {
        pointerX = e.touches[0].pageX;
      } else {
        pointerX = e.clientX;
      }
      return pointerX;
    };

    function startSlide (e) {
      e = e || window.event;
      moveThumb(e);
      document.getElementsByClassName('h5p-agamotto')[0].addEventListener('mousemove', moveThumb, false);
    };

    function stopSlide (e) {
      e = e || window.event;
      document.getElementsByClassName('h5p-agamotto')[0].removeEventListener('mousemove', moveThumb, false);
      snap();
    };

    function snap () {
      if (self.options.snap === true) {
        var snapIndex = Math.round(self.index + 1 - self.opacity);
        self.sliderThumbPosition = snapIndex * parseInt(self.sliderTrack.offsetWidth) / self.maxItem;
        updateThumb(true);
        self.update(snapIndex, 1);
      }
    }

    function updateThumb(animate) {
      if (animate) {
        self.sliderThumb.classList.add('h5p-agamotto-transition');
      } else {
        self.sliderThumb.classList.remove('h5p-agamotto-transition');
      }
      self.sliderThumb.style.left = self.sliderThumbPosition + 8 + 'px';
      self.sliderContainer.setAttribute('aria-valuenow', Math.round(self.sliderThumbPosition / self.sliderTrack.offsetWidth * 100));
    }

    function moveThumb (to) {
      if ((typeof to === 'string') || (typeof to === 'number')) {
        to = parseInt(to) + 32 - 8;
      } else if (typeof to === 'object') {
        to = getPointerX(to);
      } else {
        to = 0;
      }
      self.sliderThumbPosition = self.constrain(to - 32, 0, self.sliderTrack.offsetWidth);
      updateThumb(false);
      /*
       * Map the slider value to the image indexes. Since we might not
       * want to initiate opacity shifts right away, we can add a margin to
       * the left and right of the slider where nothing happens
       */
      var margin = 5;
      var mappedValue = self.map(
        self.sliderThumbPosition,
        (parseInt(this.min) || 0) + margin,
        (parseInt(this.max) || self.sliderTrack.offsetWidth) - margin,
        0,
        self.maxItem
      );
      // Account for margin change and mapping outside the image indexes
      var topIndex = self.constrain(Math.floor(mappedValue), 0, self.maxItem);

      /*
       * Using the cosine will allow an image to be displayed a little longer
       * before blending than a linear function
       */
      var linearOpacity = (1 - self.constrain(mappedValue - topIndex, 0, 1));
      var topOpacity = 0.5 * (1 - Math.cos(Math.PI * linearOpacity));

      self.index = topIndex;
      self.opacity = topOpacity;
      self.update(topIndex, topOpacity);
    }

    window.addEventListener('resize', function (e) {
      document.getElementById('h5p-agamotto-images').style.height = window.getComputedStyle(self.image1).height;
      var ratio = self.sliderThumbPosition / self.sliderTrackWidth;

      self.sliderTrackWidth = parseInt(self.sliderContainer.offsetWidth) - 32;
      self.sliderThumbPosition = self.sliderTrackWidth * ratio;

      self.sliderThumb.style.left = self.sliderThumbPosition + 8 + 'px';
      self.sliderTrack.style.width = self.sliderTrackWidth + 'px';
    });

    // This is needed for Chrome to detect the mouseup outside the iframe
    window.addEventListener('mouseup', function () {
      document.getElementsByClassName('h5p-agamotto')[0].dispatchEvent(new CustomEvent('mouseup'));
    });
  };

  return C;
}(H5P.jQuery);
<|endoftext|>


<commit_before>var itemNames;
	var itemQuant;
	var itemPrice;
	var itemTotalPrice;

function preparePagePostLoad() {
	setCartScore();
	generateReceipt();
}

function numberChanged(rowNumber) {

itemQuant[rowNumber] = document.getElementById('itemQuant'+rowNumber).value;

document.getElementById('priceData'+rowNumber).innerHTML = itemPrice[rowNumber] * itemQuant[rowNumber];

itemTotalPrice [rowNumber] = itemPrice[rowNumber] * itemQuant[rowNumber]

calculateTotal();
}

function calculateTotal() {
	var total = 0;
	for(var i = 0; i<getCartScore(); i++) {
		total += itemTotalPrice[i];
		console.log(itemTotalPrice[i]);
	}

	total = total.toFixed(2);

	document.getElementById('confirm-checkout').innerHTML = total;
	//console.log(total);
}

function getCartScore(){
	return localStorage.getItem("score");
}

function setCartScore() {
	document.getElementById('cart-score').innerHTML = " "+getCartScore();
}

function generateReceipt() {

	itemNames = new Array();
	itemQuant = new Array();
	itemPrice = new Array();
	itemTotalPrice = new Array();

	itemNames = ['Bacon', 'Maple Apple Pecan', 'Pumpkin Spice', 'Birthday Cake', 'Cranberry', 'Blackberry'];
	itemQuant = [1, 3, 1, 2, 2, 1];
	itemPrice = [1.00, 3.00, 9.00, 1.11, 1.00, 1.65];

    var myTable= "
";

  for (var i=0; i<getCartScore(); i++) {
  	itemTotalPrice[i] = itemPrice[i];
    myTable+="

<input id='itemQuant"+i+"' type='number' min='0' max='9' step='1' value='1' onchange='numberChanged("+i+")'>
	";
    myTable+="" + itemNames[i] + "	";
    myTable+="" + "$" + "	";
    myTable+="" + itemPrice[i].toFixed(2) + "
";

  }
  calculateTotal();

  myTable+="" + "" + "
";
   myTable+="
";

 document.getElementById('tablePrint').innerHTML = myTable;
}

<commit_msg>Fixing local storage related bugs<commit_after>var itemNames;
	var itemQuant;
	var itemPrice;
	var itemTotalPrice;

function preparePagePostLoad() {
	setCartScore();
	generateReceipt();
}

function numberChanged(rowNumber) {

itemQuant[rowNumber] = document.getElementById('itemQuant'+rowNumber).value;

document.getElementById('priceData'+rowNumber).innerHTML = itemPrice[rowNumber] * itemQuant[rowNumber];

itemTotalPrice [rowNumber] = itemPrice[rowNumber] * itemQuant[rowNumber]

calculateTotal();
}

function calculateTotal() {
	var total = 0;
	for(var i = 0; i<getCartScore(); i++) {
		total += itemTotalPrice[i];
		console.log(itemTotalPrice[i]);
	}

	total = total.toFixed(2);

	document.getElementById('confirm-checkout').innerHTML = total;
	//console.log(total);
}

function getCartScore(){
	if(localStorage.getItem("score")) {
		return localStorage.getItem("score");
	}
	return 0;
}

function setCartScore() {
	document.getElementById('cart-score').innerHTML = " "+getCartScore();
}

function generateReceipt() {

	itemNames = new Array();
	itemQuant = new Array();
	itemPrice = new Array();
	itemTotalPrice = new Array();

	itemNames = ['Bacon', 'Maple Apple Pecan', 'Pumpkin Spice', 'Birthday Cake', 'Cranberry', 'Blackberry'];
	itemQuant = [1, 3, 1, 2, 2, 1];
	itemPrice = [1.00, 3.00, 9.00, 1.11, 1.00, 1.65];

    var myTable= "
";

  for (var i=0; i<getCartScore(); i++) {
  	itemTotalPrice[i] = itemPrice[i];
    myTable+="

<input id='itemQuant"+i+"' type='number' min='0' max='9' step='1' value='1' onchange='numberChanged("+i+")'>
	";
    myTable+="" + itemNames[i] + "	";
    myTable+="" + "$" + "	";
    myTable+="" + itemPrice[i].toFixed(2) + "
";

  }
  calculateTotal();

  myTable+="" + "" + "
";
   myTable+="
";

 document.getElementById('tablePrint').innerHTML = myTable;
}

<|endoftext|>


<commit_before>function openDownloadTab(evt, cityName) {
    // Declare all variables
    var i, tabcontent, tablinks;

    // Get all elements with class="tabcontent" and hide them
    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }

    // Get all elements with class="tablinks" and remove the class "active"
    tablinks = document.getElementsByClassName("tablinks");
    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }

    // Show the current tab, and add an "active" class to the button that opened the tab
    document.getElementById(cityName).style.display = "block";
    evt.currentTarget.className += " active";
}

function getOS() {
    var platform = window.navigator.platform,
        macosPlatforms = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'],
        os = null;

    if (macosPlatforms.indexOf(platform) !== -1) {
        os = 'macos';
    } else if (!os && /Linux/.test(platform)) {
        os = 'linux';
    } else {
        // show Windows by default
        os = "Windows"
    }
    return os;
}

window.onload = function () {
    os = getOS();
    console.log(os);
    document.getElementById("macos").click();
}<commit_msg>Fix automatic OS selection<commit_after>function openDownloadTab(evt, cityName) {
    // Declare all variables
    var i, tabcontent, tablinks;

    // Get all elements with class="tabcontent" and hide them
    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }

    // Get all elements with class="tablinks" and remove the class "active"
    tablinks = document.getElementsByClassName("tablinks");
    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }

    // Show the current tab, and add an "active" class to the button that opened the tab
    document.getElementById(cityName).style.display = "block";
    evt.currentTarget.className += " active";
}

function getOS() {
    var platform = window.navigator.platform,
        macosPlatforms = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'],
        os = null;
    if (macosPlatforms.indexOf(platform) !== -1) {
        os = 'macos';
    } else if (!os && /Linux/.test(platform)) {
        os = 'Linux';
    } else {
        // show Windows by default
        os = "Windows"
    }
    return os;
}

window.onload = function () {
    os = getOS();
    document.getElementById(os).click();
}<|endoftext|>


<commit_before>$(document).ready(function(){
	$('*[verlang="vi"]').hide();
	function helloWorld(){
		$("#typed").typed({
			strings: ["Hi!", "I'm a student.", "I'm a blogger.", "I'm a developer.", "I'm Viet Anh.", "Nice to meet you!"],
			cursorChar: " ☕",
			typeSpeed: 45,
			callback: function(){
		    	setTimeout(function(){
			        helloWorld();
			    }, 4500);
		    }
		});
	}
	helloWorld();
});
<commit_msg> commit<commit_after>$(document).ready(function(){
	$('*[verlang="vi"]').hide();
	function helloWorld(){
		$("#typed").typed({
			strings: ["Hi!","I'm Cao The Toan.", "I'm a developer.", "I'd like robotic.",   "Nice to meet you!"],
			cursorChar: " ☕",
			typeSpeed: 45,
			callback: function(){
		    	setTimeout(function(){
			        helloWorld();
			    }, 4500);
		    }
		});
	}
	helloWorld();
});
<|endoftext|>


<commit_before>Dasht.map_geocoder_cache = {}

Dasht.map_plot_address = function(map, markers, geocoder, address) {
    // Maybe pull the location from cache.
    var location;
    if (location = Dasht.map_geocoder_cache[address]) {
        Dasht.map_plot_location(map, markers, address, location);
        return;
    }

    geocoder.geocode({ "address": address }, function(results, status) {
        // Don't plot if the lookup failed.
        if (status != google.maps.GeocoderStatus.OK) return;
        var location = results[0].geometry.location;
        Dasht.map_geocoder_cache[address] = location;
        Dasht.map_plot_location(map, markers, address, location);
    });
}

Dasht.map_plot_ip = function(map, markers, ip) {
    // Maybe pull the location from cache.
    var location;
    if (location = Dasht.map_geocoder_cache[ip]) {
        Dasht.map_plot_location(map, markers, ip, location);
        return;
    }

    jQuery.ajax({
        url: 'http://freegeoip.net/json/' + ip,
        type: 'POST',
        dataType: 'jsonp',
        success: function(response) {
            var location = new google.maps.LatLng(response.latitude, response.longitude);
            Dasht.map_geocoder_cache[ip] = location;
            Dasht.map_plot_location(map, markers, ip, location);
        },
        error: function (xhr, ajaxOptions, thrownError) {
            alert("Failed!");
        }
    });
}

Dasht.map_plot_location = function(map, markers, address_or_ip, location) {
    var location_exists = _.any(_.values(markers), function(marker) {
        return _.isEqual(marker.position, location);
    });
    if (location_exists) return;

    // Drop a pin.
    var marker = new google.maps.Marker({
        map: map,
        animation: google.maps.Animation.DROP,
        position: location
    });

    // Keep track of markers.
    markers[address_or_ip] = marker;
}

Dasht.map_init = function(el, options) {
    // Initialize.
    var old_data = undefined;
    var styles = [
        {
            stylers: [
                { hue: "#ffffff" },
                { saturation: -100 },
                { lightness: 20 },
                { gamma: 0.5 }
            ]
        },
        {
            featureType: "water",
            stylers: [
                { hue: "#ffffff" },
                { saturation: 80 },
                { lightness: 100 },
                { gamma: 0.43 }
            ]
        }
    ];

    var mapOptions = {
        zoom: 4,
        center: new google.maps.LatLng(39.8282, -98.5795),
        styles: styles,
        disableDefaultUI: true
    };

    var map_el = $(el).find(".map").get()[0];
    var num_entries = options["n"] || 10;
    var map = new google.maps.Map(map_el, mapOptions);
    var markers = {};
    var geocoder = new google.maps.Geocoder();
    var ip_regex = /\d+\.\d+\.\d+\.\d+/;
    var coordinate_regex = /\[(-?\d+\.\d+),\s*(-?\d+\.\d+)\]/;

    Dasht.fill_tile($(el).find(".map"));

    // Update values.
    setTimeout(function() {
        Dasht.get_value(options, function(new_data) {
            new_data = new_data[0];
            if (_.isEqual(old_data, new_data)) return;

            // Remove old markers.
            var old_markers = _.difference(_.keys(markers), new_data);
            _.each(old_markers, function(address) {
                markers[address].setMap(null);
                delete markers[address];
            });

            // Plot each marker.
            _.each(new_data, function(item, index) {
                if (item.search(ip_regex) >= 0) {
                    Dasht.map_plot_ip(map, markers, item);
                } else if (item.search(coordinate_regex) >= 0) {
                    var matches = item.match(coordinate_regex);
                    var lng = parseFloat(matches[1]);
                    var lat = parseFloat(matches[2]);
                    var location = new google.maps.LatLng(lat, lng);
                    Dasht.map_plot_location(map, markers, item, location);
                } else {
                    Dasht.map_plot_address(map, markers, geocoder, item);
                }
            });

            old_data = new_data;
        });
    }, 1000);
}
<commit_msg>Fix coordinate plotting.<commit_after>Dasht.map_geocoder_cache = {}

Dasht.map_plot_address = function(map, markers, geocoder, address) {
    // Maybe pull the location from cache.
    var location;
    if (location = Dasht.map_geocoder_cache[address]) {
        Dasht.map_plot_location(map, markers, address, location);
        return;
    }

    geocoder.geocode({ "address": address }, function(results, status) {
        // Don't plot if the lookup failed.
        if (status != google.maps.GeocoderStatus.OK) return;
        var location = results[0].geometry.location;
        Dasht.map_geocoder_cache[address] = location;
        Dasht.map_plot_location(map, markers, address, location);
    });
}

Dasht.map_plot_ip = function(map, markers, ip) {
    // Maybe pull the location from cache.
    var location;
    if (location = Dasht.map_geocoder_cache[ip]) {
        Dasht.map_plot_location(map, markers, ip, location);
        return;
    }

    jQuery.ajax({
        url: 'http://freegeoip.net/json/' + ip,
        type: 'POST',
        dataType: 'jsonp',
        success: function(response) {
            var location = new google.maps.LatLng(response.latitude, response.longitude);
            Dasht.map_geocoder_cache[ip] = location;
            Dasht.map_plot_location(map, markers, ip, location);
        },
        error: function (xhr, ajaxOptions, thrownError) {
            alert("Failed!");
        }
    });
}

Dasht.map_plot_coordinates = function(map, markers, coordinates) {
    // Maybe pull the location from cache.
    var location;
    if (location = Dasht.map_geocoder_cache[coordinates]) {
        Dasht.map_plot_location(map, markers, coordinates, location);
        return;
    }

    var coordinate_regex = /\[(-?\d+\.\d+),\s*(-?\d+\.\d+)\]/;
    var matches = coordinates.match(coordinate_regex);
    var lng = parseFloat(matches[1]);
    var lat = parseFloat(matches[2]);
    var location = new google.maps.LatLng(lat, lng);
    Dasht.map_geocoder_cache[coordinates] = location;
    Dasht.map_plot_location(map, markers, coordinates, location);
}

Dasht.map_plot_location = function(map, markers, item, location) {
    var location_exists = _.any(_.values(markers), function(marker) {
        return _.isEqual(marker.position, location);
    });
    if (location_exists) return;

    // Drop a pin.
    var marker = new google.maps.Marker({
        map: map,
        animation: google.maps.Animation.DROP,
        position: location
    });

    // Keep track of markers.
    markers[item] = marker;
}

Dasht.map_init = function(el, options) {
    // Initialize.
    var old_data = undefined;
    var styles = [
        {
            stylers: [
                { hue: "#ffffff" },
                { saturation: -100 },
                { lightness: 20 },
                { gamma: 0.5 }
            ]
        },
        {
            featureType: "water",
            stylers: [
                { hue: "#ffffff" },
                { saturation: 80 },
                { lightness: 100 },
                { gamma: 0.43 }
            ]
        }
    ];

    var mapOptions = {
        zoom: 4,
        center: new google.maps.LatLng(39.8282, -98.5795),
        styles: styles,
        disableDefaultUI: true
    };

    var map_el = $(el).find(".map").get()[0];
    var num_entries = options["n"] || 10;
    var map = new google.maps.Map(map_el, mapOptions);
    var markers = {};
    var geocoder = new google.maps.Geocoder();
    var ip_regex = /\d+\.\d+\.\d+\.\d+/;
    var coordinate_regex = /\[(-?\d+\.\d+),\s*(-?\d+\.\d+)\]/;

    Dasht.fill_tile($(el).find(".map"));

    // Update values.
    setTimeout(function() {
        Dasht.get_value(options, function(new_data) {
            new_data = new_data[0];
            if (_.isEqual(old_data, new_data)) return;

            // Remove old markers.
            var old_markers = _.difference(_.keys(markers), new_data);
            _.each(old_markers, function(address) {
                markers[address].setMap(null);
                delete markers[address];
            });

            // Plot each marker.
            _.each(new_data, function(item, index) {
                if (item.search(ip_regex) >= 0) {
                    Dasht.map_plot_ip(map, markers, item);
                } else if (item.search(coordinate_regex) >= 0) {
                    Dasht.map_plot_coordinates(map, markers, item);
                } else {
                    Dasht.map_plot_address(map, markers, geocoder, item);
                }
            });

            old_data = new_data;
        });
    }, 1000);
}
<|endoftext|>


<commit_before>

var stats = new Array(6);

var numTrials = 100;
var timer = null;
var counter = 0;
var heads = 0;
var tails = 0;
var consecutiveHeads = 0;
var consecutiveTails = 0;
var diceArray = [0, 0, 0, 0, 0, 0];

function generateQuestion() {
	numDice = parseInt(document.getElementById('numDice').value);

	switch(numDice) {
		case 2:
			document.getElementById('diceQuestion').innerHTML = "What is the probability of getting a one on the first die and an odd number on the second die?";
			break;
		case 3:
			document.getElementById('diceQuestion').innerHTML = "What is the probability of getting a one on the first die, an odd number on the second die and an even number on the third die?";
			break;
		case 4:
			document.getElementById('diceQuestion').innerHTML = "What is the probability of getting a one on the first die, an odd number on the second die, an even number on the third die and a six on the last die?";
			break;
	}
}

function rollDice() {
	numRolls = parseInt(document.getElementById('numRolls').value);
	var delay = 1000/numRolls;

	if (counter < numRolls) {
		counter ++;

		// ---------- Animate Dice ----------
		var val = parseInt(document.getElementById('numDice').value);	// get number of dice
		var dice = "";

		for (var i = 0; i < val; i ++) {
			var r = Math.ceil(Math.random() * 6);	// random number from 1-12

			diceArray[r-1]++;

			document.getElementById(r.toString()).innerHTML = diceArray[r-1];

			dice += '';
		}
		console.log(diceArray);

			// ---------- Call Animation Recursively ----------
		document.getElementById('dice').innerHTML = dice;
		timer = setTimeout(rollDice, delay);
	}

	else {
		clearInterval(timer);
		timer = null;
		counter = 0;
		diceArray = [0, 0, 0, 0, 0, 0];
	}
}

function generator() {

	numTrials = parseInt(document.getElementById('numTrials').value);
	var delay = 1000/numTrials;

	if (counter < numTrials) {
		counter ++;

		// ---------- Animate Coins ----------
		var val = parseInt(document.getElementById('selector').value);	// get number of coins
		var coinArray = new Array(val);
		var coins = "";
		var allHeads = true;
		var allTails = true;

		for (var i = 0; i < val; i ++) {
			var r = Math.ceil(Math.random() * 12);	// random number from 1-12

			if (r % 2 == 0) {
				tails ++;
			} else {
				heads ++;
			}

			coinArray[i] = r;
			coins += '';
		}

		for (var j = 0; j < coinArray.length; j ++) {
			if (coinArray[j] % 2 != 1) {
				allHeads = false;
			}
		}

		for (var j = 0; j < coinArray.length; j ++) {
			if (coinArray[j] % 2 != 0) {
				allTails = false;
			}
		}

		if (allHeads) {
			consecutiveHeads ++;
		}
		else if (allTails) {
			consecutiveTails ++;
		}

		// ---------- Update Table ----------

		var index = val - 2;

		document.getElementById('num').innerHTML = val;
		document.getElementById('trials').innerHTML = counter;
		document.getElementById('heads').innerHTML = heads;
		document.getElementById('tails').innerHTML = tails;
		document.getElementById('allHeads').innerHTML = consecutiveHeads;
		document.getElementById('allTails').innerHTML = consecutiveTails;

		// ---------- Call Animation Recursively ----------
		document.getElementById('coins').innerHTML = coins;
		timer = setTimeout(generator, delay);
	}

	else {
		clearInterval(timer);
		timer = null;
		counter = 0;

		heads = 0;
		tails = 0;
		consecutiveHeads = 0;
		consecutiveTails = 0;
	}
}

document.onload = function() {

	for (var i = 0; i < stats.length; i ++) {
		var row = new Array(5);

		for (var j = 0; j < row.length; j ++) {
			row[j] = 0;
		}

		stats.push(row);
	}
}
<commit_msg>changed animation frequency<commit_after>

var stats = new Array(6);

var numTrials = 100;
var timer = null;
var counter = 0;
var heads = 0;
var tails = 0;
var consecutiveHeads = 0;
var consecutiveTails = 0;
var diceArray = [0, 0, 0, 0, 0, 0];

function generateQuestion() {
	numDice = parseInt(document.getElementById('numDice').value);

	switch(numDice) {
		case 2:
			document.getElementById('diceQuestion').innerHTML = "What is the probability of getting a one on the first die and an odd number on the second die?";
			break;
		case 3:
			document.getElementById('diceQuestion').innerHTML = "What is the probability of getting a one on the first die, an odd number on the second die and an even number on the third die?";
			break;
		case 4:
			document.getElementById('diceQuestion').innerHTML = "What is the probability of getting a one on the first die, an odd number on the second die, an even number on the third die and a six on the last die?";
			break;
	}
}

function rollDice() {
	numRolls = parseInt(document.getElementById('numRolls').value);
	var delay = 400/numRolls;

	if (counter < numRolls) {
		counter ++;

		// ---------- Animate Dice ----------
		var val = parseInt(document.getElementById('numDice').value);	// get number of dice
		var dice = "";

		for (var i = 0; i < val; i ++) {
			var r = Math.ceil(Math.random() * 6);	// random number from 1-12

			diceArray[r-1]++;

			document.getElementById(r.toString()).innerHTML = diceArray[r-1];

			dice += '';
		}
		console.log(diceArray);

			// ---------- Call Animation Recursively ----------
		document.getElementById('dice').innerHTML = dice;
		timer = setTimeout(rollDice, delay);
	}

	else {
		clearInterval(timer);
		timer = null;
		counter = 0;
		diceArray = [0, 0, 0, 0, 0, 0];
	}
}

function generator() {

	numTrials = parseInt(document.getElementById('numTrials').value);
	var delay = 400/numTrials;

	if (counter < numTrials) {
		counter ++;

		// ---------- Animate Coins ----------
		var val = parseInt(document.getElementById('selector').value);	// get number of coins
		var coinArray = new Array(val);
		var coins = "";
		var allHeads = true;
		var allTails = true;

		for (var i = 0; i < val; i ++) {
			var r = Math.ceil(Math.random() * 12);	// random number from 1-12

			if (r % 2 == 0) {
				tails ++;
			} else {
				heads ++;
			}

			coinArray[i] = r;
			coins += '';
		}

		for (var j = 0; j < coinArray.length; j ++) {
			if (coinArray[j] % 2 != 1) {
				allHeads = false;
			}
		}

		for (var j = 0; j < coinArray.length; j ++) {
			if (coinArray[j] % 2 != 0) {
				allTails = false;
			}
		}

		if (allHeads) {
			consecutiveHeads ++;
		}
		else if (allTails) {
			consecutiveTails ++;
		}

		// ---------- Update Table ----------

		var index = val - 2;

		document.getElementById('num').innerHTML = val;
		document.getElementById('trials').innerHTML = counter;
		document.getElementById('heads').innerHTML = heads;
		document.getElementById('tails').innerHTML = tails;
		document.getElementById('allHeads').innerHTML = consecutiveHeads;
		document.getElementById('allTails').innerHTML = consecutiveTails;

		// ---------- Call Animation Recursively ----------
		document.getElementById('coins').innerHTML = coins;
		timer = setTimeout(generator, delay);
	}

	else {
		clearInterval(timer);
		timer = null;
		counter = 0;

		heads = 0;
		tails = 0;
		consecutiveHeads = 0;
		consecutiveTails = 0;
	}
}

document.onload = function() {

	for (var i = 0; i < stats.length; i ++) {
		var row = new Array(5);

		for (var j = 0; j < row.length; j ++) {
			row[j] = 0;
		}

		stats.push(row);
	}
}
<|endoftext|>


<commit_before>"use strict";

function ChatView (parent, channel, offset)
{
    var container, table, types = {}, init;

    container = document.createElement("div");
    container.className = "chatview";
    parent.appendChild(container);

    // Defeat Firefox, which insists on restoring the last known scroll position.
    setTimeout(function ()
    {
        container.scrollTop = 0;
    }, 1);

    table = document.createElement("table");
    container.appendChild(table);

    function timefmt (timestamp)
    {
        var time, date = new Date((timestamp + offset) * 1000);

        time = document.createElement("time");
        time.setAttribute("datetime", date.toISOString());
        time.setAttribute("title", date.toISOString().replace("T", " ").replace(/\..+$/, ""));
        time.textContent = "[" + Time.instant(date) + "]";

        return time;
    }

    function column (value)
    {
        var column = document.createElement("td");
        column.textContent = value;
        return column;
    }

    function row (type, timestamp, user, message)
    {
        var time, row;

        time = document.createElement("td");
        time.appendChild(timefmt(timestamp));

        row = document.createElement("tr");
        row.className = "chattype" + type;
        row.appendChild(time);
        row.appendChild(column(user));
        row.appendChild(column(message));
        table.appendChild(row);
    }

    // Like rowstar, except it singles out the username in the message part to allow styling.
    function rowspc (type, timestamp, user, message)
    {
        var time, nick, row;

        time = document.createElement("td");
        time.appendChild(timefmt(timestamp));

        nick = document.createElement("span");
        nick.textContent = user;

        row = document.createElement("tr");
        row.className = "chattype" + type;
        row.appendChild(time);
        row.appendChild(column("*"));
        row.appendChild(column(" " + message));
        row.lastChild.insertBefore(nick, row.lastChild.firstChild);
        table.appendChild(row);
    }

    function rowstar (line, message)
    {
        row(line.type, line.timestamp, "*", message);
    }

    // Best guess as to what to do with these.
    types[Relive.CHATTYPE_UNKNOWN] = function (line)
    {
        if (line.strings.length > 1)
        {
            row(line.type, line.timestamp, line.strings[0], line.strings[1]);
        }
        else
        {
            rowstar(line, line.strings[0]);
        }
    };

    types[Relive.CHATTYPE_MESSAGE] = function (line)
    {
        row(line.type, line.timestamp, line.strings[0], line.strings[1]);
    };

    types[Relive.CHATTYPE_ME] = function (line)
    {
        rowspc(line.type, line.timestamp, line.strings[0], line.strings[1]);
    };

    types[Relive.CHATTYPE_JOIN] = function (line)
    {
        rowstar(line, line.strings[0] + " has joined " + channel);
    };

    types[Relive.CHATTYPE_LEAVE] = function (line)
    {
        var msg = line.strings[0] + " has left " + channel;

        if (line.strings.length > 1)
        {
            rowstar(line, msg + " (" + line.strings[1] + ")");
        }
        else
        {
            rowstar(line, msg);
        }
    };

    types[Relive.CHATTYPE_QUIT] = function (line)
    {
        var msg = line.strings[0] + " has quit";

        if (line.strings.length > 1)
        {
            rowstar(line, msg + " (" + line.strings[1] + ")");
        }
        else
        {
            rowstar(line, msg);
        }
    };

    types[Relive.CHATTYPE_NICK] = function (line)
    {
        rowstar(line, line.strings[0] + " is now known as " + line.strings[1]);
    };

    types[Relive.CHATTYPE_TOPIC] = function (line)
    {
        rowstar(line, line.strings[0] + " has set the topic to: " + line.strings[1]);
    };

    // TODO Find an example of channel mode changing and update code to accommodate, if needed.
    types[Relive.CHATTYPE_MODE] = function (line)
    {
        if (line.strings.length > 2)
        {
            rowstar(line, line.strings[0] + " sets mode " + line.strings[1] + " on " + line.strings[2]);
        }
        else
        {
            // Hope this is a channel mode change. If it's not the added or removed mode then the
            // message format should probably be: "Channel " + channel + " modes: " + line.strings[1]
            rowstar(line, line.strings[0] + " sets mode " + line.strings[1] + " on " + channel);
        }
    };

    types[Relive.CHATTYPE_KICK] = function (line)
    {
        var msg = line.strings[0] + " has kicked " + line.strings[1] + " from " + channel;

        if (line.strings.length > 2)
        {
            rowstar(line, msg + " (" + line.strings[2] + ")");
        }
        else
        {
            rowstar(line, msg);
        }
    };

    this.addLine = function (line)
    {
        var scroll = table.children.length && container.scrollTopMax - container.scrollTop <= 34;

        // Just in case, map unknown type numbers to CHATTYPE_UNKNOWN?
        types[line.type](line);

        if (scroll)
        {
            container.scrollTop = container.scrollTopMax;
        }
    };

    this.removeLine = function (index)
    {
        table.removeChild(table.children[index]);
    };
}
<commit_msg>Changed out the check to scroll to the bottom in chatview.js as scrollTopMax may not exist in all browsers. Firefox has some nice amenities ... the more verbose option of subtracting the clientHeight from the scrollHeight gives an appropriate value which is used here now.<commit_after>"use strict";

function ChatView (parent, channel, offset)
{
    var container, table, types = {}, init;

    container = document.createElement("div");
    container.className = "chatview";
    parent.appendChild(container);

    // Defeat Firefox, which insists on restoring the last known scroll position.
    setTimeout(function ()
    {
        container.scrollTop = 0;
    }, 1);

    table = document.createElement("table");
    container.appendChild(table);

    function timefmt (timestamp)
    {
        var time, date = new Date((timestamp + offset) * 1000);

        time = document.createElement("time");
        time.setAttribute("datetime", date.toISOString());
        time.setAttribute("title", date.toISOString().replace("T", " ").replace(/\..+$/, ""));
        time.textContent = "[" + Time.instant(date) + "]";

        return time;
    }

    function column (value)
    {
        var column = document.createElement("td");
        column.textContent = value;
        return column;
    }

    function row (type, timestamp, user, message)
    {
        var time, row;

        time = document.createElement("td");
        time.appendChild(timefmt(timestamp));

        row = document.createElement("tr");
        row.className = "chattype" + type;
        row.appendChild(time);
        row.appendChild(column(user));
        row.appendChild(column(message));
        table.appendChild(row);
    }

    // Like rowstar, except it singles out the username in the message part to allow styling.
    function rowspc (type, timestamp, user, message)
    {
        var time, nick, row;

        time = document.createElement("td");
        time.appendChild(timefmt(timestamp));

        nick = document.createElement("span");
        nick.textContent = user;

        row = document.createElement("tr");
        row.className = "chattype" + type;
        row.appendChild(time);
        row.appendChild(column("*"));
        row.appendChild(column(" " + message));
        row.lastChild.insertBefore(nick, row.lastChild.firstChild);
        table.appendChild(row);
    }

    function rowstar (line, message)
    {
        row(line.type, line.timestamp, "*", message);
    }

    // Best guess as to what to do with these.
    types[Relive.CHATTYPE_UNKNOWN] = function (line)
    {
        if (line.strings.length > 1)
        {
            row(line.type, line.timestamp, line.strings[0], line.strings[1]);
        }
        else
        {
            rowstar(line, line.strings[0]);
        }
    };

    types[Relive.CHATTYPE_MESSAGE] = function (line)
    {
        row(line.type, line.timestamp, line.strings[0], line.strings[1]);
    };

    types[Relive.CHATTYPE_ME] = function (line)
    {
        rowspc(line.type, line.timestamp, line.strings[0], line.strings[1]);
    };

    types[Relive.CHATTYPE_JOIN] = function (line)
    {
        rowstar(line, line.strings[0] + " has joined " + channel);
    };

    types[Relive.CHATTYPE_LEAVE] = function (line)
    {
        var msg = line.strings[0] + " has left " + channel;

        if (line.strings.length > 1)
        {
            rowstar(line, msg + " (" + line.strings[1] + ")");
        }
        else
        {
            rowstar(line, msg);
        }
    };

    types[Relive.CHATTYPE_QUIT] = function (line)
    {
        var msg = line.strings[0] + " has quit";

        if (line.strings.length > 1)
        {
            rowstar(line, msg + " (" + line.strings[1] + ")");
        }
        else
        {
            rowstar(line, msg);
        }
    };

    types[Relive.CHATTYPE_NICK] = function (line)
    {
        rowstar(line, line.strings[0] + " is now known as " + line.strings[1]);
    };

    types[Relive.CHATTYPE_TOPIC] = function (line)
    {
        rowstar(line, line.strings[0] + " has set the topic to: " + line.strings[1]);
    };

    // TODO Find an example of channel mode changing and update code to accommodate, if needed.
    types[Relive.CHATTYPE_MODE] = function (line)
    {
        if (line.strings.length > 2)
        {
            rowstar(line, line.strings[0] + " sets mode " + line.strings[1] + " on " + line.strings[2]);
        }
        else
        {
            // Hope this is a channel mode change. If it's not the added or removed mode then the
            // message format should probably be: "Channel " + channel + " modes: " + line.strings[1]
            rowstar(line, line.strings[0] + " sets mode " + line.strings[1] + " on " + channel);
        }
    };

    types[Relive.CHATTYPE_KICK] = function (line)
    {
        var msg = line.strings[0] + " has kicked " + line.strings[1] + " from " + channel;

        if (line.strings.length > 2)
        {
            rowstar(line, msg + " (" + line.strings[2] + ")");
        }
        else
        {
            rowstar(line, msg);
        }
    };

    this.addLine = function (line)
    {
        var scroll = table.children.length && container.scrollHeight - container.clientHeight - container.scrollTop <= 34;

        // Just in case, map unknown type numbers to CHATTYPE_UNKNOWN?
        types[line.type](line);

        if (scroll)
        {
            container.scrollTop = container.scrollHeight - container.clientHeight;
        }
    };

    this.removeLine = function (index)
    {
        table.removeChild(table.children[index]);
    };
}
<|endoftext|>


<commit_before>function addEgg() {
    //创建一个div
    var div = document.createElement('div');
    //设置div的属性
    div.id='eggdiv';
    div.innerHTML = '';
    div.style.background = "rgba(0,0,0,.85)";
    div.style.position="fixed";
    div.style.zIndex=10000;
    div.style.top="0";
    div.style.bottom="0";
    div.style.left="0";
    div.style.right="0";
    div.onclick=function(){div.parentNode.removeChild(div);};
    var bo = document.body; //获取body对象.
    //动态插入到body中
    bo.insertBefore(div, bo.lastChild);
}
function eggNotice1(){
    alert("啊哈哈，是不是看到动的东西就很想点？可惜不是这里\n提示：仔细找吧，找到一个看似不能按却能按的地方，那就是了√");
}
function eggNotice2(){
    alert("提示：那是一个生日礼物噢！");
}
//儒创建的div我就不客气地借用啦嘻嘻（
function smilp1(){
    alert("哇我的妈，我就说怎么找不到你这玩意儿写哪儿的\n终于被我找到了嘻嘻嘻嘻嘻\n但是你不可以用奇怪的方法找\n请你慢慢把所有可能的一个个点开谢谢合作\n提示2：❤");
}
function smilp2(){
    alert("嗨嗨嗨，不是这里噢❤继续找找w");
}
function smilp3(){
    alert("嗯好的w恭喜恭喜w彩蛋的1/3：\n https://pan.baidu.com \n提示3：既然能找到这个了，下一个就知道是哪里了吧(ﾉ*･ω･)ﾉ");
}
function smilp4(){
    alert("彩蛋寻找完成度：2/3 鼓掌o(〃'▽'〃)o\n /s/1jI66h06 \n好啦，密码到底在哪里呢w\n提示last：你自己找咯◐▽◑");
}
function last(){
    alert("哇我的妈");
}
<commit_msg>Update eggs.js<commit_after>function addEgg() {
    //创建一个div
    var div = document.createElement('div');
    //设置div的属性
    div.id='eggdiv';
    div.innerHTML = '';
    div.style.background = "rgba(0,0,0,.85)";
    div.style.position="fixed";
    div.style.zIndex=10000;
    div.style.top="0";
    div.style.bottom="0";
    div.style.left="0";
    div.style.right="0";
    div.onclick=function(){div.parentNode.removeChild(div);};
    var bo = document.body; //获取body对象.
    //动态插入到body中
    bo.insertBefore(div, bo.lastChild);
}
function eggNotice1(){
    alert("啊哈哈，是不是看到动的东西就很想点？可惜不是这里\n提示：仔细找吧，找到一个看似不能按却能按的地方，那就是了√");
}
function eggNotice2(){
    alert("提示：那是一个生日礼物噢！");
}
//儒创建的div我就不客气地借用啦嘻嘻（
function smilp1(){
    alert("哇我的妈，我就说怎么找不到你这玩意儿写哪儿的\n终于被我找到了嘻嘻嘻嘻嘻\n但是你不可以用奇怪的方法找\n请你慢慢把所有可能的一个个点开谢谢合作\n提示2：❤");
}
function smilp2(){
    alert("哼哼哼");
}
function smilp3(){
    alert("嗯好的w恭喜恭喜w彩蛋的1/3：\n https://pan.baidu.com \n提示3：既然能找到这个了，下一个就知道是哪里了吧(ﾉ*･ω･)ﾉ");
}
function smilp4(){
    alert("彩蛋寻找完成度：2/3 鼓掌o(〃'▽'〃)o\n /s/1jI66h06 \n好啦，密码到底在哪里呢w\n提示last：你自己找咯◐▽◑");
}
function last(){
    alert("哼！");
}
<|endoftext|>


<commit_before>/* global app:true */

(function() {
  'use strict';

  app = app || {};

  app.Project = Backbone.Model.extend({
    idAttribute: '_id',
    defaults: {
      _id: undefined,
      name: '',
      slogan: '',
      company: '',
      companySlogan: '',
      copyrightYear: '',
    },
    url: function() {
      return '/admin/accounts/'+ (this.isNew() ? '' : this.id +'/');
    }
  });

  app.Record = Backbone.Model.extend({
    idAttribute: '_id',
    defaults: {
      _id: undefined,
      'name.full': '',
      company: '',
      phone: '',
      zip: '',
      status: {
        id: undefined,
        name: '',
        userCreated: {}
      },
      userCreated: {}
    },
    url: function() {
      return '/admin/accounts/'+ (this.isNew() ? '' : this.id +'/');
    }
  });

  app.RecordCollection = Backbone.Collection.extend({
    model: app.Record,
    url: '/admin/accounts/',
    parse: function(results) {
      app.pagingView.model.set({
        pages: results.pages,
        items: results.items
      });
      app.filterView.model.set(results.filters);
      return results.data;
    }
  });

  app.Filter = Backbone.Model.extend({
    defaults: {
      search: '',
      status: '',
      sort: '',
      limit: ''
    }
  });

  app.Paging = Backbone.Model.extend({
    defaults: {
      pages: {},
      items: {}
    }
  });

  app.PublicMenuView = Backbone.View.extend({
    el: '#public-menu',
    events: {
      'click #home': 'processHome',
      'click #about': 'processAbout',
      'click #contact': 'processContact',
      'click #signup': 'processSignup',
      'click #login': 'processLogin'
    },
    processHome: function(e){
      e.preventDefault();
      console.log('view: #home clicked');
      Backbone.history.navigate('#home', {trigger: true});
    },
    processAbout: function(e){
      e.preventDefault();
      console.log('view: #about clicked');
      Backbone.history.navigate('#about', {trigger: true});
    },
    processContact: function(e){
      e.preventDefault();
      console.log('view: #contact clicked');
      Backbone.history.navigate('#contact', {trigger: true});
    },
    processSignup: function(e){
      e.preventDefault();
      console.log('view: #signup clicked');
      Backbone.history.navigate('#signup', {trigger: true});
    },
    processLogin: function(e){
      e.preventDefault();
      console.log('view: #login clicked');
      Backbone.history.navigate('#login', {trigger: true});
    },
  });

  app.HeaderView = Backbone.View.extend({
    el: '#header',
    //template: _.template( $('#tmpl-header').html() ),
    events: {
      'submit form': 'preventSubmit',
      'keypress input[type="text"]': 'addNewOnEnter',
      'click .btn-add': 'addNew'
    },
    initialize: function() {
      this.model = new app.Record();
      this.listenTo(this.model, 'change', this.render);
      this.render();
    },
    render: function() {
      this.$el.html(this.template( this.model.attributes ));
    },
    preventSubmit: function(event) {
      event.preventDefault();
    },
    addNewOnEnter: function(event) {
      if (event.keyCode !== 13) { return; }
      event.preventDefault();
      this.addNew();
    },
    addNew: function() {
      if (this.$el.find('[name="name"]').val() === '') {
        alert('Please enter a name.');
      }
      else {
        this.model.save({
          'name.full': this.$el.find('[name="name"]').val()
        },{
          success: function(model, response) {
            if (response.success) {
              model.id = response.record._id;
              location.href = model.url();
            }
            else {
              alert(response.errors.join('\n'));
            }
          }
        });
      }
    }
  });

  app.ResultsView = Backbone.View.extend({
    el: '#results-table',
    //template: _.template( $('#tmpl-results-table').html() ),
    initialize: function() {
      this.collection = new app.RecordCollection( app.mainView.results.data );
      this.listenTo(this.collection, 'reset', this.render);
      this.render();
    },
    render: function() {
      this.$el.html( this.template() );

      var frag = document.createDocumentFragment();
      this.collection.each(function(record) {
        var view = new app.ResultsRowView({ model: record });
        frag.appendChild(view.render().el);
      }, this);
      $('#results-rows').append(frag);

      if (this.collection.length === 0) {
        $('#results-rows').append( $('#tmpl-results-empty-row').html() );
      }
    }
  });

  app.ResultsRowView = Backbone.View.extend({
    tagName: 'tr',
    //template: _.template( $('#tmpl-results-row').html() ),
    events: {
      'click .btn-details': 'viewDetails'
    },
    viewDetails: function() {
      location.href = this.model.url();
    },
    render: function() {
      this.$el.html(this.template( this.model.attributes ));
      this.$el.find('.timeago').each(function(index, indexValue) {
        if (indexValue.innerText) {
          var myMoment = moment(indexValue.innerText);
          indexValue.innerText = myMoment.from();
          if (indexValue.getAttribute('data-age')) {
            indexValue.innerText = indexValue.innerText.replace('ago', 'old');
          }
        }
      });
      return this;
    }
  });

  app.FilterView = Backbone.View.extend({
    el: '#filters',
    //template: _.template( $('#tmpl-filters').html() ),
    events: {
      'submit form': 'preventSubmit',
      'keypress input[type="text"]': 'filterOnEnter',
      'change select': 'filter'
    },
    initialize: function() {
      this.model = new app.Filter( app.mainView.results.filters );
      this.listenTo(this.model, 'change', this.render);
      this.render();
    },
    render: function() {
      this.$el.html(this.template( this.model.attributes ));

      for (var key in this.model.attributes) {
        if (this.model.attributes.hasOwnProperty(key)) {
          this.$el.find('[name="'+ key +'"]').val(this.model.attributes[key]);
        }
      }
    },
    preventSubmit: function(event) {
      event.preventDefault();
    },
    filterOnEnter: function(event) {
      if (event.keyCode !== 13) { return; }
      this.filter();
    },
    filter: function() {
      var query = $('#filters form').serialize();
      Backbone.history.navigate('q/'+ query, { trigger: true });
    }
  });

  app.PagingView = Backbone.View.extend({
    el: '#results-paging',
    //template: _.template( $('#tmpl-results-paging').html() ),
    events: {
      'click .btn-page': 'goToPage'
    },
    initialize: function() {
      this.model = new app.Paging({ pages: app.mainView.results.pages, items: app.mainView.results.items });
      this.listenTo(this.model, 'change', this.render);
      this.render();
    },
    render: function() {
      if (this.model.get('pages').total > 1) {
        this.$el.html(this.template( this.model.attributes ));

        if (!this.model.get('pages').hasPrev) {
          this.$el.find('.btn-prev').attr('disabled', 'disabled');
        }

        if (!this.model.get('pages').hasNext) {
          this.$el.find('.btn-next').attr('disabled', 'disabled');
        }
      }
      else {
        this.$el.empty();
      }
    },
    goToPage: function(event) {
      var query = $('#filters form').serialize() +'&page='+ $(event.target).data('page');
      Backbone.history.navigate('q/'+ query, { trigger: true });
      $('body').scrollTop(0);
    }
  });

  app.MainView = Backbone.View.extend({
    //el: 'body',
    el: '.page .container',
    initialize: function() {
      app.mainView = this;
      //this.results = JSON.parse( unescape($('#data-results').html()) );

      app.publicMenuView = new app.PublicMenuView();
      //app.headerView = new app.HeaderView();
      //app.resultsView = new app.ResultsView();
      //app.filterView = new app.FilterView();
      //app.pagingView = new app.PagingView();
    }
  });

  app.Router = Backbone.Router.extend({
    routes: {
      '': 'default',
      'q/:params': 'query',
      '#home': 'home',
      '#about': 'about',
      '#contact': 'contact',
      '#signup': 'signup',
      '#login': 'login'
    },
    initialize: function() {
      app.mainView = new app.MainView();
    },
    default: function() {
      if (!app.firstLoad) {
        app.resultsView.collection.fetch({ reset: true });
      }

      app.firstLoad = false;
    },
    query: function(params) {
      app.resultsView.collection.fetch({ data: params, reset: true });
      app.firstLoad = false;
    },
    home: function() {
      console.log('router: home');
    },
    about: function() {
      console.log('router: about');
    },
    contact: function() {
      console.log('router: contact');
    },
    signup: function() {
      console.log('router: signup');
    },
    login: function() {
      console.log('router: login');
    }
  });

  $(document).ready(function() {
    console.log('app loading...');
    app.firstLoad = true;
    app.router = new app.Router();
    Backbone.history.start();
    console.log('app loaded!');
  });
}());
<commit_msg>testing routing<commit_after>/* global app:true */

(function() {
  'use strict';

  app = app || {};

  app.Project = Backbone.Model.extend({
    idAttribute: '_id',
    defaults: {
      _id: undefined,
      name: '',
      slogan: '',
      company: '',
      companySlogan: '',
      copyrightYear: '',
    },
    url: function() {
      return '/admin/accounts/'+ (this.isNew() ? '' : this.id +'/');
    }
  });

  app.Record = Backbone.Model.extend({
    idAttribute: '_id',
    defaults: {
      _id: undefined,
      'name.full': '',
      company: '',
      phone: '',
      zip: '',
      status: {
        id: undefined,
        name: '',
        userCreated: {}
      },
      userCreated: {}
    },
    url: function() {
      return '/admin/accounts/'+ (this.isNew() ? '' : this.id +'/');
    }
  });

  app.RecordCollection = Backbone.Collection.extend({
    model: app.Record,
    url: '/admin/accounts/',
    parse: function(results) {
      app.pagingView.model.set({
        pages: results.pages,
        items: results.items
      });
      app.filterView.model.set(results.filters);
      return results.data;
    }
  });

  app.Filter = Backbone.Model.extend({
    defaults: {
      search: '',
      status: '',
      sort: '',
      limit: ''
    }
  });

  app.Paging = Backbone.Model.extend({
    defaults: {
      pages: {},
      items: {}
    }
  });

  app.PublicMenuView = Backbone.View.extend({
    el: '#public-menu',
    events: {
      'click #home': 'processHome',
      'click #about': 'processAbout',
      'click #contact': 'processContact',
      'click #signup': 'processSignup',
      'click #login': 'processLogin'
    },
    processHome: function(e){
      e.preventDefault();
      console.log('view: #home clicked');
      Backbone.history.navigate('home', {trigger: true});
    },
    processAbout: function(e){
      e.preventDefault();
      console.log('view: #about clicked');
      Backbone.history.navigate('about', {trigger: true});
    },
    processContact: function(e){
      e.preventDefault();
      console.log('view: #contact clicked');
      Backbone.history.navigate('#contact', {trigger: true});
    },
    processSignup: function(e){
      e.preventDefault();
      console.log('view: #signup clicked');
      Backbone.history.navigate('#signup', {trigger: true});
    },
    processLogin: function(e){
      e.preventDefault();
      console.log('view: #login clicked');
      Backbone.history.navigate('#login', {trigger: true});
    },
  });

  app.HeaderView = Backbone.View.extend({
    el: '#header',
    //template: _.template( $('#tmpl-header').html() ),
    events: {
      'submit form': 'preventSubmit',
      'keypress input[type="text"]': 'addNewOnEnter',
      'click .btn-add': 'addNew'
    },
    initialize: function() {
      this.model = new app.Record();
      this.listenTo(this.model, 'change', this.render);
      this.render();
    },
    render: function() {
      this.$el.html(this.template( this.model.attributes ));
    },
    preventSubmit: function(event) {
      event.preventDefault();
    },
    addNewOnEnter: function(event) {
      if (event.keyCode !== 13) { return; }
      event.preventDefault();
      this.addNew();
    },
    addNew: function() {
      if (this.$el.find('[name="name"]').val() === '') {
        alert('Please enter a name.');
      }
      else {
        this.model.save({
          'name.full': this.$el.find('[name="name"]').val()
        },{
          success: function(model, response) {
            if (response.success) {
              model.id = response.record._id;
              location.href = model.url();
            }
            else {
              alert(response.errors.join('\n'));
            }
          }
        });
      }
    }
  });

  app.ResultsView = Backbone.View.extend({
    el: '#results-table',
    //template: _.template( $('#tmpl-results-table').html() ),
    initialize: function() {
      this.collection = new app.RecordCollection( app.mainView.results.data );
      this.listenTo(this.collection, 'reset', this.render);
      this.render();
    },
    render: function() {
      this.$el.html( this.template() );

      var frag = document.createDocumentFragment();
      this.collection.each(function(record) {
        var view = new app.ResultsRowView({ model: record });
        frag.appendChild(view.render().el);
      }, this);
      $('#results-rows').append(frag);

      if (this.collection.length === 0) {
        $('#results-rows').append( $('#tmpl-results-empty-row').html() );
      }
    }
  });

  app.ResultsRowView = Backbone.View.extend({
    tagName: 'tr',
    //template: _.template( $('#tmpl-results-row').html() ),
    events: {
      'click .btn-details': 'viewDetails'
    },
    viewDetails: function() {
      location.href = this.model.url();
    },
    render: function() {
      this.$el.html(this.template( this.model.attributes ));
      this.$el.find('.timeago').each(function(index, indexValue) {
        if (indexValue.innerText) {
          var myMoment = moment(indexValue.innerText);
          indexValue.innerText = myMoment.from();
          if (indexValue.getAttribute('data-age')) {
            indexValue.innerText = indexValue.innerText.replace('ago', 'old');
          }
        }
      });
      return this;
    }
  });

  app.FilterView = Backbone.View.extend({
    el: '#filters',
    //template: _.template( $('#tmpl-filters').html() ),
    events: {
      'submit form': 'preventSubmit',
      'keypress input[type="text"]': 'filterOnEnter',
      'change select': 'filter'
    },
    initialize: function() {
      this.model = new app.Filter( app.mainView.results.filters );
      this.listenTo(this.model, 'change', this.render);
      this.render();
    },
    render: function() {
      this.$el.html(this.template( this.model.attributes ));

      for (var key in this.model.attributes) {
        if (this.model.attributes.hasOwnProperty(key)) {
          this.$el.find('[name="'+ key +'"]').val(this.model.attributes[key]);
        }
      }
    },
    preventSubmit: function(event) {
      event.preventDefault();
    },
    filterOnEnter: function(event) {
      if (event.keyCode !== 13) { return; }
      this.filter();
    },
    filter: function() {
      var query = $('#filters form').serialize();
      Backbone.history.navigate('q/'+ query, { trigger: true });
    }
  });

  app.PagingView = Backbone.View.extend({
    el: '#results-paging',
    //template: _.template( $('#tmpl-results-paging').html() ),
    events: {
      'click .btn-page': 'goToPage'
    },
    initialize: function() {
      this.model = new app.Paging({ pages: app.mainView.results.pages, items: app.mainView.results.items });
      this.listenTo(this.model, 'change', this.render);
      this.render();
    },
    render: function() {
      if (this.model.get('pages').total > 1) {
        this.$el.html(this.template( this.model.attributes ));

        if (!this.model.get('pages').hasPrev) {
          this.$el.find('.btn-prev').attr('disabled', 'disabled');
        }

        if (!this.model.get('pages').hasNext) {
          this.$el.find('.btn-next').attr('disabled', 'disabled');
        }
      }
      else {
        this.$el.empty();
      }
    },
    goToPage: function(event) {
      var query = $('#filters form').serialize() +'&page='+ $(event.target).data('page');
      Backbone.history.navigate('q/'+ query, { trigger: true });
      $('body').scrollTop(0);
    }
  });

  app.MainView = Backbone.View.extend({
    //el: 'body',
    el: '.page .container',
    initialize: function() {
      app.mainView = this;
      //this.results = JSON.parse( unescape($('#data-results').html()) );

      app.publicMenuView = new app.PublicMenuView();
      //app.headerView = new app.HeaderView();
      //app.resultsView = new app.ResultsView();
      //app.filterView = new app.FilterView();
      //app.pagingView = new app.PagingView();
    }
  });

  app.Router = Backbone.Router.extend({
    routes: {
      '': 'default',
      'q/:params': 'query',
      'home': 'home',
      'about': 'about',
      '#contact': 'contact',
      '#signup': 'signup',
      '#login': 'login'
    },
    initialize: function() {
      app.mainView = new app.MainView();
    },
    default: function() {
      if (!app.firstLoad) {
        app.resultsView.collection.fetch({ reset: true });
      }

      app.firstLoad = false;
    },
    query: function(params) {
      app.resultsView.collection.fetch({ data: params, reset: true });
      app.firstLoad = false;
    },
    home: function() {
      console.log('router: home');
    },
    about: function() {
      console.log('router: about');
    },
    contact: function() {
      console.log('router: contact');
    },
    signup: function() {
      console.log('router: signup');
    },
    login: function() {
      console.log('router: login');
    }
  });

  $(document).ready(function() {
    console.log('app loading...');
    app.firstLoad = true;
    app.router = new app.Router();
    Backbone.history.start();
    console.log('app loaded!');
  });
}());
<|endoftext|>


<commit_before>"use strict";

const normalizer = require("./cli-normalizer");

const detailOptions = normalizer.normalizeDetailOptions({
  "bracket-spacing": {
    type: "boolean",
    category: "format",
    hidden: true
  },
  color: {
    // The supports-color package (a sub sub dependency) looks directly at
    // `process.argv` for `--no-color` and such-like options. The reason it is
    // listed here is to avoid "Ignored unknown option: --no-color" warnings.
    // See https://github.com/chalk/supports-color/#info for more information.
    type: "boolean",
    default: true,
    hidden: true
  },
  config: {
    type: "path",
    category: "config",
    description:
      "Path to a prettier configuration file (.prettierrc, package.json, prettier.config.js)."
  },
  "config-precedence": {
    type: "choice",
    category: "config",
    default: "cli-override",
    choices: ["cli-override", "file-override", "prefer-file"],
    description: dedent(`
      Defines how config file should be evaluated in combination of CLI options
      cli-override  | default config => config file => CLI options
      file-override | default config => CLI options => config file
      prefer-file   | default config => config file (if config file is found) or
                      default config => CLI options (if no config file is found)
      Defaults to cli-override
    `)
  },
  "cursor-offset": {
    type: "int",
    exception: -1,
    description: dedent(`
      Print (to stderr) where a cursor at the given position would move to after formatting.
      This option cannot be used with --range-start and --range-end
    `)
  },
  "debug-check": {
    type: "boolean",
    hidden: true
  },
  "debug-print-doc": {
    type: "boolean",
    hidden: true
  },
  "find-config-path": {
    type: "path",
    category: "config",
    description:
      "Finds and prints the path to a configuration file for a given input file."
  },
  "flow-parser": {
    // Deprecated in 0.0.10
    type: "boolean",
    category: "format",
    hidden: true,
    deprecated: "Use `--parser flow` instead."
  },
  help: {
    type: "boolean",
    alias: "h",
    description: "Show help."
  },
  "ignore-path": {
    type: "path",
    category: "config",
    default: ".prettierignore",
    description: dedent(`
      Path to a file containing patterns that describe files to ignore.
      Defaults to ./.prettierignore.
    `)
  },
  "jsx-bracket-same-line": {
    type: "boolean",
    category: "format",
    description: "Put > on the last line instead of at a new line."
  },
  "list-different": {
    type: "boolean",
    alias: "l",
    description:
      "Print filenames of files that are different from Prettier formatting."
  },
  "no-bracket-spacing": {
    type: "boolean",
    category: "format",
    description: "Do not print spaces between brackets."
  },
  "no-color": {
    type: "boolean",
    description: "Do not colorize error messages."
  },
  "no-config": {
    type: "boolean",
    category: "config",
    description: "Do not look for a configuration file."
  },
  "no-semi": {
    type: "boolean",
    category: "format",
    description:
      "Do not print semicolons, except at the beginning of lines which may need them."
  },
  parser: {
    type: "choice",
    category: "format",
    exception: value => typeof value === "string",
    choices: ["flow", "babylon", "typescript", "postcss", "json", "graphql"],
    description: "Specify which parse to use. Defaults to babylon.",
    getter: (value, argv) => (argv["flow-parser"] ? "flow" : value)
  },
  "print-width": {
    type: "int",
    category: "format",
    description:
      "Specify the length of line that the printer will wrap on. Defaults to 80."
  },
  "range-end": {
    type: "int",
    category: "format",
    exception: Infinity,
    description: dedent(`
      Format code ending at a given character offset (exclusive).
      The range will extend forwards to the end of the selected statement.
      This option cannot be used with --cursor-offset.
      Defaults to Infinity.
    `)
  },
  "range-start": {
    type: "int",
    category: "format",
    description: dedent(`
      Format code starting at a given character offset.
      The range will extend backwards to the start of the first line containing the selected statement.
      This option cannot be used with --cursor-offset.
      Defaults to 0.
    `)
  },
  semi: {
    type: "boolean",
    category: "format",
    hidden: true
  },
  "single-quote": {
    type: "boolean",
    category: "format",
    description: "Use single quotes instead of double quotes."
  },
  stdin: {
    type: "boolean",
    description: "Read input from stdin."
  },
  "stdin-filepath": {
    type: "path",
    description: "Path to the file used to read from stdin."
  },
  "tab-width": {
    type: "int",
    category: "format",
    description:
      "Specify the number of spaces per indentation-level. Defaults to 2."
  },
  "trailing-comma": {
    type: "choice",
    category: "format",
    choices: [
      "none",
      "es5",
      "all",
      { value: "", deprecated: true, redirect: "es5" }
    ],
    description:
      "Print trailing commas wherever possible when multi-line. Defaults to none."
  },
  "use-tabs": {
    type: "boolean",
    category: "format",
    description: "Indent lines with tabs instead of spaces."
  },
  version: {
    type: "boolean",
    alias: "v",
    description: "Print Prettier version."
  },
  "with-node-modules": {
    type: "boolean",
    category: "config",
    description: "Process files inside 'node_modules' directory."
  },
  write: {
    type: "boolean",
    description: "Edit the file in-place. (Beware!)"
  }
});

const minimistOptions = {
  boolean: detailOptions
    .filter(
      option => !option.name.startsWith("no-") && option.type === "boolean"
    )
    .map(option => option.name),
  string: detailOptions
    .filter(
      option => !option.name.startsWith("no-") && option.type !== "boolean"
    )
    .map(option => option.name),
  default: detailOptions
    .filter(option => option.default !== undefined)
    .reduce(
      (current, option) =>
        Object.assign({ [option.name]: option.default }, current),
      {}
    ),
  alias: detailOptions
    .filter(option => option.alias !== undefined)
    .reduce(
      (current, option) =>
        Object.assign({ [option.name]: option.alias }, current),
      {}
    ),
  unknown: param => {
    if (param.startsWith("-")) {
      console.warn(`Ignored unknown option: ${param}\n`);
      return false;
    }
  }
};

function dedent(str) {
  const spaces = str.match(/\n^( +)/m)[1].length;
  return str.replace(new RegExp(`^ {${spaces}}`, "gm"), "").trim();
}

module.exports = {
  minimistOptions,
  detailOptions
};
<commit_msg>refactor: add comment<commit_after>"use strict";

const normalizer = require("./cli-normalizer");

const detailOptions = normalizer.normalizeDetailOptions({
  "bracket-spacing": {
    type: "boolean",
    category: "format",
    hidden: true
  },
  color: {
    // The supports-color package (a sub sub dependency) looks directly at
    // `process.argv` for `--no-color` and such-like options. The reason it is
    // listed here is to avoid "Ignored unknown option: --no-color" warnings.
    // See https://github.com/chalk/supports-color/#info for more information.
    type: "boolean",
    default: true,
    hidden: true
  },
  config: {
    type: "path",
    category: "config",
    description:
      "Path to a prettier configuration file (.prettierrc, package.json, prettier.config.js)."
  },
  "config-precedence": {
    type: "choice",
    category: "config",
    default: "cli-override",
    choices: ["cli-override", "file-override", "prefer-file"],
    description: dedent(`
      Defines how config file should be evaluated in combination of CLI options
      cli-override  | default config => config file => CLI options
      file-override | default config => CLI options => config file
      prefer-file   | default config => config file (if config file is found) or
                      default config => CLI options (if no config file is found)
      Defaults to cli-override
    `)
  },
  "cursor-offset": {
    type: "int",
    exception: -1,
    description: dedent(`
      Print (to stderr) where a cursor at the given position would move to after formatting.
      This option cannot be used with --range-start and --range-end
    `)
  },
  "debug-check": {
    type: "boolean",
    hidden: true
  },
  "debug-print-doc": {
    type: "boolean",
    hidden: true
  },
  "find-config-path": {
    type: "path",
    category: "config",
    description:
      "Finds and prints the path to a configuration file for a given input file."
  },
  "flow-parser": {
    // Deprecated in 0.0.10
    type: "boolean",
    category: "format",
    hidden: true,
    deprecated: "Use `--parser flow` instead."
  },
  help: {
    type: "boolean",
    alias: "h",
    description: "Show help."
  },
  "ignore-path": {
    type: "path",
    category: "config",
    default: ".prettierignore",
    description: dedent(`
      Path to a file containing patterns that describe files to ignore.
      Defaults to ./.prettierignore.
    `)
  },
  "jsx-bracket-same-line": {
    type: "boolean",
    category: "format",
    description: "Put > on the last line instead of at a new line."
  },
  "list-different": {
    type: "boolean",
    alias: "l",
    description:
      "Print filenames of files that are different from Prettier formatting."
  },
  "no-bracket-spacing": {
    type: "boolean",
    category: "format",
    description: "Do not print spaces between brackets."
  },
  "no-color": {
    type: "boolean",
    description: "Do not colorize error messages."
  },
  "no-config": {
    type: "boolean",
    category: "config",
    description: "Do not look for a configuration file."
  },
  "no-semi": {
    type: "boolean",
    category: "format",
    description:
      "Do not print semicolons, except at the beginning of lines which may need them."
  },
  parser: {
    type: "choice",
    category: "format",
    exception: value => typeof value === "string", // allow path to a parser module
    choices: ["flow", "babylon", "typescript", "postcss", "json", "graphql"],
    description: "Specify which parse to use. Defaults to babylon.",
    getter: (value, argv) => (argv["flow-parser"] ? "flow" : value)
  },
  "print-width": {
    type: "int",
    category: "format",
    description:
      "Specify the length of line that the printer will wrap on. Defaults to 80."
  },
  "range-end": {
    type: "int",
    category: "format",
    exception: Infinity,
    description: dedent(`
      Format code ending at a given character offset (exclusive).
      The range will extend forwards to the end of the selected statement.
      This option cannot be used with --cursor-offset.
      Defaults to Infinity.
    `)
  },
  "range-start": {
    type: "int",
    category: "format",
    description: dedent(`
      Format code starting at a given character offset.
      The range will extend backwards to the start of the first line containing the selected statement.
      This option cannot be used with --cursor-offset.
      Defaults to 0.
    `)
  },
  semi: {
    type: "boolean",
    category: "format",
    hidden: true
  },
  "single-quote": {
    type: "boolean",
    category: "format",
    description: "Use single quotes instead of double quotes."
  },
  stdin: {
    type: "boolean",
    description: "Read input from stdin."
  },
  "stdin-filepath": {
    type: "path",
    description: "Path to the file used to read from stdin."
  },
  "tab-width": {
    type: "int",
    category: "format",
    description:
      "Specify the number of spaces per indentation-level. Defaults to 2."
  },
  "trailing-comma": {
    type: "choice",
    category: "format",
    choices: [
      "none",
      "es5",
      "all",
      { value: "", deprecated: true, redirect: "es5" }
    ],
    description:
      "Print trailing commas wherever possible when multi-line. Defaults to none."
  },
  "use-tabs": {
    type: "boolean",
    category: "format",
    description: "Indent lines with tabs instead of spaces."
  },
  version: {
    type: "boolean",
    alias: "v",
    description: "Print Prettier version."
  },
  "with-node-modules": {
    type: "boolean",
    category: "config",
    description: "Process files inside 'node_modules' directory."
  },
  write: {
    type: "boolean",
    description: "Edit the file in-place. (Beware!)"
  }
});

const minimistOptions = {
  boolean: detailOptions
    .filter(
      option => !option.name.startsWith("no-") && option.type === "boolean"
    )
    .map(option => option.name),
  string: detailOptions
    .filter(
      option => !option.name.startsWith("no-") && option.type !== "boolean"
    )
    .map(option => option.name),
  default: detailOptions
    .filter(option => option.default !== undefined)
    .reduce(
      (current, option) =>
        Object.assign({ [option.name]: option.default }, current),
      {}
    ),
  alias: detailOptions
    .filter(option => option.alias !== undefined)
    .reduce(
      (current, option) =>
        Object.assign({ [option.name]: option.alias }, current),
      {}
    ),
  unknown: param => {
    if (param.startsWith("-")) {
      console.warn(`Ignored unknown option: ${param}\n`);
      return false;
    }
  }
};

function dedent(str) {
  const spaces = str.match(/\n^( +)/m)[1].length;
  return str.replace(new RegExp(`^ {${spaces}}`, "gm"), "").trim();
}

module.exports = {
  minimistOptions,
  detailOptions
};
<|endoftext|>


<commit_before>// eslint-disable filenames/match-exported
import React from "react"
import { render } from "react-dom"
import { BrowserRouter } from "react-router"
import { CodeSplitProvider, rehydrateState } from "code-split-component"
import { ApolloProvider } from "react-apollo"

import ReactHotLoader from "./ReactHotLoader"
import App from "../app/App"
import { createApolloClient } from "../app/Data"

// Get the DOM Element that will host our React application.
const container = document.querySelector("#app")

function renderApp(AppComponent)
{
  console.log("Client: Initialize state from server:", window.APP_STATE)
  const apollo = createApolloClient({
    initialState: window.APP_STATE
  })

  console.log("Client: Rehydrating code splitting state...")
  // Firstly we ensure that we rehydrate any code split state provided to us
  // by the server response. This state typically indicates which bundles/chunks
  // need to be registered for our application to render and the React checksum
  // to match the server response.
  // @see https://github.com/ctrlplusb/code-split-component
  rehydrateState().then((codeSplitState) =>
  {
    console.log("Client: Code Splitting State:", codeSplitState ? codeSplitState.length : 0)
    return render(
      <ReactHotLoader>
        <CodeSplitProvider state={codeSplitState}>
          <BrowserRouter>
            <ApolloProvider client={apollo.client} store={apollo.store}>
              <AppComponent/>
            </ApolloProvider>
          </BrowserRouter>
        </CodeSplitProvider>
      </ReactHotLoader>,
      container
    )
  })
}

// The following is needed so that we can hot reload our App.
if (process.env.NODE_ENV === "development" && module.hot) {
  // Accept changes to this file for hot reloading.
  module.hot.accept("./index.js")

  // Any changes to our App will cause a hotload re-render.
  module.hot.accept(
    "../app/App",
    () => renderApp(require("../app/App").default)
  )

  // Enable Webpack hot module replacement for reducers. This is so that we
  // don"t lose all of our current application state during hot reloading.
  /*
  module.hot.accept("../app/reducers", () => {
    const nextRootReducer = require("../app/reducers").default // eslint-disable-line global-require
    store.replaceReducer(nextRootReducer)
  })
  */
}

renderApp(App)
<commit_msg>Minor changes<commit_after>// eslint-disable filenames/match-exported
import React from "react"
import { render } from "react-dom"
import { BrowserRouter } from "react-router"
import { CodeSplitProvider, rehydrateState } from "code-split-component"
import { ApolloProvider } from "react-apollo"

import ReactHotLoader from "./ReactHotLoader"
import App from "../app/App"
import { createApolloClient } from "../app/Data"

// Get the DOM Element that will host our React application.
const container = document.querySelector("#app")

function renderApp(AppComponent)
{
  console.log("Client: Initialize state from server:", window.APP_STATE)
  const apollo = createApolloClient({
    initialState: window.APP_STATE
  })

  // Firstly we ensure that we rehydrate any code split state provided to us
  // by the server response. This state typically indicates which bundles/chunks
  // need to be registered for our application to render and the React checksum
  // to match the server response.
  // @see https://github.com/ctrlplusb/code-split-component
  console.log("Client: Rehydrating code splitting state...")
  rehydrateState().then((codeSplitState) =>
  {
    console.log("Client: Code Splitting State:", codeSplitState ? codeSplitState.length : 0)
    return render(
      <ReactHotLoader>
        <CodeSplitProvider state={codeSplitState}>
          <BrowserRouter>
            <ApolloProvider client={apollo.client} store={apollo.store}>
              <AppComponent/>
            </ApolloProvider>
          </BrowserRouter>
        </CodeSplitProvider>
      </ReactHotLoader>,
      container
    )
  })
}

// The following is needed so that we can hot reload our App.
if (process.env.NODE_ENV === "development" && module.hot)
{
  // Accept changes to this file for hot reloading.
  module.hot.accept("./index.js")

  // Any changes to our App will cause a hotload re-render.
  module.hot.accept("../app/App", () => renderApp(require("../app/App").default))

  // Enable Webpack hot module replacement for reducers. This is so that we
  // don"t lose all of our current application state during hot reloading.
  /*
  module.hot.accept("../app/reducers", () => {
    const nextRootReducer = require("../app/reducers").default // eslint-disable-line global-require
    store.replaceReducer(nextRootReducer)
  })
  */
}

renderApp(App)
<|endoftext|>