<commit_before>define(function(require) {
  "use strict";

  var $                = require("jquery");
  var Modal            = require("modal");
  var Validation       = require("validation");
  var ImageCrop        = require("images/ImageCrop");
  var ImageCropPreview = require("../images/ImageCropPreview");

  /**
   * Handles the modal interface for image upload buttons.
   * Requires a modal to be on the page with an id '#modal--crop'
   * The modal should have a form '#dosomething-reportback-image-form'
   * and a div to place the image preview '.image-wrapper'.
   *
   * @param {jQuery} $button  The file upload button
   */
  var ImageUpload = function($button) {
    this.$uploadButton          = $button;
    this.$cropModal             = $("#modal--crop");
    this.$reportbackForm        = $("#dosomething-reportback-form");
    this.$imageForm             = this.$cropModal.find("#dosomething-reportback-image-form");
    this.$imageCaption          = this.$imageForm.find("#modal-caption");
    this.$cropButton            = this.$imageForm.find(".button");
    this.$imagePreview          = this.$cropModal.find(".image-preview");
    this.$reportbackSubmissions = $(".reportback__submissions");
    this.imageValues            = {};
    this.readyToSave            = false;

    // Validation
    this.fileTypes              = ['image/png', 'image/gif', 'image/jpeg', 'image/pjpeg'];
    this.fileSizeLimit          = 10000000; // 10mb
    this.typeError              = "Only JPEG, PNG, and GIF images are allowed";
    this.dimensionsError        = "Please upload a larger photo. Min. size is 480px by 480px.";
    this.sizeError              = "Please upload an image under 10MB";

    this.init();
  };

  /**
   * Initalizes event listeners
   *
   */
  ImageUpload.prototype.init = function () {
    var _this = this;

    this.$uploadButton.on("change", function(event) {
      event.preventDefault();

      var files = !!this.files ? this.files : [];

      // If no file selected/no FileReader support, we're all done
      if (!files.length || !window.FileReader) {
        return;
      }

      // Validate image type and file size before proceeding.
      if (!_this.validImageType(files)) {
        _this.showError(_this.typeError);

        return;
      }

      if (!_this.validFileSize(files)) {
        _this.showError(_this.sizeError);

        return;
      }

      var fr = new FileReader();

      if (window.navigator.userAgent.match(/iPad/i) || window.navigator.userAgent.match(/iPhone/i)) {
        fr.readAsArrayBuffer(this.files[0]);
        fr.onload = function () {
          var blob = _this.getStrippedBlob(this.result);
          var urlCreator = window.URL || window.webkitURL;
          var imageUrl = urlCreator.createObjectURL(blob);
          _this.loadImage(imageUrl);
        };
      }
      else {
        fr.readAsDataURL(files[0]);

        fr.onloadend = function() {
          var result = this.result;
          _this.loadImage(result);
        };
      }
    });

    Modal.Events.subscribe("Modal:Close", function() {
      _this.resetFileField();

      // Move the upload button back into the form.
      _this.moveUploadButton($("#edit-reportback-file"));

      if (_this.readyToSave) {
        // Add a button to edit the image.
        _this.createEditButton();
      }
    });

    // When the modal opens, move the upload button into the modal,
    // so users can change their photo.
    Modal.Events.subscribe("Modal:Open", function() {
      _this.moveUploadButton($(".-change .button"));
    });
  };

  /**
   * Detatches and moves the current upload button
   * @param {jQuery}  The element to move the button to.
   */
  ImageUpload.prototype.moveUploadButton = function($el) {
    var $button = this.$uploadButton.detach();

    $button.appendTo($el);
  };

  /**
   * Validates the caption field in the modal.
   * @param  {Function} callback  If validation passes, then lets rock on!
   * @return {void}
   */
  ImageUpload.prototype.validateCaption = function(callback, image) {
    var _this = this;

    Validation.validateField(this.$imageCaption, true, function($field, result) {
      Validation.showValidationMessage($field, result);

      if (result.success) {
        callback(_this, image);
      }
    });
  };

  /**
   * Everything is set, engage in cropping the selected image.
   * @param  {object} data  ImageUpload object.
   * @param  {object} image  Image object.
   * @return {void}
   */
  ImageUpload.prototype.engageImageCrop = function(data, image) {
    var _this = data;

    // Send crop information to the main reportback form
    // so backend can use to crop.
    ImageCrop.populateFields(_this.$reportbackForm);

    // Create a crop preview on the client side.
    ImageCropPreview.cropPreview(image, _this.getCropValues());

    // The user clicked "done", so we can save this version of the crop
    // and not reset the file field.
    _this.readyToSave = true;

    // Close the modal.
    Modal.close();
  };

  /**
   * Opens the modal making sure the done button is reset.
   */
  ImageUpload.prototype.openModal = function() {
    this.enableSubmit();

    Modal.open(this.$cropModal,
      {
        animated: false,
        closeButton: "closeButtonOnly",
      }
    );
  };

  /**
   * Clears the file field input and resets it globally,
   * if the user accidentally closed out of the modal.
   * Allows the user to re-upload an image and edit it.
   */
  ImageUpload.prototype.resetFileField = function() {
    var $input = this.$uploadButton;

    if (!this.readyToSave) {
      $input.replaceWith(this.$uploadButton = $input.val("").clone(true));
    }
  };

  /**
   * Creates a button the user can click to re-open the modal
   * and edit the crop they selected.
   */
  ImageUpload.prototype.createEditButton = function() {
    var _this = this;
    if (!this.$reportbackSubmissions.find(".button--edit").length) {
      var $editButton = $("edit photo");
      this.$uploadButton.parent().hide().before($editButton);

      $editButton.click(function() {
        _this.openModal();
      });
    }
  };

  /**
   * Gets crop values from form and returns an object.
   */
  ImageUpload.prototype.getCropValues = function() {
    return {
      x       : this.$reportbackForm.find("input[name='crop_x']").val(),
      y       : this.$reportbackForm.find("input[name='crop_y']").val(),
      width   : this.$reportbackForm.find("input[name='crop_width']").val(),
      height  : this.$reportbackForm.find("input[name='crop_height']").val(),
      degrees : parseInt(this.$reportbackForm.find("input[name='crop_rotate']").val()),
      caption : this.$reportbackForm.find("input[name='caption']").val(),
    };
  };

  /**
   * Enables submit button in modal when it opens.
   */
  ImageUpload.prototype.enableSubmit = function() {
    var $submitButton = this.$cropModal.find(".-done");

    if ($submitButton.prop("disabled")) {
      $submitButton.prop("disabled", false);
    }

    if ($submitButton.hasClass("is-loading")) {
      $submitButton.removeClass("is-loading");
    }
  };

  /**
   * Validates image size.
   */
  ImageUpload.prototype.validImageSize = function(image) {
    return (image.width >= 480 && image.height >= 480);
  };

  /**
   * Validates image type.
   */
  ImageUpload.prototype.validImageType = function(files) {
    // Get the file extension.
    var extension = files[0].type;

    // Check that it is a valid file type.
    return this.fileTypes.indexOf(extension) > -1;
  };

  /**
   * Validates file size.
   */
  ImageUpload.prototype.validFileSize = function(files) {
    // Get the file extension.
    var size = files[0].size;

    // Check that it is a valid file type.
    return (size <= this.fileSizeLimit) ? true : false;
  };

  /**
   * Remove any previously added error message.
   */
  ImageUpload.prototype.removeError = function() {
    var $errorMsg = this.$uploadButton.parent().siblings(".error");

    if ($errorMsg.length) {
      $errorMsg.remove();
    }
  };

  /**
   * Show an error message.
   *
   * param {string}  Error message to be shown.
   */
   ImageUpload.prototype.showError = function(msg) {
    this.removeError();

    var $error = $("
" + msg + "
");

    // Check if the modal was open when they subitted the bad image.
    if (Modal.isOpen()) {
      Modal.close();
    }

    this.$reportbackSubmissions.prepend($error);
   };

  /**
   * Resizes an image so that the dimensions of the scaled image.
   * are never greater than it's container's maximum width (height of the container is variable).
   *
   * @param {jQuery} $image           The image to resize.
   * @param {jQuery} $container       The container to resize within.
   */
  ImageUpload.prototype.resizeImage = function($image, $container) {
    var imageWidth  = $image.width();
    var imageHeight = $image.height();
    var containerMaxWidth = $container.width();
    var orientation = (imageWidth > imageHeight) ? "landscape" : "portrait";

    if ((imageWidth > containerMaxWidth) || (imageHeight > containerMaxWidth)) {
      if (orientation === "portrait") {
        $image.height(containerMaxWidth);
      }
      else {
        $image.width(containerMaxWidth);
      }
    }
    else {
      return;
    }
  };

  /**
   * Creates a preview image of an uploaded file and adds it to a container.
   * If cropping is enabled, it initiates the cropping script.
   *
   * @param {jQuery} fileReaderResult   The result property of a file reader object.
   * @param {jQuery} $imageContainer    The DOM element to put the preview image in.
   */
  ImageUpload.prototype.previewImage = function(image, $imageContainer) {
    var _this = this;

    var $preview = $("");
    $imageContainer.html($preview);

    $preview.attr("src", image.src).load(function() {
      var $this = $(this);

      _this.resizeImage($this, $imageContainer);

      ImageCrop.dsCropperInit(image);
    });
  };

  ImageUpload.prototype.loadImage = function(imageUrl) {
    var _this = this;
    var image = new Image();
    image.src = imageUrl;

    image.onload = function() {
      var isValidSize = _this.validImageSize(this);

      _this.removeError();

      if(isValidSize) {
        // Open the modal.
        _this.openModal();

        // Add the preview image to the modal
        _this.previewImage(image, _this.$imagePreview);

        //Unbind before rebind so it doesnt fire twice.
        _this.$cropButton.off("click");

        // When the user submits the modal form, send crop values to the form.
        _this.$cropButton.on("click", function(event) {
          event.preventDefault();

          // Validate the caption field and make sure we are good to proceed.
          _this.validateCaption(_this.engageImageCrop, image);
        });
      }
      // Show user an error if they upload an image that is too small.
      else {
        _this.showError(_this.dimensionsError);
      }
    }
  };

  /**
   * This function strips out EXIF data from a file and recreates a
   * FileReader Blob that we use to create the image object that is used
   * in the modal. This way we only deal with the RAW image file on both
   * mobile and desktop with out having to wory about it rendering differently
   * and causing all of our image cropping/preview logic to be wrong.
   *
   * @TODO - try moving this into a web worker to enhance performance.
   */
  ImageUpload.prototype.getStrippedBlob = function(fileReaderResult) {
    var dataView = new DataView(fileReaderResult);
    var offset = 0;
    var recess = 0;
    var pieces = [];
    var i = 0;
    var generatedBlob;

    if (dataView.getUint16(offset) === 0xffd8) {
      offset   += 2;
      var app1  = dataView.getUint16(offset);
      offset   += 2;

      // This loop doing the acutal reading of the data
      // and creating an array with only the pieces we want.
      while (offset < dataView.byteLength) {
        if (app1 === 0xffe1) {
          pieces[i] = {
            recess : recess,
            offset : offset - 2
          };

          recess = offset + dataView.getUint16(offset);

          i++;
        }
        else if (app1 === 0xffda) {
          break;
        }

        offset   += dataView.getUint16(offset);
        app1  = dataView.getUint16(offset);
        offset   += 2;
      }

      // If the file had EXIF data and it was removed,
      // create a file blob with using the new array of file data.
      if (pieces.length > 0) {
        var newPieces = [];

        pieces.forEach(function(v) {
          newPieces.push(fileReaderResult.slice(v.recess, v.offset));
        }, this);

        newPieces.push(fileReaderResult.slice(recess));

        generatedBlob = new Blob(newPieces, {type: "image/jpeg"});
      }
      // If no EXIF data existed on the file, then nothing was done to it.
      // We can just create a blob with the original data.
      else {
        generatedBlob = new Blob([dataView], {type: "image/jpeg"});
      }
    }
    // @TODO - If it is not a jpeg, create a png. We can work out a more
    // robust fix for this that maybe only runs through the EXIF
    // stuff if it is a jpeg in the first place.
    else {
      generatedBlob = new Blob([dataView], {type: "image/png"});
    }
    return generatedBlob;
  };

  return ImageUpload;

});
<commit_msg>Fixing linting errors<commit_after>define(function(require) {
  "use strict";

  var $                = require("jquery");
  var Modal            = require("modal");
  var Validation       = require("validation");
  var ImageCrop        = require("images/ImageCrop");
  var ImageCropPreview = require("../images/ImageCropPreview");

  /**
   * Handles the modal interface for image upload buttons.
   * Requires a modal to be on the page with an id '#modal--crop'
   * The modal should have a form '#dosomething-reportback-image-form'
   * and a div to place the image preview '.image-wrapper'.
   *
   * @param {jQuery} $button  The file upload button
   */
  var ImageUpload = function($button) {
    this.$uploadButton          = $button;
    this.$cropModal             = $("#modal--crop");
    this.$reportbackForm        = $("#dosomething-reportback-form");
    this.$imageForm             = this.$cropModal.find("#dosomething-reportback-image-form");
    this.$imageCaption          = this.$imageForm.find("#modal-caption");
    this.$cropButton            = this.$imageForm.find(".button");
    this.$imagePreview          = this.$cropModal.find(".image-preview");
    this.$reportbackSubmissions = $(".reportback__submissions");
    this.imageValues            = {};
    this.readyToSave            = false;

    // Validation
    this.fileTypes              = ["image/png", "image/gif", "image/jpeg", "image/pjpeg"];
    this.fileSizeLimit          = 10000000; // 10mb
    this.typeError              = "Only JPEG, PNG, and GIF images are allowed";
    this.dimensionsError        = "Please upload a larger photo. Min. size is 480px by 480px.";
    this.sizeError              = "Please upload an image under 10MB";

    this.init();
  };

  /**
   * Initalizes event listeners
   *
   */
  ImageUpload.prototype.init = function () {
    var _this = this;

    this.$uploadButton.on("change", function(event) {
      event.preventDefault();

      var files = !!this.files ? this.files : [];

      // If no file selected/no FileReader support, we're all done
      if (!files.length || !window.FileReader) {
        return;
      }

      // Validate image type and file size before proceeding.
      if (!_this.validImageType(files)) {
        _this.showError(_this.typeError);

        return;
      }

      if (!_this.validFileSize(files)) {
        _this.showError(_this.sizeError);

        return;
      }

      var fr = new FileReader();

      if (window.navigator.userAgent.match(/iPad/i) || window.navigator.userAgent.match(/iPhone/i)) {
        fr.readAsArrayBuffer(this.files[0]);
        fr.onload = function () {
          var blob = _this.getStrippedBlob(this.result);
          var urlCreator = window.URL || window.webkitURL;
          var imageUrl = urlCreator.createObjectURL(blob);
          _this.loadImage(imageUrl);
        };
      }
      else {
        fr.readAsDataURL(files[0]);

        fr.onloadend = function() {
          var result = this.result;
          _this.loadImage(result);
        };
      }
    });

    Modal.Events.subscribe("Modal:Close", function() {
      _this.resetFileField();

      // Move the upload button back into the form.
      _this.moveUploadButton($("#edit-reportback-file"));

      if (_this.readyToSave) {
        // Add a button to edit the image.
        _this.createEditButton();
      }
    });

    // When the modal opens, move the upload button into the modal,
    // so users can change their photo.
    Modal.Events.subscribe("Modal:Open", function() {
      _this.moveUploadButton($(".-change .button"));
    });
  };

  /**
   * Detatches and moves the current upload button
   * @param {jQuery}  The element to move the button to.
   */
  ImageUpload.prototype.moveUploadButton = function($el) {
    var $button = this.$uploadButton.detach();

    $button.appendTo($el);
  };

  /**
   * Validates the caption field in the modal.
   * @param  {Function} callback  If validation passes, then lets rock on!
   * @return {void}
   */
  ImageUpload.prototype.validateCaption = function(callback, image) {
    var _this = this;

    Validation.validateField(this.$imageCaption, true, function($field, result) {
      Validation.showValidationMessage($field, result);

      if (result.success) {
        callback(_this, image);
      }
    });
  };

  /**
   * Everything is set, engage in cropping the selected image.
   * @param  {object} data  ImageUpload object.
   * @param  {object} image  Image object.
   * @return {void}
   */
  ImageUpload.prototype.engageImageCrop = function(data, image) {
    var _this = data;

    // Send crop information to the main reportback form
    // so backend can use to crop.
    ImageCrop.populateFields(_this.$reportbackForm);

    // Create a crop preview on the client side.
    ImageCropPreview.cropPreview(image, _this.getCropValues());

    // The user clicked "done", so we can save this version of the crop
    // and not reset the file field.
    _this.readyToSave = true;

    // Close the modal.
    Modal.close();
  };

  /**
   * Opens the modal making sure the done button is reset.
   */
  ImageUpload.prototype.openModal = function() {
    this.enableSubmit();

    Modal.open(this.$cropModal,
      {
        animated: false,
        closeButton: "closeButtonOnly",
      }
    );
  };

  /**
   * Clears the file field input and resets it globally,
   * if the user accidentally closed out of the modal.
   * Allows the user to re-upload an image and edit it.
   */
  ImageUpload.prototype.resetFileField = function() {
    var $input = this.$uploadButton;

    if (!this.readyToSave) {
      $input.replaceWith(this.$uploadButton = $input.val("").clone(true));
    }
  };

  /**
   * Creates a button the user can click to re-open the modal
   * and edit the crop they selected.
   */
  ImageUpload.prototype.createEditButton = function() {
    var _this = this;
    if (!this.$reportbackSubmissions.find(".button--edit").length) {
      var $editButton = $("edit photo");
      this.$uploadButton.parent().hide().before($editButton);

      $editButton.click(function() {
        _this.openModal();
      });
    }
  };

  /**
   * Gets crop values from form and returns an object.
   */
  ImageUpload.prototype.getCropValues = function() {
    return {
      x       : this.$reportbackForm.find("input[name='crop_x']").val(),
      y       : this.$reportbackForm.find("input[name='crop_y']").val(),
      width   : this.$reportbackForm.find("input[name='crop_width']").val(),
      height  : this.$reportbackForm.find("input[name='crop_height']").val(),
      degrees : parseInt(this.$reportbackForm.find("input[name='crop_rotate']").val()),
      caption : this.$reportbackForm.find("input[name='caption']").val(),
    };
  };

  /**
   * Enables submit button in modal when it opens.
   */
  ImageUpload.prototype.enableSubmit = function() {
    var $submitButton = this.$cropModal.find(".-done");

    if ($submitButton.prop("disabled")) {
      $submitButton.prop("disabled", false);
    }

    if ($submitButton.hasClass("is-loading")) {
      $submitButton.removeClass("is-loading");
    }
  };

  /**
   * Validates image size.
   */
  ImageUpload.prototype.validImageSize = function(image) {
    return (image.width >= 480 && image.height >= 480);
  };

  /**
   * Validates image type.
   */
  ImageUpload.prototype.validImageType = function(files) {
    // Get the file extension.
    var extension = files[0].type;

    // Check that it is a valid file type.
    return this.fileTypes.indexOf(extension) > -1;
  };

  /**
   * Validates file size.
   */
  ImageUpload.prototype.validFileSize = function(files) {
    // Get the file extension.
    var size = files[0].size;

    // Check that it is a valid file type.
    return (size <= this.fileSizeLimit) ? true : false;
  };

  /**
   * Remove any previously added error message.
   */
  ImageUpload.prototype.removeError = function() {
    var $errorMsg = this.$uploadButton.parent().siblings(".error");

    if ($errorMsg.length) {
      $errorMsg.remove();
    }
  };

  /**
   * Show an error message.
   *
   * param {string}  Error message to be shown.
   */
  ImageUpload.prototype.showError = function(msg) {
    this.removeError();

    var $error = $("
" + msg + "
");

    // Check if the modal was open when they subitted the bad image.
    if (Modal.isOpen()) {
      Modal.close();
    }

    this.$reportbackSubmissions.prepend($error);
  };

  /**
   * Resizes an image so that the dimensions of the scaled image.
   * are never greater than it's container's maximum width (height of the container is variable).
   *
   * @param {jQuery} $image           The image to resize.
   * @param {jQuery} $container       The container to resize within.
   */
  ImageUpload.prototype.resizeImage = function($image, $container) {
    var imageWidth  = $image.width();
    var imageHeight = $image.height();
    var containerMaxWidth = $container.width();
    var orientation = (imageWidth > imageHeight) ? "landscape" : "portrait";

    if ((imageWidth > containerMaxWidth) || (imageHeight > containerMaxWidth)) {
      if (orientation === "portrait") {
        $image.height(containerMaxWidth);
      }
      else {
        $image.width(containerMaxWidth);
      }
    }
    else {
      return;
    }
  };

  /**
   * Creates a preview image of an uploaded file and adds it to a container.
   * If cropping is enabled, it initiates the cropping script.
   *
   * @param {jQuery} fileReaderResult   The result property of a file reader object.
   * @param {jQuery} $imageContainer    The DOM element to put the preview image in.
   */
  ImageUpload.prototype.previewImage = function(image, $imageContainer) {
    var _this = this;

    var $preview = $("");
    $imageContainer.html($preview);

    $preview.attr("src", image.src).load(function() {
      var $this = $(this);

      _this.resizeImage($this, $imageContainer);

      ImageCrop.dsCropperInit(image);
    });
  };

  ImageUpload.prototype.loadImage = function(imageUrl) {
    var _this = this;
    var image = new Image();
    image.src = imageUrl;

    image.onload = function() {
      var isValidSize = _this.validImageSize(this);

      _this.removeError();

      if(isValidSize) {
        // Open the modal.
        _this.openModal();

        // Add the preview image to the modal
        _this.previewImage(image, _this.$imagePreview);

        //Unbind before rebind so it doesnt fire twice.
        _this.$cropButton.off("click");

        // When the user submits the modal form, send crop values to the form.
        _this.$cropButton.on("click", function(event) {
          event.preventDefault();

          // Validate the caption field and make sure we are good to proceed.
          _this.validateCaption(_this.engageImageCrop, image);
        });
      }
      // Show user an error if they upload an image that is too small.
      else {
        _this.showError(_this.dimensionsError);
      }
    };
  };

  /**
   * This function strips out EXIF data from a file and recreates a
   * FileReader Blob that we use to create the image object that is used
   * in the modal. This way we only deal with the RAW image file on both
   * mobile and desktop with out having to wory about it rendering differently
   * and causing all of our image cropping/preview logic to be wrong.
   *
   * @TODO - try moving this into a web worker to enhance performance.
   */
  ImageUpload.prototype.getStrippedBlob = function(fileReaderResult) {
    var dataView = new DataView(fileReaderResult);
    var offset = 0;
    var recess = 0;
    var pieces = [];
    var i = 0;
    var generatedBlob;

    if (dataView.getUint16(offset) === 0xffd8) {
      offset   += 2;
      var app1  = dataView.getUint16(offset);
      offset   += 2;

      // This loop doing the acutal reading of the data
      // and creating an array with only the pieces we want.
      while (offset < dataView.byteLength) {
        if (app1 === 0xffe1) {
          pieces[i] = {
            recess : recess,
            offset : offset - 2
          };

          recess = offset + dataView.getUint16(offset);

          i++;
        }
        else if (app1 === 0xffda) {
          break;
        }

        offset   += dataView.getUint16(offset);
        app1  = dataView.getUint16(offset);
        offset   += 2;
      }

      // If the file had EXIF data and it was removed,
      // create a file blob with using the new array of file data.
      if (pieces.length > 0) {
        var newPieces = [];

        pieces.forEach(function(v) {
          newPieces.push(fileReaderResult.slice(v.recess, v.offset));
        }, this);

        newPieces.push(fileReaderResult.slice(recess));

        generatedBlob = new Blob(newPieces, {type: "image/jpeg"});
      }
      // If no EXIF data existed on the file, then nothing was done to it.
      // We can just create a blob with the original data.
      else {
        generatedBlob = new Blob([dataView], {type: "image/jpeg"});
      }
    }
    // @TODO - If it is not a jpeg, create a png. We can work out a more
    // robust fix for this that maybe only runs through the EXIF
    // stuff if it is a jpeg in the first place.
    else {
      generatedBlob = new Blob([dataView], {type: "image/png"});
    }
    return generatedBlob;
  };

  return ImageUpload;

});
<|endoftext|>


<commit_before>var gulp = require('gulp'),
    wiredep = require('wiredep').stream,
    eventStream = require('event-stream'),
    gulpLoadPlugins = require('gulp-load-plugins'),
    map = require('vinyl-map'),
    fs = require('fs'),
    path = require('path'),
    url = require('url'),
    uri = require('URIjs'),
    s = require('underscore.string'),
    hawtio = require('hawtio-node-backend');

var plugins = gulpLoadPlugins({});
var pkg = require('./package.json');

var config = {
  main: '.',
  ts: ['plugins/**/*.ts'],
  templates: ['plugins/**/*.html'],
  templateModule: pkg.name + '-templates',
  dist: './dist/',
  js: pkg.name + '.js',
  tsProject: plugins.typescript.createProject({
    target: 'ES5',
    module: 'commonjs',
    declarationFiles: true,
    noExternalResolve: false
  })
};

gulp.task('bower', function() {
  gulp.src('index.html')
    .pipe(wiredep({}))
    .pipe(gulp.dest('.'));
});

/** Adjust the reference path of any typescript-built plugin this project depends on */
gulp.task('path-adjust', function() {
  gulp.src('libs/**/includes.d.ts')
    .pipe(map(function(buf, filename) {
      var textContent = buf.toString();
      var newTextContent = textContent.replace(/"\.\.\/libs/gm, '"../../../libs');
      // console.log("Filename: ", filename, " old: ", textContent, " new:", newTextContent);
      return newTextContent;
    }))
    .pipe(gulp.dest('libs'));
});

gulp.task('clean-defs', function() {
  return gulp.src('defs.d.ts', { read: false })
    .pipe(plugins.clean());
});

gulp.task('tsc', ['clean-defs'], function() {
  var cwd = process.cwd();
  var tsResult = gulp.src(config.ts)
    .pipe(plugins.typescript(config.tsProject))
    .on('error', plugins.notify.onError({
      message: '#{ error.message }',
      title: 'Typescript compilation error'
    }));

    return eventStream.merge(
      tsResult.js
        .pipe(plugins.concat('compiled.js'))
        .pipe(gulp.dest('.')),
      tsResult.dts
        .pipe(gulp.dest('d.ts')))
        .pipe(map(function(buf, filename) {
          if (!s.endsWith(filename, 'd.ts')) {
            return buf;
          }
          var relative = path.relative(cwd, filename);
          fs.appendFileSync('defs.d.ts', '/// <reference path="' + relative + '"/>\n');
          return buf;
        }));
});

gulp.task('template', ['tsc'], function() {
  return gulp.src(config.templates)
    .pipe(plugins.angularTemplatecache({
      filename: 'templates.js',
      root: 'plugins/',
      standalone: true,
      module: config.templateModule,
      templateFooter: '}]); hawtioPluginLoader.addModule("' + config.templateModule + '");'
    }))
    .pipe(gulp.dest('.'));
});

gulp.task('concat', ['template'], function() {
  return gulp.src(['compiled.js', 'templates.js'])
    .pipe(plugins.concat(config.js))
    .pipe(gulp.dest(config.dist));
});

gulp.task('clean', ['concat'], function() {
  return gulp.src(['templates.js', 'compiled.js', 'site'], { read: false })
    .pipe(plugins.clean());
});

gulp.task('watch', ['build'], function() {
  plugins.watch(['libs/**/*.js', 'libs/**/*.css', 'index.html', config.dist + '/' + config.js], function() {
    gulp.start('reload');
  });
  plugins.watch(['libs/**/*.d.ts', config.ts, config.templates], function() {
    gulp.start(['tsc', 'template', 'concat', 'clean']);
  });
});

gulp.task('connect', ['watch'], function() {
  // lets disable unauthorised TLS issues with kube REST API
  process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

  var kube = uri(process.env.KUBERNETES_MASTER || 'http://localhost:8080');
  console.log("Connecting to Kubernetes on: " + kube);

  var localProxies = [];
  if (process.env.LOCAL_APP_LIBRARY === "true") {
    localProxies.push({
        proto: "http",
        port: "8588",
        hostname: "localhost",
        path: '/services/app-library',
        targetPath: "/"
      });
  }
  var defaultProxies = [{
    proto: kube.protocol(),
    port: kube.port(),
    hostname: kube.hostname(),
    path: '/kubernetes',
    targetPath: kube.path()
  }, {
    proto: kube.protocol(),
    hostname: kube.hostname(),
    port: kube.port(),
    path: '/jolokia',
    targetPath: '/hawtio/jolokia'
  }, {
    proto: kube.protocol(),
    hostname: kube.hostname(),
    port: kube.port(),
    path: '/git',
    targetPath: '/hawtio/git'
  }];

  var staticProxies = localProxies.concat(defaultProxies);

  hawtio.setConfig({
    port: 2772,
    staticProxies: staticProxies,
    staticAssets: [{
      path: '/',
      dir: '.'
    }],
    fallback: 'index.html',
    liveReload: {
      enabled: true
    }
  });
  var debugLoggingOfProxy = process.env.DEBUG_PROXY === "true";
  hawtio.use('/', function(req, res, next) {
          var path = req.originalUrl;
          // avoid returning these files, they should get pulled from js
          if (s.startsWith(path, '/plugins/') && s.endsWith(path, 'html')) {
            console.log("returning 404 for: ", path);
            res.statusCode = 404;
            res.end();
          } else {
            if (debugLoggingOfProxy) {
              console.log("allowing: ", path);
            }
            next();
          }
        });
  hawtio.listen(function(server) {
    var host = server.address().address;
    var port = server.address().port;
    console.log("started from gulp file at ", host, ":", port);
  });
});

gulp.task('reload', function() {
  gulp.src('.')
    .pipe(hawtio.reload());
});

gulp.task('build', ['bower', 'path-adjust', 'tsc', 'template', 'concat', 'clean']);

gulp.task('site', ['clean', 'build'], function() {
  gulp.src(['index.html', 'css/**', 'images/**', 'libs/**', 'dist/**'], {base: '.'}).pipe(gulp.dest('site'));
});

gulp.task('default', ['connect']);

<commit_msg>Add /api suffix to kube gulp proxy<commit_after>var gulp = require('gulp'),
    wiredep = require('wiredep').stream,
    eventStream = require('event-stream'),
    gulpLoadPlugins = require('gulp-load-plugins'),
    map = require('vinyl-map'),
    fs = require('fs'),
    path = require('path'),
    url = require('url'),
    uri = require('URIjs'),
    s = require('underscore.string'),
    hawtio = require('hawtio-node-backend');

var plugins = gulpLoadPlugins({});
var pkg = require('./package.json');

var config = {
  main: '.',
  ts: ['plugins/**/*.ts'],
  templates: ['plugins/**/*.html'],
  templateModule: pkg.name + '-templates',
  dist: './dist/',
  js: pkg.name + '.js',
  tsProject: plugins.typescript.createProject({
    target: 'ES5',
    module: 'commonjs',
    declarationFiles: true,
    noExternalResolve: false
  })
};

gulp.task('bower', function() {
  gulp.src('index.html')
    .pipe(wiredep({}))
    .pipe(gulp.dest('.'));
});

/** Adjust the reference path of any typescript-built plugin this project depends on */
gulp.task('path-adjust', function() {
  gulp.src('libs/**/includes.d.ts')
    .pipe(map(function(buf, filename) {
      var textContent = buf.toString();
      var newTextContent = textContent.replace(/"\.\.\/libs/gm, '"../../../libs');
      // console.log("Filename: ", filename, " old: ", textContent, " new:", newTextContent);
      return newTextContent;
    }))
    .pipe(gulp.dest('libs'));
});

gulp.task('clean-defs', function() {
  return gulp.src('defs.d.ts', { read: false })
    .pipe(plugins.clean());
});

gulp.task('tsc', ['clean-defs'], function() {
  var cwd = process.cwd();
  var tsResult = gulp.src(config.ts)
    .pipe(plugins.typescript(config.tsProject))
    .on('error', plugins.notify.onError({
      message: '#{ error.message }',
      title: 'Typescript compilation error'
    }));

    return eventStream.merge(
      tsResult.js
        .pipe(plugins.concat('compiled.js'))
        .pipe(gulp.dest('.')),
      tsResult.dts
        .pipe(gulp.dest('d.ts')))
        .pipe(map(function(buf, filename) {
          if (!s.endsWith(filename, 'd.ts')) {
            return buf;
          }
          var relative = path.relative(cwd, filename);
          fs.appendFileSync('defs.d.ts', '/// <reference path="' + relative + '"/>\n');
          return buf;
        }));
});

gulp.task('template', ['tsc'], function() {
  return gulp.src(config.templates)
    .pipe(plugins.angularTemplatecache({
      filename: 'templates.js',
      root: 'plugins/',
      standalone: true,
      module: config.templateModule,
      templateFooter: '}]); hawtioPluginLoader.addModule("' + config.templateModule + '");'
    }))
    .pipe(gulp.dest('.'));
});

gulp.task('concat', ['template'], function() {
  return gulp.src(['compiled.js', 'templates.js'])
    .pipe(plugins.concat(config.js))
    .pipe(gulp.dest(config.dist));
});

gulp.task('clean', ['concat'], function() {
  return gulp.src(['templates.js', 'compiled.js', 'site'], { read: false })
    .pipe(plugins.clean());
});

gulp.task('watch', ['build'], function() {
  plugins.watch(['libs/**/*.js', 'libs/**/*.css', 'index.html', config.dist + '/' + config.js], function() {
    gulp.start('reload');
  });
  plugins.watch(['libs/**/*.d.ts', config.ts, config.templates], function() {
    gulp.start(['tsc', 'template', 'concat', 'clean']);
  });
});

gulp.task('connect', ['watch'], function() {
  // lets disable unauthorised TLS issues with kube REST API
  process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

  var kube = uri((process.env.KUBERNETES_MASTER || 'http://localhost:8080') + '/api');
  console.log("Connecting to Kubernetes on: " + kube);

  var localProxies = [];
  if (process.env.LOCAL_APP_LIBRARY === "true") {
    localProxies.push({
        proto: "http",
        port: "8588",
        hostname: "localhost",
        path: '/services/app-library',
        targetPath: "/"
      });
  }
  var defaultProxies = [{
    proto: kube.protocol(),
    port: kube.port(),
    hostname: kube.hostname(),
    path: '/kubernetes/api',
    targetPath: kube.path()
  }, {
    proto: kube.protocol(),
    hostname: kube.hostname(),
    port: kube.port(),
    path: '/jolokia',
    targetPath: '/hawtio/jolokia'
  }, {
    proto: kube.protocol(),
    hostname: kube.hostname(),
    port: kube.port(),
    path: '/git',
    targetPath: '/hawtio/git'
  }];

  var staticProxies = localProxies.concat(defaultProxies);

  hawtio.setConfig({
    port: 2772,
    staticProxies: staticProxies,
    staticAssets: [{
      path: '/',
      dir: '.'
    }],
    fallback: 'index.html',
    liveReload: {
      enabled: true
    }
  });
  var debugLoggingOfProxy = process.env.DEBUG_PROXY === "true";
  hawtio.use('/', function(req, res, next) {
          var path = req.originalUrl;
          // avoid returning these files, they should get pulled from js
          if (s.startsWith(path, '/plugins/') && s.endsWith(path, 'html')) {
            console.log("returning 404 for: ", path);
            res.statusCode = 404;
            res.end();
          } else {
            if (debugLoggingOfProxy) {
              console.log("allowing: ", path);
            }
            next();
          }
        });
  hawtio.listen(function(server) {
    var host = server.address().address;
    var port = server.address().port;
    console.log("started from gulp file at ", host, ":", port);
  });
});

gulp.task('reload', function() {
  gulp.src('.')
    .pipe(hawtio.reload());
});

gulp.task('build', ['bower', 'path-adjust', 'tsc', 'template', 'concat', 'clean']);

gulp.task('site', ['clean', 'build'], function() {
  gulp.src(['index.html', 'css/**', 'images/**', 'libs/**', 'dist/**'], {base: '.'}).pipe(gulp.dest('site'));
});

gulp.task('default', ['connect']);

<|endoftext|>


<commit_before>var
  pkg = require('./package.json'),

	gulp = require('gulp'),
	gutil = require('gulp-util'),

	jshint = require('gulp-jshint'),
  jscs = require('gulp-jscs'),
  //concatSourcemap = require('gulp-concat-sourcemap'),
  uglify = require('gulp-uglify'),
  header = require('gulp-header'),
  concat = require('gulp-concat'),
  csso = require('gulp-csso'),
	shell = require('gulp-shell'),

	outDirJS = 'dest',
	outFileJS = 'dom5.min.js',

	banner = [
	  '/**',
	  ' * <%= pkg.name %> - <%= pkg.description %>',
	  ' * @version v<%= pkg.version %>',
	  ' * @repository <%= pkg.homepage %>',
	  ' * @author <%= pkg.author %>',
	  ' * @license <%= pkg.license %>',
	  ' * @build <%= new Date().toLocaleString() %>',
	  ' */',
	  '',
	  ''
	].join('\n')
;

gulp.task('Lint scripts',
  function () {
    return gulp.src([
			  'src/**/*.js',
			  'test/spec/*.js',
			  'gulpfile.js'
		  ])
      .pipe(jshint('.jshintrc'));
  }
);

gulp.task('Check code style',
  function () {
    return gulp.src([
			  'src/**/*.js',
			  'test/spec/*.js'
		])
		.pipe(jscs());
  }
);

gulp.task('Compress src',
  function() {
    return gulp.src('src/dom5.js')
      .pipe(uglify())
		  .pipe(header(banner, { pkg : pkg }))
      .pipe(concat(outFileJS))
		  .pipe(gulp.dest(outDirJS));
  }
);

gulp.task('Gzip estimation',
  shell.task([
    'echo "[INFO] GZIPSIZE \'' + gutil.colors.cyan(outFileJS) + '\' estimated' +
		  gutil.colors.magenta('" `gzip -c ' + outDirJS + '/' + outFileJS + ' | wc -c ` "bytes"') + ' [INFO]'
  ])
);

gulp.task('default', [
  'Lint scripts',
  'Check code style',
	'Compress src',
	'Gzip estimation'
]);<commit_msg>some cleanup<commit_after>var
  pkg = require('./package.json'),

  gulp = require('gulp'),
  gutil = require('gulp-util'),

  jshint = require('gulp-jshint'),
  jscs = require('gulp-jscs'),
  //concatSourcemap = require('gulp-concat-sourcemap'),
  uglify = require('gulp-uglify'),
  header = require('gulp-header'),
  concat = require('gulp-concat'),
  csso = require('gulp-csso'),
  shell = require('gulp-shell'),

  outDirJS = 'dest',
  outFileJS = 'dom5.min.js',

  banner = [
    '/**',
    ' * <%= pkg.name %> - <%= pkg.description %>',
    ' * @version v<%= pkg.version %>',
    ' * @repository <%= pkg.homepage %>',
    ' * @author <%= pkg.author %>',
    ' * @license <%= pkg.license %>',
    ' * @build <%= new Date().toLocaleString() %>',
    ' */',
    '',
    ''
  ].join('\n')
;

gulp.task('Lint scripts',
  function () {
    return gulp.src([
        'src/**/*.js',
        'test/spec/*.js',
        'gulpfile.js'
      ])
      .pipe(jshint('.jshintrc'));
  }
);

gulp.task('Check code style',
  function () {
    return gulp.src([
      'src/**/*.js',
      'test/spec/*.js'
    ])
    .pipe(jscs());
  }
);

gulp.task('Compress src',
  function() {
    return gulp.src('src/dom5.js')
      .pipe(uglify())
      .pipe(header(banner, { pkg : pkg }))
      .pipe(concat(outFileJS))
      .pipe(gulp.dest(outDirJS));
  }
);

gulp.task('Gzip estimation',
  shell.task([
    'echo "[INFO] GZIPSIZE \'' + gutil.colors.cyan(outFileJS) + '\' estimated' +
      gutil.colors.magenta('" `gzip -c ' + outDirJS + '/' + outFileJS + ' | wc -c ` "bytes"') + ' [INFO]'
  ])
);

gulp.task('default', [
  'Lint scripts',
  'Check code style',
  'Compress src',
  'Gzip estimation'
]);<|endoftext|>


<commit_before>// Sass configuration
var gulp = require('gulp');
var sass = require('gulp-sass');

'use strict';

var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', function () {
  gulp.src('public/css/**/*.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(gulp.dest(f => f.base));
});

gulp.task('sass:watch', function () {
  gulp.watch('*.scss', ['sass']);
});<commit_msg>remove redundancies in gulp file<commit_after>'use strict';
var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', function () {
  gulp.src('public/css/**/*.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(gulp.dest(f => f.base));
});

gulp.task('sass:watch', function () {
  gulp.watch('*.scss', ['sass']);
});<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');
var gulpLoadPlugins = require('gulp-load-plugins');
var browserSync = require('browser-sync');
var plugins = gulpLoadPlugins(),
  reload = browserSync.reload,
  BROWSER_SYNC_RELOAD_DELAY = 500,
  paths = {
    js: ['*.js', 'app.js', 'test/**/*.js', '!test/coverage/**', 'routes/**/*.js',
         'public/javascripts/**/*.js', 'modules/**/*.js'],
    html: ['views/**/*.*'],
    css: ['public/stylesheets/style.scss'],
    cssDest: ['public/stylesheets'],
    sass: ['public/stylesheets/*.scss'],
    publicPath: ['public/**/*.*']};

// TODO: Define env variables and ports globally

gulp.task('lint', function () {
    return gulp.src(paths.js)
      // .pipe(reload({stream: true, once: true}))
      // eslint() attaches the lint output to the eslint property
      // of the file object so it can be used by other modules.
      .pipe(plugins.eslint())
      // eslint.format() outputs the lint results to the console.
      // Alternatively use eslint.formatEach() (see Docs).
      .pipe(plugins.eslint.format())
      // To have the process exit with an error code (1) on
      // lint error, return the stream and pipe to failOnError last.
      .pipe(plugins.eslint.failOnError());
});

// Lint JavaScript
gulp.task('jshint', function () {
    return gulp.src(paths.js)
      // .pipe(reload({stream: true, once: true}))
      .pipe(plugins.jshint())
      .pipe(plugins.jshint.reporter('jshint-stylish'))
      // .pipe(plugins.jshint.reporter('default'))
      .pipe(plugins.jshint.reporter('fail'));
});

gulp.task('sass', function () {
    return gulp.src(paths.css)
      .pipe(plugins.sass())
      .pipe(gulp.dest(paths.cssDest[0]))
      .pipe(reload({stream: true}));
});

gulp.task('mochaTest', ['jshint', 'lint'], function () {
    return gulp.src(paths.js[2], {read: false})
      .pipe(plugins.mocha({
        reporter: 'spec'
      }));
});

gulp.task('coverage', ['mochaTest'], function (cb) {
    gulp.src([paths.js[1], paths.js[4], paths.js[5], paths.js[6]])
      .pipe(plugins.istanbul()) // Covering files
      .pipe(plugins.istanbul.hookRequire()) // Force `require` to return covered files
      .on('finish', function () {
          gulp.src(paths.js[2], {read: false})
            .pipe(plugins.mocha({
              reporter: 'spec'
            }))
            .pipe(plugins.istanbul.writeReports()) // Creating the reports after tests runned
            .pipe(plugins.istanbul.enforceThresholds({ thresholds: { global: 80 } })) // Enforce a coverage of at least 90%
            .on('end', cb);
      });
});

gulp.task('browser-sync', ['mochaTest', 'sass', 'nodemon'], function() {
    browserSync.init({
      proxy: 'http://localhost:5000',
          files: [paths.publicPath],
          browser: 'google chrome',
          port: 7000
    });
    gulp.watch(paths.sass, ['sass', reload]);
    gulp.watch(paths.js, ['mochaTest']);
});

gulp.task('nodemon', ['mochaTest'], function (cb) {
    var called = false;
    return plugins.nodemon({
      script: paths.js[1],
      watch: [paths.js, paths.html]
    })
    .on('start', function () {
        if (!called) {
            cb();
        }
        called = true;
    })
    .on('restart', function onRestart() {
        // reload connected browsers after a slight delay
        setTimeout(function reload() {
            browserSync.reload({
              stream: false
            });
        }, BROWSER_SYNC_RELOAD_DELAY);
    });
});

gulp.task('default', ['browser-sync'], function() {
  // place code for your default task here
});
<commit_msg>gulp file modifications<commit_after>'use strict';

var gulp = require('gulp');
var gulpLoadPlugins = require('gulp-load-plugins');
var browserSync = require('browser-sync');

var plugins = gulpLoadPlugins(),
  reload = browserSync.reload,
  BROWSER_SYNC_RELOAD_DELAY = 500,
  paths = {
    js: ['*.js', 'app.js', 'test/**/*.js', '!test/coverage/**', 'routes/**/*.js',
         'public/javascripts/**/*.js', 'modules/**/*.js'],
    html: ['views/**/*.*'],
    css: ['public/stylesheets/style.scss'],
    cssDest: ['public/stylesheets'],
    sass: ['public/stylesheets/*.scss'],
    publicPath: ['public/**/*.*']};

// TODO: Define env variables and ports globally

gulp.task('lint', function () {
    return gulp.src(paths.js)
      // .pipe(reload({stream: true, once: true}))
      // eslint() attaches the lint output to the eslint property
      // of the file object so it can be used by other modules.
      .pipe(plugins.eslint())
      // eslint.format() outputs the lint results to the console.
      // Alternatively use eslint.formatEach() (see Docs).
      .pipe(plugins.eslint.format())
      // To have the process exit with an error code (1) on
      // lint error, return the stream and pipe to failOnError last.
      .pipe(plugins.eslint.failOnError());
});

// Lint JavaScript
gulp.task('jshint', function () {
    return gulp.src(paths.js)
      // .pipe(reload({stream: true, once: true}))
      .pipe(plugins.jshint())
      .pipe(plugins.jshint.reporter('jshint-stylish'))
      // .pipe(plugins.jshint.reporter('default'))
      .pipe(plugins.jshint.reporter('fail'));
});

gulp.task('sass', function () {
    return gulp.src(paths.css)
      .pipe(plugins.sass())
      .pipe(gulp.dest(paths.cssDest[0]))
      .pipe(reload({stream: true}));
});

gulp.task('mochaTest', ['jshint', 'lint'], function () {
    return gulp.src(paths.js[2], {read: false})
      .pipe(plugins.mocha({
        reporter: 'spec'
      }));
});

gulp.task('coverage', ['mochaTest'], function (cb) {
    gulp.src([paths.js[1], paths.js[4], paths.js[5], paths.js[6]])
      .pipe(plugins.istanbul()) // Covering files
      .pipe(plugins.istanbul.hookRequire()) // Force `require` to return covered files
      .on('finish', function () {
          gulp.src(paths.js[2], {read: false})
            .pipe(plugins.mocha({
              reporter: 'spec'
            }))
            .pipe(plugins.istanbul.writeReports()) // Creating the reports after tests runned
            .pipe(plugins.istanbul.enforceThresholds({ thresholds: { global: 80 } })) // Enforce a coverage of at least 90%
            .on('end', cb);
      });
});

gulp.task('browser-sync', ['mochaTest', 'sass', 'nodemon'], function() {
    browserSync.init({
      proxy: 'http://localhost:5000',
          files: [paths.publicPath],
          browser: 'google chrome',
          port: 7000
    });
    gulp.watch(paths.sass, ['sass', reload]);
    gulp.watch(paths.js, ['mochaTest']);
});

gulp.task('nodemon', ['mochaTest'], function (cb) {
    var called = false;
    return plugins.nodemon({
      script: paths.js[1],
      watch: [paths.js, paths.html]
    })
    .on('start', function () {
        if (!called) {
            cb();
        }
        called = true;
    })
    .on('restart', function onRestart() {
        // reload connected browsers after a slight delay
        setTimeout(function reload() {
            browserSync.reload({
              stream: false
            });
        }, BROWSER_SYNC_RELOAD_DELAY);
    });
});

gulp.task('default', ['browser-sync'], function() {
  // place code for your default task here
});
<|endoftext|>


<commit_before>var gulp = require('gulp'),
    jshint = require('gulp-jshint'),
    bump = require('gulp-bump'),
    git = require('gulp-git'),
    concat = require('gulp-concat'),
    rename = require('gulp-rename'),
    uglify = require('gulp-uglify'),
    size = require('gulp-size'),
    pkg = require('./package.json');

var paths = {
    pkg: './package.json',
    src: './tote.js',
    all: [ 'gulpfile.js', './tote.js' ],
    dist: './www/dist'
};

gulp.task('lint', function() {
    return gulp.src(paths.src)
        .pipe(jshint('.jshintrc'))
        .pipe(jshint.reporter('jshint-stylish'));
});

gulp.task('bump', function() {
    return gulp.src(paths.pkg)
        .pipe(bump())
        .pipe(gulp.dest('./'));
});

gulp.task('tag', function () {
    var pkg = require(paths.pkg),
        ver = 'v' + pkg.version,
        msg = 'Release ' + v;

    return gulp.src('./')
        .pipe(git.commit(msg))
        .pipe(git.tag(v, msg))
        .pipe(git.push('origin', 'master', '--tags'))
        .pipe(gulp.dest('./'));
});

gulp.task('package', function() {
    return gulp.src(paths.src)
        .pipe(concat(pkg.name + '.js'))
        .pipe(gulp.dest(paths.dist))
        .pipe(rename(pkg.name + '.min.js'))
        .pipe(uglify())
        .pipe(size())
        .pipe(gulp.dest(paths.dist));
});

gulp.task('dev', ['lint', 'package'], function() {
    gulp.watch(paths.all, ['lint', 'package']);
});

gulp.task('default', ['package']);<commit_msg>Add release tab -- bare-bones for later<commit_after>var gulp = require('gulp'),
    jshint = require('gulp-jshint'),
    bump = require('gulp-bump'),
    git = require('gulp-git'),
    concat = require('gulp-concat'),
    rename = require('gulp-rename'),
    uglify = require('gulp-uglify'),
    size = require('gulp-size'),
    pkg = require('./package.json');

var paths = {
    pkg: './package.json',
    src: './tote.js',
    all: [ 'gulpfile.js', './tote.js' ],
    dist: './www/dist'
};

gulp.task('lint', function() {
    return gulp.src(paths.src)
        .pipe(jshint('.jshintrc'))
        .pipe(jshint.reporter('jshint-stylish'));
});

gulp.task('bump', function() {
    return gulp.src(paths.pkg)
        .pipe(bump())
        .pipe(gulp.dest('./'));
});

gulp.task('tag', function () {
    var pkg = require(paths.pkg),
        ver = 'v' + pkg.version,
        msg = 'Release ' + v;

    return gulp.src('./')
        .pipe(git.commit(msg))
        .pipe(git.tag(v, msg))
        .pipe(git.push('origin', 'master', '--tags'))
        .pipe(gulp.dest('./'));
});

gulp.task('package', function() {
    return gulp.src(paths.src)
        .pipe(concat(pkg.name + '.js'))
        .pipe(gulp.dest(paths.dist))
        .pipe(rename(pkg.name + '.min.js'))
        .pipe(uglify())
        .pipe(size())
        .pipe(gulp.dest(paths.dist));
});

gulp.task('dev', ['lint', 'package'], function() {
    gulp.watch(paths.all, ['lint', 'package']);
});

gulp.task('default', ['package']);
gulp.task('release', ['tag']);<|endoftext|>


<commit_before>
(function () {
  'use strict';

  var countPrisoners = function (board, player1IsMe) {
    var i, j,
        freeMenCount = 0;
    board.forEach(function (row) {
      row.forEach(function (cell) {
        if (player1IsMe) {
          if (cell === 'M' || cell === 'K') {
            freeMenCount++;
          }
        } else {
          if (cell === 'm' || cell === 'k') {
            freeMenCount++;
          }
        }
      });
    });
    return (12 - freeMenCount);
  };

  var filterGamesList = function (self, obj) {

    return self.collection.filter(function (game) {

      obj.isOddTurn = game.attributes.game.turn_counter % 2 == 1;
      obj.isEvenTurn = !obj.isOddTurn;

      // TODO: Swap out app.username for ?app.user.username? once that is exposed.

      obj.player1IsMe = game.attributes.player1.username === app.username;
      obj.player2IsMe = !obj.player1IsMe;
      game.set('me', (obj.player1IsMe) ? 'player1' : 'player2');

      // TODO: I may need to flip player1IsMe with player2IsMe
      // depending on how server handles the game startup.
      obj.isMyTurn = obj.isOddTurn && obj.player1IsMe ||
                     obj.isEvenTurn && obj.player2IsMe;

      return (self.myMoves) ? obj.isMyTurn : !obj.isMyTurn;
    });
  };

  var addProps = function (filteredGamesList, obj, view) {

    var opponentUsername, hash, opponent, prisonCount, prisoner, timestamp;

    filteredGamesList.forEach(function (game) {

      opponentUsername = obj.player1IsMe ? game.attributes.player2.username : game.attributes.player1.username;
      hash = CryptoJS.MD5(opponentUsername).toString();
      game.set('hash', hash);

      opponent = obj.player1IsMe ? game.attributes.player2.username : game.attributes.player1.username;
      game.set('opponent', opponent);

      prisonCount = countPrisoners(game.attributes.game.board, obj.player1IsMe);
      game.set('prisonCount', prisonCount || 'NO');

      prisoner = utils.pluralize('prisoner', prisonCount);
      game.set('prisoner', prisoner);

      game.set('isMyTurn', obj.isMyTurn);

      timestamp = moment(game.attributes.game.updated_at).fromNow();
      game.set('timestamp', timestamp);

      view.$el.append(view.template(game.attributes));
    });

  };

  var render = function () {
    var self = this,
        obj = {};
    this.$el.empty();
    this.collection.fetch().done(function () {
      var filteredGamesList = filterGamesList(self, obj);

      if (filteredGamesList.length > 0) {
        addProps(filteredGamesList, obj, self);
      } else {
        self.$el.append(self.templateNoMoves(game.attributes));
      }
    });
  };

  var launchGame = function (e) {
    console.log('Clicked to launch game');
    var game = app.games.find(function (game) {
      return game.attributes.game.id == e.currentTarget.id;
    });
    app.menView = new app.MenView(game);
    app.boardView = new app.BoardView(game);
  };

  app.GamesListView = Backbone.View.extend({

    initialize: function () {
      $('.games-wrapper').append('

');
      app.myMovesView = new app.MyMovesView(app.games);
      app.theirMovesView = new app.TheirMovesView(app.games);
    }

  });

  app.MyMovesView = Backbone.View.extend({

    tagName: 'ul',
    className: 'games',

    template: Handlebars.templates.game,
    templateNoMoves: Handlebars.templates.game_no_my_moves,

    events: {
      'click li': 'clicked'
    },

    initialize: function (collection) {
      this.collection = collection;
      this.render();
      this.myMoves = true;

      $('.games-page').append('
Your Move
').append(this.el);
    },

    render: render,

    clicked: launchGame

  });

  app.TheirMovesView = Backbone.View.extend({

    tagName: 'ul',
    className: 'games',

    template: Handlebars.templates.game,
    templateNoMoves: Handlebars.templates.game_no_their_moves,

    events: {
      'click li': 'clicked'
    },

    initialize: function (collection) {
      this.collection = collection;
      this.render();
      this.myMoves = false;

      $('.games-page').append('
Their Move
').append(this.el);
    },

    render: render,

    clicked: launchGame

  });

}());

<commit_msg>Fix bug in games_list.view.js<commit_after>
(function () {
  'use strict';

  var countPrisoners = function (board, player1IsMe) {
    var i, j,
        freeMenCount = 0;
    board.forEach(function (row) {
      row.forEach(function (cell) {
        if (player1IsMe) {
          if (cell === 'M' || cell === 'K') {
            freeMenCount++;
          }
        } else {
          if (cell === 'm' || cell === 'k') {
            freeMenCount++;
          }
        }
      });
    });
    return (12 - freeMenCount);
  };

  var filterGamesList = function (self, obj) {

    return self.collection.filter(function (game) {

      obj.isOddTurn = game.attributes.game.turn_counter % 2 == 1;
      obj.isEvenTurn = !obj.isOddTurn;

      // TODO: Swap out app.username for ?app.user.username? once that is exposed.

      obj.player1IsMe = game.attributes.player1.username === app.username;
      obj.player2IsMe = !obj.player1IsMe;
      game.set('me', (obj.player1IsMe) ? 'player1' : 'player2');

      // TODO: I may need to flip player1IsMe with player2IsMe
      // depending on how server handles the game startup.
      obj.isMyTurn = obj.isOddTurn && obj.player1IsMe ||
                     obj.isEvenTurn && obj.player2IsMe;

      return (self.myMoves) ? obj.isMyTurn : !obj.isMyTurn;
    });
  };

  var addProps = function (filteredGamesList, obj, view) {

    var opponentUsername, hash, opponent, prisonCount, prisoner, timestamp;

    filteredGamesList.forEach(function (game) {

      opponentUsername = obj.player1IsMe ? game.attributes.player2.username : game.attributes.player1.username;
      hash = CryptoJS.MD5(opponentUsername).toString();
      game.set('hash', hash);

      opponent = obj.player1IsMe ? game.attributes.player2.username : game.attributes.player1.username;
      game.set('opponent', opponent);

      prisonCount = countPrisoners(game.attributes.game.board, obj.player1IsMe);
      game.set('prisonCount', prisonCount || 'NO');

      prisoner = utils.pluralize('prisoner', prisonCount);
      game.set('prisoner', prisoner);

      game.set('isMyTurn', obj.isMyTurn);

      timestamp = moment(game.attributes.game.updated_at).fromNow();
      game.set('timestamp', timestamp);

      view.$el.append(view.template(game.attributes));
    });

  };

  var render = function () {
    var self = this,
        obj = {};
    this.$el.empty();
    this.collection.fetch().done(function () {
      var filteredGamesList = filterGamesList(self, obj);

      if (filteredGamesList.length > 0) {
        addProps(filteredGamesList, obj, self);
      } else {
        self.$el.append(self.templateNoMoves());
      }
    });
  };

  var launchGame = function (e) {
    console.log('Clicked to launch game');
    var game = app.games.find(function (game) {
      return game.attributes.game.id == e.currentTarget.id;
    });
    app.menView = new app.MenView(game);
    app.boardView = new app.BoardView(game);
  };

  app.GamesListView = Backbone.View.extend({

    initialize: function () {
      $('.games-wrapper').append('

');
      app.myMovesView = new app.MyMovesView(app.games);
      app.theirMovesView = new app.TheirMovesView(app.games);
    }

  });

  app.MyMovesView = Backbone.View.extend({

    tagName: 'ul',
    className: 'games',

    template: Handlebars.templates.game,
    templateNoMoves: Handlebars.templates.game_no_my_moves,

    events: {
      'click li': 'clicked'
    },

    initialize: function (collection) {
      this.collection = collection;
      this.render();
      this.myMoves = true;

      $('.games-page').append('
Your Move
').append(this.el);
    },

    render: render,

    clicked: launchGame

  });

  app.TheirMovesView = Backbone.View.extend({

    tagName: 'ul',
    className: 'games',

    template: Handlebars.templates.game,
    templateNoMoves: Handlebars.templates.game_no_their_moves,

    events: {
      'click li': 'clicked'
    },

    initialize: function (collection) {
      this.collection = collection;
      this.render();
      this.myMoves = false;

      $('.games-page').append('
Their Move
').append(this.el);
    },

    render: render,

    clicked: launchGame

  });

}());

<|endoftext|>


<commit_before>var $Gulp = require('gulp'),
    $PEG = require("pegjs"),
    $EJS = require("ejs"),
    $Mkdirp = require('mkdirp'),
    $Path = require('path'),
    $FileSystem = require('fs');

$Gulp.task('build parser', function() {
    // TODO: get all parser and generate each of them
    var parser = new PEGParser("Author", "grammars");
    parser.build().writeTo("build/parser/test");
});

/**
 * Utility class used to generate parser from PEG grammar
 * @param {String} name - The name of the parser
 * @param {String} path - The path to the grammar file
 * @constructor
 * @example
 *      // generates a new parser using a PEG grammar
 *      var parser = new PEGParser("Author", "grammars");
 *      parser.build().writeTo("src/parser");
 */
function PEGParser(name, path) {
    this._name = name;
    this._path = path;
}

/**
 * Builds the parser
 * @returns {{writeTo: writeTo}} Returns an object containing a function to write the parser to the file system
 * @example
 *      PEGParser("Author", "grammars").build().writeTo("src/parser");
 */
PEGParser.prototype.build = function() {
    var grammarFileName = this._name.toLowerCase() + ".pegjs";
    var parserFileName = this._name.toLowerCase() + "_parser.js";
    var grammar = new File(grammarFileName).readFrom(this._path);

    // generate parser using grammar
    var source = $PEG.buildParser(grammar, {
        output: "source"
    });

    // convert parser to a module
    source = $EJS.render("export var <%- name %> = <%- src %>;", {
        name: this._name + "Parser",
        src: source
    });

    return {
        writeTo: function(path) {
            new File(parserFileName, source).writeTo(path);
        }
    };
};

/**
 * Helper class used to read or write files
 * @param {String} name - The name of the file to write or read
 * @param {String} [data] - The data to write. This is an optional parameter and just required if data must be written to disk
 * @constructor
 * @example
 *      // write data
 *      var file = new File("file.js", "data to write");
 *      file.writeTo("path/to/directory");
 *
 *      // read data
 *      var file = new File("file.js");
 *      var data = file.readFrom("path/to/directory");
 */
function File(name, data) {
    this._name = name;
    this._data = data;
}

/**
 * Writes the file to the given directory path
 * @param {String} path - The directory path to write the file to
 */
File.prototype.writeTo = function(path) {
    var directory = $Path.join("./", path);
    var filePath = $Path.join(directory, this._name);

    // create folder if not exists
    if (!$FileSystem.existsSync(directory)) {
        $Mkdirp.sync(directory);
    }

    $FileSystem.writeFileSync(filePath, this._data);
};

/**
 * Reads the file from the given directory path
 * @param {String} path - The directory path to read the file from
 * @returns {String} An UTF-8 encoded string which represents the content of the file
 */
File.prototype.readFrom = function(path) {
    var filePath = $Path.join("./", path, this._name);
    return $FileSystem.readFileSync(filePath, {encoding: 'utf-8'});
};
<commit_msg>[added] task to transpile ES6 to ES5<commit_after>var $Gulp = require('gulp'),
    $Babel = require('babel-core'),
    $Browserify = require("browserify"),
    $Uglify = require("uglify-js"),
    $PEG = require("pegjs"),
    $EJS = require("ejs"),
    $FileWalker = require('walk'),
    $Mkdirp = require('mkdirp'),
    $Path = require('path'),
    $FileSystem = require('fs');

$Gulp.task('build parser', function() {
    // TODO: get all parser and generate each of them
    var parser = new PEGParser("Author", "grammars");
    parser.build().writeTo("src/parser");

    parser = new PEGParser("Version", "grammars");
    parser.build().writeTo("src/parser");
});

$Gulp.task('compile SCSS', function() {

});

$Gulp.task('compile ES6', function() {
    var transformer = new ES5Transformer();

    // transform to ES5 and browserify
    transformer.browserify(
        "src", "modularity.js",
        "build", "modularity.js"
    );

    // minify source
    transformer.minify(
        "build", "modularity.js",
        "build", "modularity.min.js"
    )
});

function ES5Transformer() {

}

ES5Transformer.prototype.transform = function(inputDir, outputDir) {
    var inDir = $Path.join("./", inputDir);
    var files = new FileSystem().readFiles(inDir, function(root, name) {
        // TODO: filter all non .js files
        return true;
    });

    for (var i=0; i < files.length; i++) {
        var file = files[i];
        var outDir = $Path.join("./", outputDir, "out", file.path);

        // get source code
        var source = file.read();

        // transform to ES5
        source = $Babel.transform(source, {
            modules: "common",
            sourceMaps: false,
            comments: true,
            ast: false
        }).code;

        new File(outDir, file.name).write(source);
    }
};

// TODO: make this function sync
ES5Transformer.prototype.browserify = function(inputDir, inputFileName, outputDir, outputFileName) {
    var inputPath = $Path.join("./", outputDir, "out", inputDir, inputFileName);
    var outputPath = $Path.join("./", outputDir, outputFileName);
    var outputStream = $FileSystem.createWriteStream(outputPath);
    var bundle = $Browserify();

    this.transform(inputDir, outputDir);

    bundle.add(inputPath);

    outputStream.on('finish', function () {
        console.log("done");
    });

    outputStream.on('error', function () {
        // TODO: fails on first execution, if no build dir exists
        console.log("error");
    });

    bundle.bundle().pipe(outputStream)
};

/**
 * Obfuscates the source code of the given file
 */
ES5Transformer.prototype.minify = function(inputDir, inputFileName, outputDir, outputFileName) {
    var source = new File(inputDir, inputFileName).read();

    // obfuscate code
    source = $Uglify.minify(source, {
        fromString: true
    }).code;

    new File(outputDir, outputFileName).write(source);
};

/**
 * Utility class used to generate parser from PEG grammar
 * @param {String} name - The name of the parser
 * @param {String} path - The path to the grammar file
 * @constructor
 * @example
 *      // generates a new parser using a PEG grammar
 *      var parser = new PEGParser("Author", "grammars");
 *      parser.build().writeTo("src/parser");
 */
function PEGParser(name, path) {
    this._name = name;
    this._path = path;
}

/**
 * Builds the parser
 * @returns {{writeTo: writeTo}} Returns an object containing a function to write the parser to the file system
 * @example
 *      PEGParser("Author", "grammars").build().writeTo("src/parser");
 */
PEGParser.prototype.build = function() {
    var grammarFileName = this._name.toLowerCase() + ".pegjs";
    var parserFileName = this._name.toLowerCase() + "_parser.js";
    var grammar = new File(this._path, grammarFileName).read();

    // generate parser using grammar
    var source = $PEG.buildParser(grammar, {
        output: "source"
    });

    // convert parser to a module
    source = $EJS.render("export var <%- name %> = <%- src %>;", {
        name: this._name + "Parser",
        src: source
    });

    return {
        writeTo: function(path) {
            new File(path, parserFileName).write(source);
        }
    };
};

/**
 * Helper class used to read or write files
 * @param {String} name - The name of the file to write or read
 * @param {String} path - The path of the directory which contains or should contain the file
 * @constructor
 * @example
 *      // write data
 *      var file = new File("path/to/directory", "file.js");
 *      file.write("data to write");
 *
 *      // read data
 *      var file = new File("path/to/directory", "file.js");
 *      var data = file.read();
 */
function File(path, name) {
    this.name = name;
    this.path = path;
}

/**
 * Writes the file to the given directory path
 * @param {String} data - The data to write
 */
File.prototype.write = function(data) {
    var directory = $Path.join("./", this.path);
    var filePath = $Path.join(directory, this.name);

    // create folder if not exists
    if (!$FileSystem.existsSync(directory)) {
        $Mkdirp.sync(directory);
    }

    $FileSystem.writeFileSync(filePath, data);
};

/**
 * Reads the file from the given directory path
 * @returns {String} An UTF-8 encoded string which represents the content of the file
 */
File.prototype.read = function() {
    var filePath = $Path.join("./", this.path, this.name);
    return $FileSystem.readFileSync(filePath, {encoding: 'utf-8'});
};

function FileSystem() {

}

FileSystem.prototype.readFiles = function(path, filter) {
    var directory = $Path.join("./" + path);
    var files = [];

    $FileWalker.walkSync(directory, {
        followLinks: false,
        listeners: {

            file: function(filePath, fileInfo, next) {
                if (!filter || filter(filePath, fileInfo.name)) {
                    files.push(new File(filePath, fileInfo.name));
                }

                next();
            },

            error: function(filePath, fileInfo, next) {
                console.log("Unable to read file: " + fileInfo.name + " from: " + filePath);
                next();
            }
        }
    });

    return files;
};
<|endoftext|>


<commit_before>var gulp = require('gulp');

var gutil = require('gulp-util');
var clean = require('gulp-clean');
var rename = require('gulp-rename');
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
var uglify = require('gulp-uglify');
var concat = require('gulp-concat');
var qunit = require('gulp-qunit');

var fb = require('gulp-fb');

var paths = {
    src: [
        'src/__intro.js',

        'src/core.js',
        'src/attribute.js',
        'src/class.js',
        'src/utils.js',
        'src/serialize.js',
        'src/deserialize.js',
        'src/object.js',
        'src/asset.js',
        'src/vec2.js',
        'src/matrix3.js',
        'src/rect.js',
        'src/color.js',
        'src/texture.js',
        'src/sprite.js',
        'src/atlas.js',
        'src/fontInfo.js',

        'src/editor/platform.js',
        'src/editor/dom.js',
        'src/editor/fileUtils.js',

        'src/__outro.js',
    ],
    dev: 'bin/core.dev.js',
    min: 'bin/core.min.js',

    test: {
        src: 'test/unit/**/*.js',
        runner: 'test/lib/runner.html',
        lib_dev: [
            'bin/core.dev.js',
        ],
        lib_min: [
            'bin/core.min.js',
        ],
    },

    ref: {
        src: [
            'test/lib/*.js',
            'test/unit/_*.js',
        ],
        dest: '_references.js',
    },
};

// clean
gulp.task('clean', function() {
    return gulp.src('bin/**/*', {read: false})
    .pipe(clean())
    ;
});

// jshint
gulp.task('jshint', function() {
    return gulp.src(paths.src.concat( ['!**/__intro.js','!**/__outro.js'] ))
    .pipe(jshint({
        forin: false,
        multistr: true,
    }))
    .pipe(jshint.reporter(stylish))
    ;
});

// dev
gulp.task('dev', ['jshint'], function() {
    return gulp.src(paths.src)
    .pipe(concat('core.dev.js'))
    .pipe(gulp.dest('bin'))
    ;
});

// min
gulp.task('min', ['dev'], function() {
    return gulp.src('bin/core.dev.js')
    .pipe(rename('core.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('bin'))
    ;
});

/////////////////////////////////////////////////////////////////////////////
// test
/////////////////////////////////////////////////////////////////////////////

gulp.task('unit-runner', function() {
    var js = paths.test.src;
    var dest = paths.test.src.split('*')[0];
    return gulp.src(js, { read: false, base: './' })
               .pipe(fb.toFileList())
               .pipe(fb.generateRunner(paths.test.runner,
                                         dest,
                                         'Fireball Core Test Suite',
                                         paths.test.lib_min,
                                         paths.test.lib_dev,
                                         paths.src))
               .pipe(gulp.dest(dest))
               ;
});

gulp.task('test', ['dev', 'unit-runner'], function() {
    return gulp.src(['test/unit/**/*.html', '!**/*.dev.*'])
                .pipe(qunit())
                ;
});

/////////////////////////////////////////////////////////////////////////////
// tasks
/////////////////////////////////////////////////////////////////////////////

// ref
gulp.task('ref', function() {
    var src = paths.src;//.concat(['!src/__intro.js', '!src/__outro.js']);
    var files = paths.ref.src.concat(src);
    var destPath = paths.ref.dest;
    return fb.generateReference(files, destPath);
});

// watch
gulp.task('watch', function() {
    gulp.watch(paths.src, ['min']).on( 'error', gutil.log );
});

//
gulp.task('all', ['min', 'test', 'ref'] );
gulp.task('ci', ['min', 'test'] );
gulp.task('default', ['min'] );
<commit_msg>update gulpfile<commit_after>var gulp = require('gulp');

var gutil = require('gulp-util');
var clean = require('gulp-clean');
var rename = require('gulp-rename');
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
var uglify = require('gulp-uglify');
var concat = require('gulp-concat');
var qunit = require('gulp-qunit');

var fb = require('gulp-fb');

var paths = {
    src: [
        'src/__intro.js',

        'src/core.js',
        'src/attribute.js',
        'src/class.js',
        'src/utils.js',
        'src/serialize.js',
        'src/deserialize.js',
        'src/object.js',
        'src/asset.js',
        'src/vec2.js',
        'src/matrix3.js',
        'src/rect.js',
        'src/color.js',
        'src/texture.js',
        'src/sprite.js',
        'src/atlas.js',
        'src/fontInfo.js',

        'src/editor/platform.js',
        'src/editor/dom.js',
        'src/editor/fileUtils.js',

        'src/__outro.js',
    ],
    dev: 'bin/core.dev.js',
    min: 'bin/core.min.js',

    test: {
        src: 'test/unit/**/*.js',
        runner: 'test/lib/runner.html',
        lib_dev: [
            'bin/core.dev.js',
        ],
        lib_min: [
            'bin/core.min.js',
        ],
    },

    ref: {
        src: [
            'test/lib/*.js',
            'test/unit/_*.js',
        ],
        dest: '_references.js',
    },
};

// clean
gulp.task('clean', function() {
    return gulp.src('bin/**/*', {read: false})
    .pipe(clean())
    ;
});

// js-hint
gulp.task('jshint', function() {
    return gulp.src(paths.src.concat( ['!**/__intro.js','!**/__outro.js'] ))
    .pipe(jshint({
        forin: false,
        multistr: true,
    }))
    .pipe(jshint.reporter(stylish))
    ;
});

// dev
gulp.task('dev', ['jshint'], function() {
    return gulp.src(paths.src)
    .pipe(concat('core.dev.js'))
    .pipe(gulp.dest('bin'))
    ;
});

// min
gulp.task('min', ['dev'], function() {
    return gulp.src('bin/core.dev.js')
    .pipe(rename('core.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('bin'))
    ;
});

/////////////////////////////////////////////////////////////////////////////
// test
/////////////////////////////////////////////////////////////////////////////

gulp.task('unit-runner', function() {
    var js = paths.test.src;
    var dest = paths.test.src.split('*')[0];
    return gulp.src(js, { read: false, base: './' })
               .pipe(fb.toFileList())
               .pipe(fb.generateRunner(paths.test.runner,
                                         dest,
                                         'Fireball Core Test Suite',
                                         paths.test.lib_min,
                                         paths.test.lib_dev,
                                         paths.src))
               .pipe(gulp.dest(dest))
               ;
});

gulp.task('test', ['dev', 'unit-runner'], function() {
    return gulp.src(['test/unit/**/*.html', '!**/*.dev.*'])
                .pipe(qunit())
                ;
});

/////////////////////////////////////////////////////////////////////////////
// tasks
/////////////////////////////////////////////////////////////////////////////

// ref
gulp.task('ref', function() {
    var src = paths.src;//.concat(['!src/__intro.js', '!src/__outro.js']);
    var files = paths.ref.src.concat(src);
    var destPath = paths.ref.dest;
    return fb.generateReference(files, destPath);
});

// watch
gulp.task('watch', function() {
    gulp.watch(paths.src, ['min']).on( 'error', gutil.log );
});

//
gulp.task('all', ['min', 'test', 'ref'] );
gulp.task('ci', ['min', 'test'] );
gulp.task('default', ['min'] );
<|endoftext|>


<commit_before>var browserify = require('browserify'),
  concat = require('gulp-concat'),
  gulp = require('gulp'),
  insert = require('gulp-insert'),
  jshint = require('gulp-jshint'),
  karma = require('karma'),
  package = require('./package.json'),
  replace = require('gulp-replace'),
  source = require('vinyl-source-stream');
  streamify = require('gulp-streamify');

var srcDir = './src/';
var srcFiles = srcDir + '**.js';
var buildDir = './';

var header = "/*!\n\
 * chartjs-chart-financial\n\
 * Version: {{ version }}\n\
 *\n\
 * Copyright 2017 Ben McCann\n\
 * Released under the MIT license\n\
 * https://github.com/chartjs/chartjs-chart-financial/blob/master/LICENSE.md\n\
 */\n";

gulp.task('default', ['watch']);
gulp.task('build', buildTask);
gulp.task('jshint', jsHintTask);
gulp.task('watch', watchTask);
gulp.task('test', testTask);

function buildTask() {
  var nonBundled = browserify('./src/index.js')
    .ignore('chart.js')
    .bundle()
    .pipe(source('Chart.Financial.js'))
    .pipe(insert.prepend(header))
    .pipe(streamify(replace('{{ version }}', package.version)))
    .pipe(gulp.dest(buildDir))
    .pipe(streamify(uglify({
      preserveComments: 'some'
    })))
    .pipe(streamify(concat('Chart.Financial.min.js')))
    .pipe(gulp.dest(buildDir));

  return nonBundled;

}

function watchTask() {
  return gulp.watch(srcFiles, ['build', 'jshint']);
}

function jsHintTask() {
  return gulp.src(srcFiles)
    .pipe(jshint())
    .pipe(jshint.reporter('default'));
}

function runTest(done, singleRun) {
    new karma.Server({
        configFile: __dirname + '/karma.conf.js',
        singleRun: singleRun
    }, done).start();
}

function testTask(done) {
    runTest(done, true);
}
<commit_msg>Add back required include to gulpfile<commit_after>var browserify = require('browserify'),
  concat = require('gulp-concat'),
  gulp = require('gulp'),
  insert = require('gulp-insert'),
  jshint = require('gulp-jshint'),
  karma = require('karma'),
  package = require('./package.json'),
  replace = require('gulp-replace'),
  source = require('vinyl-source-stream');
  streamify = require('gulp-streamify'),
  uglify = require('gulp-uglify');

var srcDir = './src/';
var srcFiles = srcDir + '**.js';
var buildDir = './';

var header = "/*!\n\
 * chartjs-chart-financial\n\
 * Version: {{ version }}\n\
 *\n\
 * Copyright 2017 Ben McCann\n\
 * Released under the MIT license\n\
 * https://github.com/chartjs/chartjs-chart-financial/blob/master/LICENSE.md\n\
 */\n";

gulp.task('default', ['watch']);
gulp.task('build', buildTask);
gulp.task('jshint', jsHintTask);
gulp.task('watch', watchTask);
gulp.task('test', testTask);

function buildTask() {
  var nonBundled = browserify('./src/index.js')
    .ignore('chart.js')
    .bundle()
    .pipe(source('Chart.Financial.js'))
    .pipe(insert.prepend(header))
    .pipe(streamify(replace('{{ version }}', package.version)))
    .pipe(gulp.dest(buildDir))
    .pipe(streamify(uglify({
      preserveComments: 'some'
    })))
    .pipe(streamify(concat('Chart.Financial.min.js')))
    .pipe(gulp.dest(buildDir));

  return nonBundled;

}

function watchTask() {
  return gulp.watch(srcFiles, ['build', 'jshint']);
}

function jsHintTask() {
  return gulp.src(srcFiles)
    .pipe(jshint())
    .pipe(jshint.reporter('default'));
}

function runTest(done, singleRun) {
    new karma.Server({
        configFile: __dirname + '/karma.conf.js',
        singleRun: singleRun
    }, done).start();
}

function testTask(done) {
    runTest(done, true);
}
<|endoftext|>


<commit_before>'use strict';

var gulp        = require('gulp'),
	browserSync = require('browser-sync').create(),
	SSI 		= require('browsersync-ssi'),
	minifyCss   = require('gulp-clean-css'),
	minify   	= require('gulp-minify'),
	plumber     = require('gulp-plumber'),
	sass        = require('gulp-sass'),
	Tmaker      = require('gulp-tmaker'),
	rm      	= require('gulp-rm'),
	yargs      	= require('yargs'),
	wjson		= require('write-json'),
	verAppend 	= require('gulp-version-number'),
	fs			= require('fs'),
	useref		= require('gulp-useref'),
	gulpif 		= require('gulp-if'),
	path		= require('path'),
	projectInfo	= require('./projectInfo.json'),
	gulpSSI		= require('gulp-html-ssi');

var switchProjectName = '_init';

var fedisPath = {
	htmlSrc : 'app/'+projectInfo.projectName+'/**/*.html',
	htmlDist: 'dist/'+projectInfo.projectName+'/',
	sassSrc : 'app/'+projectInfo.projectName+'/scss/**/*.scss',
	sassDist : 'dist/'+projectInfo.projectName+'/styles/',
	jsSrc	: 'app/'+projectInfo.projectName+'/scripts/**/*.js',
	jsDist	: 'dist/'+projectInfo.projectName+'/scripts/',
	dataSrc : './app/'+projectInfo.projectName+'/data/*.*',
	dataDist: './dist/'+projectInfo.projectName+'/data/',
	assetSrc: './app/'+projectInfo.projectName+'/scss/*.+(jpg|png|gif)',
	assetDist: './dist/'+projectInfo.projectName+'/styles/'
}

// Static Server + watching scss/html files
gulp.task('serve', ['Tmaker', 'sass', 'js'], function() {

	browserSync.init({
		server: {
			baseDir:["./dist/"+projectInfo.projectName],
			middleware:SSI({
				baseDir:'./dist/'+projectInfo.projectName,
				ext:'.html',
				version:'2.10.0'
			})
		}
	});

	gulp.watch(fedisPath.sassSrc, ['sass']);
	gulp.watch(fedisPath.assetSrc, ['asset']);
	gulp.watch(fedisPath.dataSrc, ['preview-data']);
	gulp.watch(fedisPath.jsSrc, ['js']);
	gulp.watch(fedisPath.htmlSrc, ['Tmaker']);
	console.log('当前项目 :' + projectInfo.projectName);
});

gulp.task('Tmaker',function () {
	return gulp.src(fedisPath.htmlSrc)
		.pipe(plumber())
		.pipe(Tmaker({isPreview:true}))
		.pipe(gulp.dest(fedisPath.htmlDist))
		.pipe(browserSync.stream());
});

// Compile sass into CSS & auto-inject into browsers
gulp.task('sass', function() {
	return gulp.src(fedisPath.sassSrc)
		.pipe(plumber())
		.pipe(sass.sync().on('error', sass.logError))
		.pipe(sass({outputStyle:"compact"}))
		.pipe(gulp.dest(fedisPath.sassDist))
		.pipe(browserSync.stream());
});

// javscript files operate
gulp.task('js', function(){
	return gulp.src(fedisPath.jsSrc)
		.pipe(plumber())
		.pipe(gulp.dest(fedisPath.jsDist))
		.pipe(browserSync.stream());
});

gulp.task('preview-data', function () {
	return gulp.src(fedisPath.dataSrc)
		.pipe(gulp.dest(fedisPath.dataDist));
});

gulp.task('asset', function () {
	return gulp.src(fedisPath.assetSrc)
		.pipe(gulp.dest(fedisPath.assetDist));
});

// publish
function semverUpdate(key){

	var versionJson,
		semver = {
			major:0,
			minor:1,
			patch:2
		},
		semverArr;

	if(fs.existsSync('./app/'+projectInfo.projectName+'/version.json')){
		versionJson  = require('./app/'+projectInfo.projectName+'/version.json');
	} else {
		versionJson = { "version":	"1.0.0"}
	}

	semverArr = versionJson.version.split('.');
	semverArr[semver[key]] = (parseInt(semverArr[semver[key]]) + 1).toString();

	semverArr[1] = semver[key] < 1 ? 0 : semverArr[1];
	semverArr[2] = semver[key] < 2 ? 0 : semverArr[2];

	versionJson.version = semverArr.join('.');
	wjson.sync('./app/'+projectInfo.projectName+'/version.json',versionJson);
	return versionJson.version;
}

gulp.task('publish', function(){
	if(projectInfo.projectName == 'null'){
		console.log('\n 请先执行 "gulp --switch projectName" 新建一个项目\n');
		return null;
	}
	var key = (yargs.argv.major && 'major') || (yargs.argv.minor && 'minor') || (yargs.argv.patch && 'patch') || (yargs.argv.nover && 'nover') || 'patch';
	var gulpStream = null,
		canAppendVer = true;

	if (key == 'nover'){
		canAppendVer = false;
		key = 'patch';
	}

	var version = semverUpdate(key);

	gulp.src(fedisPath.assetSrc)
		.pipe(gulp.dest('release/'+projectInfo.projectName + '-' + version));

	gulpStream = gulp.src(fedisPath.htmlSrc)
		.pipe(plumber())
		.pipe(gulpSSI())
		.pipe(Tmaker({isPreview:false}))
		.pipe(useref({ searchPath: fedisPath.htmlDist}))
		.pipe(gulpif('*.js', minify()))
        .pipe(gulpif('*.css', minifyCss()));

		if(canAppendVer){
			gulpStream = gulpStream.pipe(verAppend({'append':{key:'v',to:[['css','%MD5%'],['js','%MD5%']]}}));
		}

	gulpStream.pipe(gulp.dest('release/'+projectInfo.projectName + '-' + version))
		.on('end',function(){
			console.log('已发布项目 ' + projectInfo.projectName + '-' + version)}
		);
});

// switch project
gulp.task('switch', function(cb){

	// 切换/新建 项目
	if(yargs.argv.switch == 'null'){
		console.log('\n 项目名不能为 null');
		return ;
	}

	if(yargs.argv.switch){
		switchProjectName = yargs.argv.switch;

		// 如果要切换的项目是 _init 或 已经在要切换的项目，直接返回。
		if(switchProjectName == projectInfo.projectName || projectInfo.projectName == '_init'){
			return ;
		}

		if(fs.existsSync('app/'+ switchProjectName))
		{
			// 切换项目
			projectInfo.projectName = switchProjectName;
			wjson.sync('projectInfo.json',projectInfo);
			console.log('已切换到项目 ' + switchProjectName);
		}
		else
		{
			// 新建项目
			console.log('新建 '+switchProjectName+' 项目');
			gulp.src('app/_init/**/*',{ dot: true })
				.pipe(gulp.dest('app/'+ switchProjectName))
				.on('end',function () {
					projectInfo.projectName = switchProjectName;
					wjson.sync('projectInfo.json',projectInfo);
					process.stdout.write(`新建项目完成\n`);
				});
		}
		return;
	}

	if(projectInfo.projectName == 'null'){
		console.log('\n 请先执行 "gulp --switch projectName" 新建一个项目');
		return ;
	}

	// 显示当前项目列表
	if(yargs.argv.show)
	{
		console.log('\n 当前项目 :\n');
		fs.readdirSync('app/').forEach(function(item) {
			if(item == '_init') {return;}
			console.log('   ' + item);
		})
		return console.log('\n 已列出所有项目\n');
	}

	gulp.start('serve');
});

gulp.task('default',['switch']);<commit_msg>remove  suffix<commit_after>'use strict';

var gulp = require('gulp'),
	browserSync = require('browser-sync').create(),
	SSI = require('browsersync-ssi'),
	minifyCss = require('gulp-clean-css'),
	minify = require('gulp-minify'),
	plumber = require('gulp-plumber'),
	sass = require('gulp-sass'),
	Tmaker = require('gulp-tmaker'),
	rm = require('gulp-rm'),
	yargs = require('yargs'),
	wjson = require('write-json'),
	verAppend = require('gulp-version-number'),
	fs = require('fs'),
	useref = require('gulp-useref'),
	gulpif = require('gulp-if'),
	path = require('path'),
	projectInfo = require('./projectInfo.json'),
	gulpSSI = require('gulp-html-ssi');

var switchProjectName = '_init';

var fedisPath = {
	htmlSrc: './app/' + projectInfo.projectName + '/**/*.html',
	htmlDist: './dist/' + projectInfo.projectName + '/',
	sassSrc: './app/' + projectInfo.projectName + '/scss/**/*.scss',
	sassDist: './dist/' + projectInfo.projectName + '/styles/',
	jsSrc: './app/' + projectInfo.projectName + '/scripts/**/*.js',
	jsDist: './dist/' + projectInfo.projectName + '/scripts/',
	dataSrc: './app/' + projectInfo.projectName + '/data/*.*',
	dataDist: './dist/' + projectInfo.projectName + '/data/',
	assetSrc: './app/' + projectInfo.projectName + '/scss/*.+(jpg|png|gif)',
	assetDist: './dist/' + projectInfo.projectName + '/styles/'
}

// Static Server + watching scss/html files
gulp.task('serve', ['Tmaker', 'sass', 'js'], function () {

	browserSync.init({
		server: {
			baseDir: ["./dist/" + projectInfo.projectName],
			middleware: SSI({
				baseDir: './dist/' + projectInfo.projectName,
				ext: '.html',
				version: '2.10.0'
			})
		}
	});

	gulp.watch(fedisPath.sassSrc, ['sass']);
	gulp.watch(fedisPath.assetSrc, ['asset']);
	gulp.watch(fedisPath.dataSrc, ['preview-data']);
	gulp.watch(fedisPath.jsSrc, ['js']);
	gulp.watch(fedisPath.htmlSrc, ['Tmaker']);
	console.log('当前项目 :' + projectInfo.projectName);
});

gulp.task('Tmaker', function () {
	return gulp.src(fedisPath.htmlSrc)
		.pipe(plumber())
		.pipe(Tmaker({ isPreview: true }))
		.pipe(gulp.dest(fedisPath.htmlDist))
		.pipe(browserSync.stream());
});

// Compile sass into CSS & auto-inject into browsers
gulp.task('sass', function () {
	return gulp.src(fedisPath.sassSrc)
		.pipe(plumber())
		.pipe(sass.sync().on('error', sass.logError))
		.pipe(sass({ outputStyle: "compact" }))
		.pipe(gulp.dest(fedisPath.sassDist))
		.pipe(browserSync.stream());
});

// javscript files operate
gulp.task('js', function () {
	return gulp.src(fedisPath.jsSrc)
		.pipe(plumber())
		.pipe(gulp.dest(fedisPath.jsDist))
		.pipe(browserSync.stream());
});

gulp.task('preview-data', function () {
	return gulp.src(fedisPath.dataSrc)
		.pipe(gulp.dest(fedisPath.dataDist));
});

gulp.task('asset', function () {
	return gulp.src(fedisPath.assetSrc)
		.pipe(gulp.dest(fedisPath.assetDist));
});

// publish
function semverUpdate(key) {

	var versionJson,
		semver = {
			major: 0,
			minor: 1,
			patch: 2
		},
		semverArr;

	if (fs.existsSync('./app/' + projectInfo.projectName + '/version.json')) {
		versionJson = require('./app/' + projectInfo.projectName + '/version.json');
	} else {
		versionJson = { "version": "1.0.0" }
	}

	semverArr = versionJson.version.split('.');
	semverArr[semver[key]] = (parseInt(semverArr[semver[key]]) + 1).toString();

	semverArr[1] = semver[key] < 1 ? 0 : semverArr[1];
	semverArr[2] = semver[key] < 2 ? 0 : semverArr[2];

	versionJson.version = semverArr.join('.');
	wjson.sync('./app/' + projectInfo.projectName + '/version.json', versionJson);
	return versionJson.version;
}

gulp.task('publish', function () {
	if (projectInfo.projectName == 'null') {
		console.log('\n 请先执行 "gulp --switch projectName" 新建一个项目\n');
		return null;
	}
	var key = (yargs.argv.major && 'major') || (yargs.argv.minor && 'minor') || (yargs.argv.patch && 'patch') || (yargs.argv.nover && 'nover') || 'patch';
	var gulpStream = null,
		canAppendVer = true;

	if (key == 'nover') {
		canAppendVer = false;
		key = 'patch';
	}

	var version = semverUpdate(key);

	gulp.src(fedisPath.assetSrc)
		.pipe(gulp.dest('release/' + projectInfo.projectName + '-' + version));

	gulpStream = gulp.src(fedisPath.htmlSrc)
		.pipe(plumber())
		.pipe(gulpSSI())
		.pipe(Tmaker({ isPreview: false }))
		.pipe(useref({ searchPath: fedisPath.htmlDist }))
		.pipe(gulpif('*.js', minify()))
		.pipe(gulpif('*.css', minifyCss()))
		.pipe(gulp.dest('release/' + projectInfo.projectName + '-' + version))
		.on('end', function () {
			console.log('已发布项目 ' + projectInfo.projectName + '-' + version)
		});
});

// switch project
gulp.task('switch', function (cb) {

	// 切换/新建 项目
	if (yargs.argv.switch == 'null') {
		console.log('\n 项目名不能为 null');
		return;
	}

	if (yargs.argv.switch) {
		switchProjectName = yargs.argv.switch;

		// 如果要切换的项目是 _init 或 已经在要切换的项目，直接返回。
		if (switchProjectName == projectInfo.projectName || projectInfo.projectName == '_init') {
			return;
		}

		if (fs.existsSync('app/' + switchProjectName)) {
			// 切换项目
			projectInfo.projectName = switchProjectName;
			wjson.sync('projectInfo.json', projectInfo);
			console.log('已切换到项目 ' + switchProjectName);
		}
		else {
			// 新建项目
			console.log('新建 ' + switchProjectName + ' 项目');
			gulp.src('app/_init/**/*', { dot: true })
				.pipe(gulp.dest('app/' + switchProjectName))
				.on('end', function () {
					projectInfo.projectName = switchProjectName;
					wjson.sync('projectInfo.json', projectInfo);
					process.stdout.write(`新建项目完成\n`);
				});
		}
		return;
	}

	if (projectInfo.projectName == 'null') {
		console.log('\n 请先执行 "gulp --switch projectName" 新建一个项目');
		return;
	}

	// 显示当前项目列表
	if (yargs.argv.show) {
		console.log('\n 当前项目 :\n');
		fs.readdirSync('app/').forEach(function (item) {
			if (item == '_init') { return; }
			console.log('   ' + item);
		})
		return console.log('\n 已列出所有项目\n');
	}

	gulp.start('serve');
});

gulp.task('default', ['switch']);<|endoftext|>


<commit_before>const gulp = require('gulp');
const globby = require('globby');
const path = require('path');
const fs = require('fs');
const index = require('create-index');
const shelljs = require('shelljs');

gulp.task('create-index', () => {
    index.writeIndex(['./dist']);
});

gulp.task('publish', ['create-index'], () => {
    console.log(`Patching new version ...`);
    shelljs.exec('npm version patch --force && yarn publish');

    console.log(`Writing publish package.json ...`);
    const package = fs.readFileSync('./package.json');
    const packageConfig = JSON.parse(package);

    const distPackageConfig = {};

    distPackageConfig.name = packageConfig.name;
    distPackageConfig.version = packageConfig.version;
    distPackageConfig.author = packageConfig.author;
    distPackageConfig.license = packageConfig.license;
    distPackageConfig.repository = packageConfig.repository;
    distPackageConfig.dependencies = packageConfig.dependencies;
    distPackageConfig.main = './engine/index.js';

    fs.writeFileSync('dist/package.json', JSON.stringify(distPackageConfig, null, 2));
});<commit_msg>gulp publish<commit_after>const gulp = require('gulp');
const globby = require('globby');
const path = require('path');
const fs = require('fs');
const index = require('create-index');
const shelljs = require('shelljs');

gulp.task('create-index', () => {
    index.writeIndex(['./dist']);
});

gulp.task('publish', ['create-index'], () => {
    console.log(`Patching new version ...`);
    shelljs.exec('npm version patch --force');

    console.log(`Writing publish package.json ...`);
    const package = fs.readFileSync('./package.json');
    const packageConfig = JSON.parse(package);

    const distPackageConfig = {};

    distPackageConfig.name = packageConfig.name;
    distPackageConfig.version = packageConfig.version;
    distPackageConfig.author = packageConfig.author;
    distPackageConfig.license = packageConfig.license;
    distPackageConfig.repository = packageConfig.repository;
    distPackageConfig.dependencies = packageConfig.dependencies;
    distPackageConfig.main = './engine/index.js';

    fs.writeFileSync('dist/package.json', JSON.stringify(distPackageConfig, null, 2));

    shelljs.exec('yarn publish');
});<|endoftext|>