<commit_before>(function(H) {
  if (!H.exporting) {
    H.exporting = function() {};
  }

  // This will be redefined later;
  var oldExport = H.Chart.prototype.exportChart;
  H.Chart.prototype.exportChart = function() {};

  // Set the URL of the export server to a non-existant one, just to be sure.
  H.getOptions().exporting.url = "http://127.0.0.1:666/";

  var MIME_TYPES = {
    "PDF": "application/pdf",
    "PNG": "image/png",
    "JPEG": "image/jpeg",
    "SVG": "image/svg+xml",
    "CSV": "text/csv",
    "XLS": "application/vnd.ms-excel"
  };

  var MIME_TYPE_TO_EXTENSION = {
    "application/pdf": ".pdf",
    "image/png": ".png",
    "image/jpeg": ".jpeg",
    "image/svg+xml": ".svg",
    "text/csv": ".csv",
    "application/vnd.ms-excel": ".xls"
  };

  var TRANSLATION_KEY_TO_MIME_TYPES = {
    "downloadPDF": "application/pdf",
    "downloadPNG": "image/png",
    "downloadJPEG": "image/jpeg",
    "downloadSVG": "image/svg+xml"
  };
  TRANSLATION_KEY_TO_MIME_TYPES[H.getOptions().lang.downloadCSV || 'Download CSV'] = "text/csv";
  TRANSLATION_KEY_TO_MIME_TYPES[H.getOptions().lang.downloadXLS || 'Download XLS'] = "application/vnd.ms-excel";

  // This var indicates if the browser supports HTML5 download feature
  var browserSupportDownload = false;
  var a = document.createElement('a');
  if (typeof a.download != "undefined") {
    browserSupportDownload = true;
  }
  // This is for IE support of Blob
  var browserSupportBlob = window.Blob && window.navigator.msSaveOrOpenBlob;

  /**
   * Describes the MIME types that this module supports.
   * Additionnally, you can call `support(mimeType)` to check
   * that this type is available on the current platform.
   */
  H.exporting.MIME_TYPES = MIME_TYPES;

  var supportStatus = {};
  var buildSupportStatus = function() {
    supportStatus[MIME_TYPES.CSV] = (H.Chart.prototype.getCSV !== undefined);
    supportStatus[MIME_TYPES.XLS] = (H.Chart.prototype.getTable !== undefined);

    var svgSupport = (H.Chart.prototype.getSVG !== undefined);

    supportStatus[MIME_TYPES.SVG] = svgSupport && (window.btoa !== undefined);

    // Canvg uses a function named RGBColor, but it's also a not widely known standard object
    // http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/css.html#CSS-RGBColor
    // Fugly, but heh.
    var rbgColorSupport = false;
    try {
      rbgColorSupport = (new RGBColor("").ok) !== undefined;
    }
    catch(e) {}
    // We also check that a canvas element can be created.
    var canvas = document.createElement('canvas');
    var canvgSupport = typeof canvg !== "undefined" && typeof RGBColor != "undefined" &&
    rbgColorSupport && canvas.getContext && canvas.getContext('2d');

    supportStatus[MIME_TYPES.PNG] = svgSupport && canvgSupport;
    supportStatus[MIME_TYPES.JPEG] = svgSupport && canvgSupport;

    supportStatus[MIME_TYPES.PDF] = svgSupport && canvgSupport && (typeof jsPDF !== "undefined");

  };
  buildSupportStatus();

  /**
   * Checks if the supplied MIME type is available on the
   * current platform for a chart to be exported in.
   * @param mimeType {String} The MIME type.
   * @returns {boolean} true if the MIME type is available on the
   *    current platform.
   */
   H.exporting.supports = function(mimeType) {
    if(supportStatus[mimeType]) {
      return supportStatus[mimeType];
    }
    else {
      return false;
    }
  };

  // Remove unsupported download features from the menu
  var menuItems = H.getOptions().exporting.buttons.contextButton.menuItems,
      menuItem,
      textKey,
      text,
      mimeType,
      handlerBuilder = function(mimeType) {
        return function() {
          this.exportChartLocal({
            type: mimeType,
            csv: {
              itemDelimiter: ';'
            }
          });
        }
      };
  for(var i in menuItems) {
    menuItem = menuItems[i];
    textKey = menuItems[i].textKey;
    text = menuItems[i].text; // export-csv do not use a textKey attribute
    mimeType = TRANSLATION_KEY_TO_MIME_TYPES[textKey] || TRANSLATION_KEY_TO_MIME_TYPES[text];
    if(mimeType) {
      if(!H.exporting.supports(mimeType)) {
        // Setting enabled = false isn't enough.
        delete menuItems[i];
      }
      else {
        // Redefines click handler to use our method.
        menuItems[i].onclick = handlerBuilder(mimeType);
      }
    }
  }

  /*
   * Converts a SVG string to a canvas element
   * thanks to canvg.
   * @param svg {String} A SVG string.
   * @param width {Integer} The rasterized width.
   * @param height {Integer} The rasterized height.
   * @return {DOMNode} a canvas element.
   */
  var svgToCanvas = function(svg, width, height) {
    var canvas = document.createElement('canvas');

    canvas.setAttribute('width', width);
    canvas.setAttribute('height', height);

    canvas.getContext('2d').drawSvg(svg, 0, 0, width, height);

    return canvas;
  };

  /**
   * An object to simplifies the retrieval of options in
   * multiple bundles.
   * @param opts {Object} Multiple, an object containing options.
   */
  var Opt = function(opts1, opt2, dotdotdot) {
    this.bundles = arguments;
  };

  /**
   * Fetch the value associated with the specified key in the bundles.
   * First one defined is the one returned.
   * @param key {String} The key.
   * @param value {mixed} The first defined value in the bundles or
   *    undefined if none is found.
   */
  Opt.prototype.get = function(key) {
    for(var i = 0; i < this.bundles.length; i++) {
      if(this.bundles[i] && this.bundles[i][key]) {
        return this.bundles[i][key];
      }
    }
    return undefined;
  };

  // Default options.
  var defaultExportOptions = {
    type: MIME_TYPES.PNG,
    scale: 2,
    filename: "chart",
    csv: {
      useLocalDecimalPoint: true
    }
  };

  /**
   * Redefines the export function of the official exporting module.
   * @param options {Object} Overload the export options defined in the chart.
   * @param chartOptions {Object} Additionnal chart options.
   */
  H.Chart.prototype.exportChartLocal = function(options, chartOptions) {
    var opt = new Opt(options, this.options.exporting, defaultExportOptions);

    var type = opt.get("type");
    if (!H.exporting.supports(type)) {
      throw new Error("Unsupported export format on this platform: " + type);
    }

    var filename = opt.get("filename") + MIME_TYPE_TO_EXTENSION[type];

    var data = false;

    if (type == MIME_TYPES.CSV) {
      // Copies some values from the options, so we can set it and change those
      // through the options argument.
      var hasCSVOptions = this.options.exporting && this.options.exporting.csv;
      var csvOpt = new Opt((options || {}).csv, (this.options.exporting || {}).csv, defaultExportOptions.csv);

      var oldOptions = {},
      optionsToCopy = ["dateFormat", "itemDelimiter", "lineDelimiter"],
      optionToCopy;
      for (var i in optionsToCopy) {
        optionToCopy = optionsToCopy[i];
        if (csvOpt.get(optionToCopy)) {
          if (!this.options.exporting) {
            this.options.exporting = {};
          }
          if (!this.options.exporting.csv) {
            this.options.exporting.csv = {};
          }

          oldOptions[optionToCopy] = this.options.exporting.csv[optionToCopy];
          this.options.exporting.csv[optionToCopy] = csvOpt.get(optionToCopy);
        }
      }

      var useLocalDecimalPoint = csvOpt.get("useLocalDecimalPoint");

      var csv = this.getCSV(useLocalDecimalPoint);
      data = 'data:' + MIME_TYPES.CSV + ',' + csv.replace(/\n/g, '%0A');

      if (hasCSVOptions) {
        for (var i in optionsToCopy) {
          optionToCopy = optionsToCopy[i];
          if (csvOpt.get(optionToCopy)) {
            this.options.exporting.csv[optionToCopy] = oldOptions[optionToCopy];
          }
        }
      }
      else {
        delete this.options.exporting.csv;
      }
    }
    else if (type == MIME_TYPES.XLS) {
      // Same as above
      var hasCSVOptions = this.options.exporting && this.options.exporting.csv;
      var csvOpt = new Opt((options || {}).csv, (this.options.exporting || {}).csv, defaultExportOptions.csv);

      var oldOptions = {},
          optionsToCopy = ["dateFormat"],
          optionToCopy;
      for (var i in optionsToCopy) {
        optionToCopy = optionsToCopy[i];
        if (csvOpt.get(optionToCopy)) {
          if (!this.options.exporting) {
            this.options.exporting = {};
          }
          if (!this.options.exporting.csv) {
            this.options.exporting.csv = {};
          }

          oldOptions[optionToCopy] = this.options.exporting.csv[optionToCopy];
          this.options.exporting.csv[optionToCopy] = csvOpt.get(optionToCopy);
        }
      }

      var useLocalDecimalPoint = csvOpt.get("useLocalDecimalPoint");

      var xls = '' +
        '' +
        '' +
        '<meta name=ProgId content=Excel.Sheet>' +
        '' +
        this.getTable(useLocalDecimalPoint) +
        '';
      data = 'data:' + MIME_TYPES.XLS + ';base64,' + window.btoa(decodeURIComponent(encodeURIComponent(xls)));

      if (hasCSVOptions) {
        for (var i in optionsToCopy) {
          optionToCopy = optionsToCopy[i];
          if (csvOpt.get(optionToCopy)) {
            this.options.exporting.csv[optionToCopy] = oldOptions[optionToCopy];
          }
        }
      }
      else {
        delete this.options.exporting.csv;
      }
    }
    // Image processing
    else {
      var scale = opt.get("scale"),
      sourceWidth = this.options.width || opt.get("sourceWidth") || this.chartWidth,
      sourceHeight = this.options.height || opt.get("sourceHeight") || this.chartHeight,
      destWidth = sourceWidth * scale,
      destHeight = sourceHeight * scale;

      var cChartOptions = chartOptions || this.options.exporting && this.options.exporting.chartOptions || {};
      if (!cChartOptions.chart) {
        cChartOptions.chart = { width: destWidth, height: destHeight };
      }
      else {
        cChartOptions.chart.width = destWidth;
        cChartOptions.chart.height = destHeight;
      }

      var svg = this.getSVG(cChartOptions);

      if (type == MIME_TYPES.SVG) {
        data = "data:" + MIME_TYPES.SVG + ";base64," + window.btoa(svg);
      }
      else if (type == MIME_TYPES.PNG || type == MIME_TYPES.JPEG) {
        var canvas = svgToCanvas(svg, destWidth, destHeight);
        data = canvas.toDataURL(type);
      }
      else if(type == MIME_TYPES.PDF) {
        var canvas = svgToCanvas(svg, destWidth, destHeight);

        var doc = new jsPDF('l', 'mm', [destWidth, destHeight]);;
        doc.addImage(canvas, 'JPEG', 0, 0, destWidth, destHeight);

        data = doc.output('datauristring');
      }
    }

    if (!data) {
      throw new Error("Something went wrong while exporting the chart");
    }

    if (browserSupportDownload) {
      a = document.createElement('a');
      a.href = data;
      a.download = filename;
      document.body.appendChild(a);
      a.click();
      a.remove();
    }
    else if (browserSupportBlob) {
      blobObject = new Blob([data]);
      window.navigator.msSaveOrOpenBlob(blobObject, filename);
    }
    else {
      window.open(data);
    }
  }

  // Forces method from export module to use the local version
  H.Chart.prototype.exportChart = H.Chart.prototype.exportChartLocal;

}(Highcharts));
<commit_msg>IE10+ support and better file format support detection<commit_after>(function(H) {
  if (!H.exporting) {
    H.exporting = function() {};
  }

  // This will be redefined later;
  var oldExport = H.Chart.prototype.exportChart;
  H.Chart.prototype.exportChart = function() {};

  // Set the URL of the export server to a non-existant one, just to be sure.
  H.getOptions().exporting.url = "http://127.0.0.1:666/";

  var MIME_TYPES = {
    "PDF": "application/pdf",
    "PNG": "image/png",
    "JPEG": "image/jpeg",
    "SVG": "image/svg+xml",
    "CSV": "text/csv",
    "XLS": "application/vnd.ms-excel"
  };

  var MIME_TYPE_TO_EXTENSION = {
    "application/pdf": ".pdf",
    "image/png": ".png",
    "image/jpeg": ".jpeg",
    "image/svg+xml": ".svg",
    "text/csv": ".csv",
    "application/vnd.ms-excel": ".xls"
  };

  var TRANSLATION_KEY_TO_MIME_TYPES = {
    "downloadPDF": "application/pdf",
    "downloadPNG": "image/png",
    "downloadJPEG": "image/jpeg",
    "downloadSVG": "image/svg+xml"
  };
  TRANSLATION_KEY_TO_MIME_TYPES[H.getOptions().lang.downloadCSV || 'Download CSV'] = "text/csv";
  TRANSLATION_KEY_TO_MIME_TYPES[H.getOptions().lang.downloadXLS || 'Download XLS'] = "application/vnd.ms-excel";

  // This var indicates if the browser supports HTML5 download feature
  var browserSupportDownload = false;
  var a = document.createElement('a');
  if (typeof window.btoa != "undefined" && typeof a.download != "undefined") {
    browserSupportDownload = true;
  }
  // This is for IE support of Blob
  var browserSupportBlob = window.Blob && window.navigator.msSaveOrOpenBlob;

  /**
   * Describes the MIME types that this module supports.
   * Additionnally, you can call `support(mimeType)` to check
   * that this type is available on the current platform.
   */
  H.exporting.MIME_TYPES = MIME_TYPES;

  var supportStatus = {};
  var buildSupportStatus = function() {
    var hasDownloadOrBlob = browserSupportDownload || browserSupportBlob;

    supportStatus[MIME_TYPES.CSV] = hasDownloadOrBlob && (H.Chart.prototype.getCSV !== undefined);
    supportStatus[MIME_TYPES.XLS] = hasDownloadOrBlob && (H.Chart.prototype.getTable !== undefined);

    var svgSupport = (H.Chart.prototype.getSVG !== undefined);

    supportStatus[MIME_TYPES.SVG] = hasDownloadOrBlob && svgSupport && (window.btoa !== undefined);

    // Canvg uses a function named RGBColor, but it's also a not widely known standard object
    // http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/css.html#CSS-RGBColor
    // Fugly, but heh.
    var rbgColorSupport = false;
    try {
      rbgColorSupport = (new RGBColor("").ok) !== undefined;
    }
    catch(e) {}
    // We also check that a canvas element can be created.
    var canvas = document.createElement('canvas');
    var canvgSupport = typeof canvg !== "undefined" && typeof RGBColor != "undefined" &&
    rbgColorSupport && canvas.getContext && canvas.getContext('2d');

    supportStatus[MIME_TYPES.PNG] = hasDownloadOrBlob && svgSupport && canvgSupport;
    // On IE, it relies on canvas.msToBlob() which always returns PNG
    supportStatus[MIME_TYPES.JPEG] = /* useless, see last param: hasDownloadOrBlob && */
        svgSupport && canvgSupport && browserSupportDownload;

    supportStatus[MIME_TYPES.PDF] = hasDownloadOrBlob && svgSupport && canvgSupport && (typeof jsPDF !== "undefined");

  };
  buildSupportStatus();

  /**
   * Checks if the supplied MIME type is available on the
   * current platform for a chart to be exported in.
   * @param mimeType {String} The MIME type.
   * @returns {boolean} true if the MIME type is available on the
   *    current platform.
   */
   H.exporting.supports = function(mimeType) {
    if(supportStatus[mimeType]) {
      return supportStatus[mimeType];
    }
    else {
      return false;
    }
  };

  // Remove unsupported download features from the menu
  var menuItems = H.getOptions().exporting.buttons.contextButton.menuItems,
      menuItem,
      textKey,
      text,
      mimeType,
      handlerBuilder = function(mimeType) {
        return function() {
          this.exportChartLocal({
            type: mimeType,
            csv: {
              itemDelimiter: ';'
            }
          });
        }
      };
  for(var i in menuItems) {
    menuItem = menuItems[i];
    textKey = menuItems[i].textKey;
    text = menuItems[i].text; // export-csv do not use a textKey attribute
    mimeType = TRANSLATION_KEY_TO_MIME_TYPES[textKey] || TRANSLATION_KEY_TO_MIME_TYPES[text];
    if(mimeType) {
      if(!H.exporting.supports(mimeType)) {
        // Setting enabled = false isn't enough.
        delete menuItems[i];
      }
      else {
        // Redefines click handler to use our method.
        menuItems[i].onclick = handlerBuilder(mimeType);
      }
    }
  }

  /*
   * Converts a SVG string to a canvas element
   * thanks to canvg.
   * @param svg {String} A SVG string.
   * @param width {Integer} The rasterized width.
   * @param height {Integer} The rasterized height.
   * @return {DOMNode} a canvas element.
   */
  var svgToCanvas = function(svg, width, height) {
    var canvas = document.createElement('canvas');

    canvas.setAttribute('width', width);
    canvas.setAttribute('height', height);

    canvas.getContext('2d').drawSvg(svg, 0, 0, width, height);

    return canvas;
  };

  /**
   * An object to simplifies the retrieval of options in
   * multiple bundles.
   * @param opts {Object} Multiple, an object containing options.
   */
  var Opt = function(opts1, opt2, dotdotdot) {
    this.bundles = arguments;
  };

  /**
   * Fetch the value associated with the specified key in the bundles.
   * First one defined is the one returned.
   * @param key {String} The key.
   * @param value {mixed} The first defined value in the bundles or
   *    undefined if none is found.
   */
  Opt.prototype.get = function(key) {
    for(var i = 0; i < this.bundles.length; i++) {
      if(this.bundles[i] && this.bundles[i][key]) {
        return this.bundles[i][key];
      }
    }
    return undefined;
  };

  // Default options.
  var defaultExportOptions = {
    type: MIME_TYPES.PNG,
    scale: 2,
    filename: "chart",
    csv: {
      useLocalDecimalPoint: true
    }
  };

  /**
   * Redefines the export function of the official exporting module.
   * @param options {Object} Overload the export options defined in the chart.
   * @param chartOptions {Object} Additionnal chart options.
   */
  H.Chart.prototype.exportChartLocal = function(options, chartOptions) {
    var opt = new Opt(options, this.options.exporting, defaultExportOptions);

    var type = opt.get("type");
    if (!H.exporting.supports(type)) {
      throw new Error("Unsupported export format on this platform: " + type);
    }

    var filename = opt.get("filename") + MIME_TYPE_TO_EXTENSION[type];

    var data = {
        content: undefined,
        datauri: undefined,
        blob: undefined
      };

    if (type == MIME_TYPES.CSV) {
      // Copies some values from the options, so we can set it and change those
      // through the options argument.
      var hasCSVOptions = this.options.exporting && this.options.exporting.csv;
      var csvOpt = new Opt((options || {}).csv, (this.options.exporting || {}).csv, defaultExportOptions.csv);

      var oldOptions = {},
      optionsToCopy = ["dateFormat", "itemDelimiter", "lineDelimiter"],
      optionToCopy;
      for (var i in optionsToCopy) {
        optionToCopy = optionsToCopy[i];
        if (csvOpt.get(optionToCopy)) {
          if (!this.options.exporting) {
            this.options.exporting = {};
          }
          if (!this.options.exporting.csv) {
            this.options.exporting.csv = {};
          }

          oldOptions[optionToCopy] = this.options.exporting.csv[optionToCopy];
          this.options.exporting.csv[optionToCopy] = csvOpt.get(optionToCopy);
        }
      }

      var useLocalDecimalPoint = csvOpt.get("useLocalDecimalPoint");

      var csv = this.getCSV(useLocalDecimalPoint);
      data.content = csv;

      if (hasCSVOptions) {
        for (var i in optionsToCopy) {
          optionToCopy = optionsToCopy[i];
          if (csvOpt.get(optionToCopy)) {
            this.options.exporting.csv[optionToCopy] = oldOptions[optionToCopy];
          }
        }
      }
      else {
        delete this.options.exporting.csv;
      }
    }
    else if (type == MIME_TYPES.XLS) {
      // Same as above
      var hasCSVOptions = this.options.exporting && this.options.exporting.csv;
      var csvOpt = new Opt((options || {}).csv, (this.options.exporting || {}).csv, defaultExportOptions.csv);

      var oldOptions = {},
          optionsToCopy = ["dateFormat"],
          optionToCopy;
      for (var i in optionsToCopy) {
        optionToCopy = optionsToCopy[i];
        if (csvOpt.get(optionToCopy)) {
          if (!this.options.exporting) {
            this.options.exporting = {};
          }
          if (!this.options.exporting.csv) {
            this.options.exporting.csv = {};
          }

          oldOptions[optionToCopy] = this.options.exporting.csv[optionToCopy];
          this.options.exporting.csv[optionToCopy] = csvOpt.get(optionToCopy);
        }
      }

      var useLocalDecimalPoint = csvOpt.get("useLocalDecimalPoint");

      var xls = '' +
        '' +
        '' +
        '<meta name=ProgId content=Excel.Sheet>' +
        '' +
        this.getTable(useLocalDecimalPoint) +
        '';
      data.content = xls;

      if (hasCSVOptions) {
        for (var i in optionsToCopy) {
          optionToCopy = optionsToCopy[i];
          if (csvOpt.get(optionToCopy)) {
            this.options.exporting.csv[optionToCopy] = oldOptions[optionToCopy];
          }
        }
      }
      else {
        delete this.options.exporting.csv;
      }
    }
    // Image processing
    else {
      var scale = opt.get("scale"),
      sourceWidth = this.options.width || opt.get("sourceWidth") || this.chartWidth,
      sourceHeight = this.options.height || opt.get("sourceHeight") || this.chartHeight,
      destWidth = sourceWidth * scale,
      destHeight = sourceHeight * scale;

      var cChartOptions = chartOptions || this.options.exporting && this.options.exporting.chartOptions || {};
      if (!cChartOptions.chart) {
        cChartOptions.chart = { width: destWidth, height: destHeight };
      }
      else {
        cChartOptions.chart.width = destWidth;
        cChartOptions.chart.height = destHeight;
      }

      var svg = this.getSVG(cChartOptions);

      if (type == MIME_TYPES.SVG) {
        data.content = svg;
      }
      else if (type == MIME_TYPES.PNG || type == MIME_TYPES.JPEG) {
        var canvas = svgToCanvas(svg, destWidth, destHeight);
        data.datauri = browserSupportDownload && canvas.toDataURL && canvas.toDataURL(type);
        data.blob = (type == MIME_TYPES.PNG) && !browserSupportDownload && canvas.msToBlob && canvas.msToBlob();
      }
      else if(type == MIME_TYPES.PDF) {
        var canvas = svgToCanvas(svg, destWidth, destHeight);

        var doc = new jsPDF('l', 'mm', [destWidth, destHeight]);;
        doc.addImage(canvas, 'JPEG', 0, 0, destWidth, destHeight);

        data.datauri = browserSupportDownload && doc.output('datauristring');
        data.blob = !browserSupportDownload && doc.output('blob');
      }
    }

    if (!data.content && !(data.datauri || data.blob)) {
      throw new Error("Something went wrong while exporting the chart");
    }

    if (browserSupportDownload && (data.datauri || data.content)) {
      a = document.createElement('a');
      a.href = data.datauri || ('data:' + type + ';base64,' + window.btoa(unescape(encodeURIComponent(data.content))));
      a.download = filename;
      document.body.appendChild(a);
      a.click();
      a.remove();
    }
    else if (browserSupportBlob && (data.blob || data.content)) {
      blobObject = data.blob || new Blob([data.content], { type: type });
      window.navigator.msSaveOrOpenBlob(blobObject, filename);
    }
    else {
      window.open(data);
    }
  }

  // Forces method from export module to use the local version
  H.Chart.prototype.exportChart = H.Chart.prototype.exportChartLocal;

}(Highcharts));
<|endoftext|>


<commit_before>/* eslint no-console:0 */
'use strict';

const chalk = require('chalk');
const dateformat = require('dateformat');
const symbols = require('log-symbols');

class Logger {

  constructor(options) {
    this.options = options;
  }

  static warning(entry) {
    this._log(entry, 'yellow');
  }

  static error(entry) {
    this._log(entry, 'red');
  }

  static info(entry) {
    console.log(entry);
  }

  // graphics

  static failed(entry) {
    this._log(`${symbols.error} ${entry}`, 'red');
  }

  static ok(entry) {
    this._log(`${symbols.success} ${entry}`, 'green');
  }

  static _log(entry, _color) {

    const now = dateformat(new Date(), 'HH:MM:ss');
    const defaultColor = entry instanceof Error ? 'red' : 'gray';

    const color = _color || defaultColor;

    console.log(`[${ chalk.cyan(now) }] ${ chalk[color](entry) }` );

  }

  static log(entry) {
    this._log(entry);
  }

}

module.exports = Logger;
<commit_msg>add timestamp to Logger.info<commit_after>/* eslint no-console:0 */
'use strict';

const chalk = require('chalk');
const dateformat = require('dateformat');
const symbols = require('log-symbols');

class Logger {

  constructor(options) {
    this.options = options;
  }

  static warning(entry) {
    this._log(entry, 'yellow');
  }

  static error(entry) {
    this._log(entry, 'red');
  }

  static info(entry) {
    this._log(entry);
  }

  // graphics

  static failed(entry) {
    this._log(`${symbols.error} ${entry}`, 'red');
  }

  static ok(entry) {
    this._log(`${symbols.success} ${entry}`, 'green');
  }

  static _log(entry, _color) {

    const now = dateformat(new Date(), 'HH:MM:ss');
    const defaultColor = entry instanceof Error ? 'red' : 'gray';

    const color = _color || defaultColor;

    console.log(`[${ chalk.cyan(now) }] ${ chalk[color](entry) }` );

  }

  static log(entry) {
    this._log(entry);
  }

}

module.exports = Logger;
<|endoftext|>


<commit_before>import util from 'util';
import test from 'ava';
import stdio from '../lib/stdio';

util.inspect.styles.name = 'magenta';

function createMacro(func) {
	const macro = (t, input, expected) => {
		if (expected instanceof Error) {
			t.throws(() => {
				stdio(input);
			}, expected.message);
			return;
		}

		const result = func(input);

		if (typeof expected === 'object' && expected !== null) {
			t.deepEqual(result, expected);
		} else {
			t.is(result, expected);
		}
	};

	macro.title = (providedTitle, input) => `${func.name} ${(providedTitle || util.inspect(input, {colors: true}))}`;

	return macro;
}

const stdioMacro = createMacro(stdio);

test(stdioMacro, undefined, undefined);
test(stdioMacro, null, undefined);

test(stdioMacro, {stdio: 'inherit'}, 'inherit');
test(stdioMacro, {stdio: 'pipe'}, 'pipe');
test(stdioMacro, {stdio: 'ignore'}, 'ignore');
test(stdioMacro, {stdio: [0, 1, 2]}, [0, 1, 2]);

test(stdioMacro, {}, [undefined, undefined, undefined]);
test(stdioMacro, {stdio: []}, [undefined, undefined, undefined]);
test(stdioMacro, {stdin: 'pipe'}, ['pipe', undefined, undefined]);
test(stdioMacro, {stdout: 'ignore'}, [undefined, 'ignore', undefined]);
test(stdioMacro, {stderr: 'inherit'}, [undefined, undefined, 'inherit']);
test(stdioMacro, {stdin: 'pipe', stdout: 'ignore', stderr: 'inherit'}, ['pipe', 'ignore', 'inherit']);
test(stdioMacro, {stdin: 'pipe', stdout: 'ignore'}, ['pipe', 'ignore', undefined]);
test(stdioMacro, {stdin: 'pipe', stderr: 'inherit'}, ['pipe', undefined, 'inherit']);
test(stdioMacro, {stdout: 'ignore', stderr: 'inherit'}, [undefined, 'ignore', 'inherit']);
test(stdioMacro, {stdin: 0, stdout: 1, stderr: 2}, [0, 1, 2]);
test(stdioMacro, {stdin: 0, stdout: 1}, [0, 1, undefined]);
test(stdioMacro, {stdin: 0, stderr: 2}, [0, undefined, 2]);
test(stdioMacro, {stdout: 1, stderr: 2}, [undefined, 1, 2]);

test(stdioMacro, {stdio: {foo: 'bar'}}, new TypeError('Expected `stdio` to be of type `string` or `Array`, got `object`'));

test(stdioMacro, {stdin: 'inherit', stdio: 'pipe'}, new Error('It\'s not possible to provide `stdio` in combination with one of `stdin`, `stdout`, `stderr`'));
test(stdioMacro, {stdin: 'inherit', stdio: ['pipe']}, new Error('It\'s not possible to provide `stdio` in combination with one of `stdin`, `stdout`, `stderr`'));
test(stdioMacro, {stdin: 'inherit', stdio: [undefined, 'pipe']}, new Error('It\'s not possible to provide `stdio` in combination with one of `stdin`, `stdout`, `stderr`'));

const forkMacro = createMacro(stdio.node);

test(forkMacro, undefined, ['pipe', 'pipe', 'pipe', 'ipc']);
test(forkMacro, {stdio: 'ignore'}, ['ignore', 'ignore', 'ignore', 'ipc']);
test(forkMacro, {stdio: [0, 1, 2]}, [0, 1, 2, 'ipc']);
test(forkMacro, {stdio: [0, 1, 2, 3]}, [0, 1, 2, 3, 'ipc']);
test(forkMacro, {stdio: [0, 1, 2, 'ipc']}, [0, 1, 2, 'ipc']);

test(forkMacro, {stdout: 'ignore'}, ['pipe', 'ignore', 'pipe', 'ipc']);
test(forkMacro, {stdout: 'ignore', stderr: 'ignore'}, ['pipe', 'ignore', 'ignore', 'ipc']);

test(forkMacro, {stdio: {foo: 'bar'}}, new TypeError('Expected `stdio` to be of type `string` or `Array`, got `object`'));
test(forkMacro, {stdin: 'inherit', stdio: 'pipe'}, new Error('It\'s not possible to provide `stdio` in combination with one of `stdin`, `stdout`, `stderr`'));
<commit_msg>Simplify tests for stdio (#300)<commit_after>import util from 'util';
import test from 'ava';
import stdio from '../lib/stdio';

const macro = (t, input, expected, func) => {
	if (expected instanceof Error) {
		t.throws(() => {
			stdio(input);
		}, expected.message);
		return;
	}

	t.deepEqual(func(input), expected);
};

const macroTitle = name => (title, input) => `${name} ${(util.inspect(input))}`;

const stdioMacro = (...args) => macro(...args, stdio);
stdioMacro.title = macroTitle('execa()');

test(stdioMacro, undefined, undefined);
test(stdioMacro, null, undefined);

test(stdioMacro, {stdio: 'inherit'}, 'inherit');
test(stdioMacro, {stdio: 'pipe'}, 'pipe');
test(stdioMacro, {stdio: 'ignore'}, 'ignore');
test(stdioMacro, {stdio: [0, 1, 2]}, [0, 1, 2]);

test(stdioMacro, {}, [undefined, undefined, undefined]);
test(stdioMacro, {stdio: []}, [undefined, undefined, undefined]);
test(stdioMacro, {stdin: 'pipe'}, ['pipe', undefined, undefined]);
test(stdioMacro, {stdout: 'ignore'}, [undefined, 'ignore', undefined]);
test(stdioMacro, {stderr: 'inherit'}, [undefined, undefined, 'inherit']);
test(stdioMacro, {stdin: 'pipe', stdout: 'ignore', stderr: 'inherit'}, ['pipe', 'ignore', 'inherit']);
test(stdioMacro, {stdin: 'pipe', stdout: 'ignore'}, ['pipe', 'ignore', undefined]);
test(stdioMacro, {stdin: 'pipe', stderr: 'inherit'}, ['pipe', undefined, 'inherit']);
test(stdioMacro, {stdout: 'ignore', stderr: 'inherit'}, [undefined, 'ignore', 'inherit']);
test(stdioMacro, {stdin: 0, stdout: 1, stderr: 2}, [0, 1, 2]);
test(stdioMacro, {stdin: 0, stdout: 1}, [0, 1, undefined]);
test(stdioMacro, {stdin: 0, stderr: 2}, [0, undefined, 2]);
test(stdioMacro, {stdout: 1, stderr: 2}, [undefined, 1, 2]);

test(stdioMacro, {stdio: {foo: 'bar'}}, new TypeError('Expected `stdio` to be of type `string` or `Array`, got `object`'));

test(stdioMacro, {stdin: 'inherit', stdio: 'pipe'}, new Error('It\'s not possible to provide `stdio` in combination with one of `stdin`, `stdout`, `stderr`'));
test(stdioMacro, {stdin: 'inherit', stdio: ['pipe']}, new Error('It\'s not possible to provide `stdio` in combination with one of `stdin`, `stdout`, `stderr`'));
test(stdioMacro, {stdin: 'inherit', stdio: [undefined, 'pipe']}, new Error('It\'s not possible to provide `stdio` in combination with one of `stdin`, `stdout`, `stderr`'));

const forkMacro = (...args) => macro(...args, stdio.node);
forkMacro.title = macroTitle('execa.fork()');

test(forkMacro, undefined, ['pipe', 'pipe', 'pipe', 'ipc']);
test(forkMacro, {stdio: 'ignore'}, ['ignore', 'ignore', 'ignore', 'ipc']);
test(forkMacro, {stdio: [0, 1, 2]}, [0, 1, 2, 'ipc']);
test(forkMacro, {stdio: [0, 1, 2, 3]}, [0, 1, 2, 3, 'ipc']);
test(forkMacro, {stdio: [0, 1, 2, 'ipc']}, [0, 1, 2, 'ipc']);

test(forkMacro, {stdout: 'ignore'}, ['pipe', 'ignore', 'pipe', 'ipc']);
test(forkMacro, {stdout: 'ignore', stderr: 'ignore'}, ['pipe', 'ignore', 'ignore', 'ipc']);

test(forkMacro, {stdio: {foo: 'bar'}}, new TypeError('Expected `stdio` to be of type `string` or `Array`, got `object`'));
test(forkMacro, {stdin: 'inherit', stdio: 'pipe'}, new Error('It\'s not possible to provide `stdio` in combination with one of `stdin`, `stdout`, `stderr`'));
<|endoftext|>


<commit_before>/*!
 * angular-loading-bar v0.0.1
 * https://chieffancypants.github.io/angular-loading-bar
 * Copyright (c) 2013 Wes Cruver
 * License: MIT
 */
!function(){"use strict";angular.module("chieffancypants.loadingBar",[]).config(["$httpProvider",function(a){var b=["$q","$cacheFactory","cfpLoadingBar",function(b,c,d){function e(){d.complete(),h=0,g=0}function f(b){if("GET"!=b.method||b.cache===!1)return b.cached=!1,!1;var d,e=a.defaults;d=b.cache===!0&&void 0===e.cache?c.get("$http"):void 0!==e.cache?e.cache:b.cache;var f=void 0!==d?void 0!==d.get(b.url):!1;return void 0!==b.cached&&f!=b.cached?b.cached:(b.cached=f,f)}var g=0,h=0;return{request:function(a){return f(a)||(0===g&&d.start(),g++),a},response:function(a){return f(a.config)||(h++,h===g?e():d.set(h/g)),a},responseError:function(a){return f(a.config)||(h++,h===g?e():d.set(h/g)),b.reject(a)}}}];a.interceptors.push(b)}]).provider("cfpLoadingBar",function(){this.includeSpinner=!0,this.$get=["$document","$timeout","$animate",function(a,b,c){function d(){n=!0,c.enter(k,j),p&&c.enter(m,j),e(.02)}function e(a){if(n){var c=100*a+"%";l.css("width",c),o=a,b.cancel(i),i=b(function(){f()},250)}}function f(){if(!(g()>=1)){var a=0,b=g();a=b>=0&&.25>b?(3*Math.random()+3)/100:b>=.25&&.65>b?3*Math.random()/100:b>=.65&&.9>b?2*Math.random()/100:b>=.9&&.99>b?.005:0;var c=g()+a;e(c)}}function g(){return o}function h(){e(1),b(function(){c.leave(k,function(){o=0,n=!1}),c.leave(m)},500)}var i,j=a.find("body"),k=angular.element('

'),l=k.find("div").eq(0),m=angular.element('

'),n=!1,o=0,p=this.includeSpinner;return{start:d,set:e,status:g,complete:h,includeSpinner:this.includeSpinner}}]})}();<commit_msg>updated minified JS<commit_after>/*!
 * angular-loading-bar v0.0.1
 * https://chieffancypants.github.io/angular-loading-bar
 * Copyright (c) 2013 Wes Cruver
 * License: MIT
 */
!function(){"use strict";angular.module("chieffancypants.loadingBar",[]).config(["$httpProvider",function(a){var b=["$q","$cacheFactory","cfpLoadingBar",function(b,c,d){function e(){d.complete(),h=0,g=0}function f(b){var d,e=a.defaults;if("GET"!==b.method||b.cache===!1)return b.cached=!1,!1;d=b.cache===!0&&void 0===e.cache?c.get("$http"):void 0!==e.cache?e.cache:b.cache;var f=void 0!==d?void 0!==d.get(b.url):!1;return void 0!==b.cached&&f!==b.cached?b.cached:(b.cached=f,f)}var g=0,h=0;return{request:function(a){return f(a)||(0===g&&d.start(),g++),a},response:function(a){return f(a.config)||(h++,h===g?e():d.set(h/g)),a},responseError:function(a){return f(a.config)||(h++,h===g?e():d.set(h/g)),b.reject(a)}}}];a.interceptors.push(b)}]).provider("cfpLoadingBar",function(){this.includeSpinner=!0,this.parentSelector="body",this.$get=["$document","$timeout","$animate",function(a,b,c){function d(){o=!0,c.enter(l,k),q&&c.enter(n,k),e(.02)}function e(a){if(o){var c=100*a+"%";m.css("width",c),p=a,b.cancel(i),i=b(function(){f()},250)}}function f(){if(!(g()>=1)){var a=0,b=g();a=b>=0&&.25>b?(3*Math.random()+3)/100:b>=.25&&.65>b?3*Math.random()/100:b>=.65&&.9>b?2*Math.random()/100:b>=.9&&.99>b?.005:0;var c=g()+a;e(c)}}function g(){return p}function h(){e(1),b(function(){c.leave(l,function(){p=0,o=!1}),c.leave(n)},500)}var i,j=this.parentSelector,k=a.find(j),l=angular.element('

'),m=l.find("div").eq(0),n=angular.element('

'),o=!1,p=0,q=this.includeSpinner;return{start:d,set:e,status:g,complete:h,includeSpinner:this.includeSpinner,parentSelector:this.parentSelector}}]})}();<|endoftext|>


<commit_before>/**
 * Author: Jeff Whelpley
 * Date: 2/18/14
 *
 * A simple adapter to call out to API from another node process
 */
var Q               = require('q');
var _               = require('lodash');
var request         = require('request');
var jsonwebtoken    = require('jsonwebtoken');
var cls             = require('continuation-local-storage');
var mongo           = require('pancakes-mongo');
var admin = {}, baseUrl, headers;

/**
 * Initialize the methods for this interface using the resource. This will
 * loop through the routes defined in the api section of the resource file
 * and auto generate method interfaces which all end up make REST API calls.
 *
 * @param resource
 * @constructor
 */
function ApiclientAdapter(resource) {
    this.admin = admin;
    this.resource = resource || {};

    // loop through API interface for resource to get methods to expose
    var me = this;
    _.each(resource.api, function (methodInfo, httpMethod) {
        _.each(methodInfo, function (operation, path) {
            me[operation] = function (req) {
                return me.send(httpMethod, path, req);
            };
        });
    });
}

/**
 * Init called at startup and is used to
 * @param config
 */
function init(config) {
    var tokenConfig = config.security.token || {};
    var privateKey = tokenConfig.privateKey;
    var decryptedToken = {
        _id: tokenConfig.webserverId,
        authToken: tokenConfig.webserverToken
    };
    var jwt = jsonwebtoken.sign(decryptedToken, privateKey);

    headers = { 'Authorization': 'Bearer ' + jwt };

    admin._id =  mongo.newObjectId('000000000000000000000000');
    admin.name = 'systemAdmin';
    admin.type = 'user';
    admin.role = 'admin';

    var useSSL = (config.api && config.api.serverUseSSL !== undefined) ?
        config.api.serverUseSSL : config.useSSL;
    baseUrl = (useSSL ? 'https://' : 'http://') + config.api.host;

    var port = config.api.port;
    if (port !== 80 && port !== 443) {
        baseUrl += ':' + port;
    }

    baseUrl += '/' + config.api.version;

    return config;
}

// add to the class
_.extend(ApiclientAdapter, {
    init:       init,
    webInit:    init
});

/**
 * Send the request to the restful endpoint
 * @param httpMethod
 * @param path
 * @param req
 */
function send(httpMethod, path, req) {
    req = req || {};
    httpMethod = httpMethod.toUpperCase();

    var deferred = Q.defer();
    var url = baseUrl + path;
    var data = req.data || {};          // separate out data from request
    delete req.data;

    var isAdmin = req.caller && req.caller.role === 'admin';
    delete req.caller;

    var id = req._id || data._id;       // get id from request or data
    if (req._id) { delete req._id; }    // delete id from request so no dupe

    var session = cls.getNamespace('appSession');
    var caller = session && session.active && session.get('caller');
    if (caller && !isAdmin) {
        _.extend(req, {                 // onBehalfOf used by API to know who is the caller
            onBehalfOfType: caller.type,
            onBehalfOfId:   caller._id + '',
            onBehalfOfRole: caller.role,
            onBehalfOfName: caller.name
        });
    }

    _.each(req, function (val, key) {
        if (!_.isString(val)) { req[key] = JSON.stringify(val); }
    });

    // replace the ID portion of the URL
    url = id ?
        url.replace('{_id}', id + '') :
        url.replace('/{_id}', '');

    var reqConfig = {
        headers:    headers,
        url:        url,
        method:     httpMethod,
        qs:         _.isEmpty(req) ? undefined : req,
        json:       _.isEmpty(data) ? true : data
    };

    request(reqConfig, function (err, resp, obj) {
        if (err)                            { deferred.reject(err); }
        else if (resp.statusCode !== 200)   { deferred.reject(obj || resp.statusMessage); }
        else                                { deferred.resolve(obj); }
    });

    return deferred.promise;
}

// add send to the prototype for an instance of apiclient adapter
_.extend(ApiclientAdapter.prototype, {
    send: send
});

// return the class
module.exports = ApiclientAdapter;
<commit_msg>Adding internal host from web to api<commit_after>/**
 * Author: Jeff Whelpley
 * Date: 2/18/14
 *
 * A simple adapter to call out to API from another node process
 */
var Q               = require('q');
var _               = require('lodash');
var request         = require('request');
var jsonwebtoken    = require('jsonwebtoken');
var cls             = require('continuation-local-storage');
var mongo           = require('pancakes-mongo');
var admin = {}, baseUrl, headers;

/**
 * Initialize the methods for this interface using the resource. This will
 * loop through the routes defined in the api section of the resource file
 * and auto generate method interfaces which all end up make REST API calls.
 *
 * @param resource
 * @constructor
 */
function ApiclientAdapter(resource) {
    this.admin = admin;
    this.resource = resource || {};

    // loop through API interface for resource to get methods to expose
    var me = this;
    _.each(resource.api, function (methodInfo, httpMethod) {
        _.each(methodInfo, function (operation, path) {
            me[operation] = function (req) {
                return me.send(httpMethod, path, req);
            };
        });
    });
}

/**
 * Init called at startup and is used to
 * @param config
 */
function init(config) {
    var tokenConfig = config.security.token || {};
    var privateKey = tokenConfig.privateKey;
    var decryptedToken = {
        _id: tokenConfig.webserverId,
        authToken: tokenConfig.webserverToken
    };
    var jwt = jsonwebtoken.sign(decryptedToken, privateKey);

    headers = { 'Authorization': 'Bearer ' + jwt };

    admin._id =  mongo.newObjectId('000000000000000000000000');
    admin.name = 'systemAdmin';
    admin.type = 'user';
    admin.role = 'admin';

    var apiConfig = config.api || {};
    var host = apiConfig.internalHost || apiConfig.host;  // from web server to api use internalHost name
    var useSSL = apiConfig.serverUseSSL !== undefined ?
        apiConfig.serverUseSSL : config.useSSL;
    baseUrl = (useSSL ? 'https://' : 'http://') + host;

    var port = config.api.port;
    if (port !== 80 && port !== 443) {
        baseUrl += ':' + port;
    }

    baseUrl += '/' + config.api.version;

    return config;
}

// add to the class
_.extend(ApiclientAdapter, {
    init:       init,
    webInit:    init
});

/**
 * Send the request to the restful endpoint
 * @param httpMethod
 * @param path
 * @param req
 */
function send(httpMethod, path, req) {
    req = req || {};
    httpMethod = httpMethod.toUpperCase();

    var deferred = Q.defer();
    var url = baseUrl + path;
    var data = req.data || {};          // separate out data from request
    delete req.data;

    var isAdmin = req.caller && req.caller.role === 'admin';
    delete req.caller;

    var id = req._id || data._id;       // get id from request or data
    if (req._id) { delete req._id; }    // delete id from request so no dupe

    var session = cls.getNamespace('appSession');
    var caller = session && session.active && session.get('caller');
    if (caller && !isAdmin) {
        _.extend(req, {                 // onBehalfOf used by API to know who is the caller
            onBehalfOfType: caller.type,
            onBehalfOfId:   caller._id + '',
            onBehalfOfRole: caller.role,
            onBehalfOfName: caller.name
        });
    }

    _.each(req, function (val, key) {
        if (!_.isString(val)) { req[key] = JSON.stringify(val); }
    });

    // replace the ID portion of the URL
    url = id ?
        url.replace('{_id}', id + '') :
        url.replace('/{_id}', '');

    var reqConfig = {
        headers:    headers,
        url:        url,
        method:     httpMethod,
        qs:         _.isEmpty(req) ? undefined : req,
        json:       _.isEmpty(data) ? true : data
    };

    request(reqConfig, function (err, resp, obj) {
        if (err)                            { deferred.reject(err); }
        else if (resp.statusCode !== 200)   { deferred.reject(obj || resp.statusMessage); }
        else                                { deferred.resolve(obj); }
    });

    return deferred.promise;
}

// add send to the prototype for an instance of apiclient adapter
_.extend(ApiclientAdapter.prototype, {
    send: send
});

// return the class
module.exports = ApiclientAdapter;
<|endoftext|>


<commit_before>game.SpendExp = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {
		me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage("exp-screen")), -10); // TODO

                me.game.world.addChild(new (me.Renderable.extend({
                    init: function(){
                        this._super(me.Renderable, 'init', [10, 10, 300, 50]);
                        this.font = new me.Font("Arial", 25, "white");

                    },

                    draw: function(renderer){
                        this.font.draw(renderer.getContext(), "PRESS F1 - F4 TO BUY, AND F5 TO SKIP", this.pos.x, this.pos.y);
                        this.font.draw(renderer.getContext(), "CURRENT EXP: " + game.data.exp.toString(), this.pos.x + 100, this.pos.y + 50);
                        this.font.draw(renderer.getContext(), "F1: INCREASE GOLD PRODUCTION CURRENT LEVEL " + game.data.exp1.toString() + " PRICE: ", this.pos.x + 200, this.pos.y + 100);
                        this.font.draw(renderer.getContext(), "F2: ADD STARTING GOLD " + game.data.exp2.toString() + " PRICE: " + ((game.data.exp1 + 1) * 10), this.pos.x + 200, this.pos.y + 150);
                        this.font.draw(renderer.getContext(), "F3: INCREASE ATTACK DAMAGES " + game.data.exp3.toString() + " PRICE: ", this.pos.x + 200, this.pos.y + 200);
                        this.font.draw(renderer.getContext(), "F4: INCREASE STARTING HEALTH " + game.data.exp4.toString() + " PRICE: ", this.pos.x + 200, this.pos.y + 250);

                    }
                })));

        },

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {

	}
});
<commit_msg>Finished SpendExp screen<commit_after>game.SpendExp = me.ScreenObject.extend({
	/**
	 *  action to perform on state change
	 */
	onResetEvent: function() {
		me.game.world.addChild(new me.Sprite(0, 0, me.loader.getImage("exp-screen")), -10); // TODO
                me.input.bindKey(me.input.KEY.F1, "F1");
                me.input.bindKey(me.input.KEY.F2, "F2");
                me.input.bindKey(me.input.KEY.F3, "F3");
                me.input.bindKey(me.input.KEY.F4, "F4");
                me.input.bindKey(me.input.KEY.F5, "F5");
                me.game.world.addChild(new (me.Renderable.extend({
                    init: function(){
                        this._super(me.Renderable, 'init', [10, 10, 300, 50]);
                        this.font = new me.Font("Arial", 25, "white");

                    },

                    draw: function(renderer){
                        this.font.draw(renderer.getContext(), "PRESS F1 - F4 TO BUY, AND F5 TO SKIP", this.pos.x, this.pos.y);
                        this.font.draw(renderer.getContext(), "CURRENT EXP: " + game.data.exp.toString(), this.pos.x + 100, this.pos.y + 50);
                        this.font.draw(renderer.getContext(), "F1: INCREASE GOLD PRODUCTION CURRENT LEVEL " + game.data.exp1.toString() + " PRICE: " + ((game.data.exp1 + 1) * 10), this.pos.x + 200, this.pos.y + 100);
                        this.font.draw(renderer.getContext(), "F2: ADD STARTING GOLD " + game.data.exp2.toString() + " PRICE: " + ((game.data.exp2 + 2) * 10), this.pos.x + 200, this.pos.y + 150);
                        this.font.draw(renderer.getContext(), "F3: INCREASE ATTACK DAMAGES " + game.data.exp3.toString() + " PRICE: " + ((game.data.exp3 + 3) * 10), this.pos.x + 200, this.pos.y + 200);
                        this.font.draw(renderer.getContext(), "F4: INCREASE STARTING HEALTH " + game.data.exp4.toString() + " PRICE: " + ((game.data.exp4 + 4) * 10), this.pos.x + 200, this.pos.y + 250);

                    }
                })));

                this.handler = me.event.subscribe(me.event.KEYDOWN, function (action, keyCode, edge){
                    if(action === "F1"){

                    }else if(action === "F2"){

                    }else if(action === "F3"){

                    }else if(action === "F4"){

                    }else if(action === "F5"){
                        me.state.change(me.state.PLAY);
                    }
                });
        },

	/**
	 *  action to perform when leaving this screen (state change)
	 */
	onDestroyEvent: function() {
	me.input.unbindKey(me.input.KEY.F1, "F1");
        me.input.unbindKey(me.input.KEY.F2, "F2");
        me.input.unbindKey(me.input.KEY.F3, "F3");
        me.input.unbindKey(me.input.KEY.F4, "F4");
        me.input.unbindKey(me.input.KEY.F5, "F5");
        me.event.unsubscribe(this.handler);
	}
});
<|endoftext|>


<commit_before>'use strict';

angular.module('sv')
  .controller('MainCtrl', function ($scope, $timeout, GithubAPI) {

    $scope.user = {'username': '', 'repos':[], 'branches':[], 'currentRepo':'', 'currentBranch': '', 'currentCommits':[]}

	//var dbClient = new Dropbox.Client({ key: 'ul8h8jpx9o164n1'});
	if(!$scope.dbClient){
		$scope.dbClient = new Dropbox.Client({ key: '4nl4o8v9y9wqv1i' });
	}

	if(!$scope.dbClient.isAuthenticated()){
		$scope.dbClient.authDriver(new Dropbox.AuthDriver.Popup({ receiverUrl:  'https://ronlaflamme.github.io/sv/oauth_receiver.html' }));
		$scope.dbClient.authenticate(function(authError){
		if(authError || !$scope.dbClient.isAuthenticated()){
			alert("Cannot login to Dropbox!");
		}});
	}

	$scope.usernameChange = function(){
		$scope.user.branches = [];
		$scope.user.repos = [];
		$scope.user.currentRepo = '';
		$scope.user.currentBranch = '';
		$scope.user.currentCommits = [];

        GithubAPI.getRepos($scope.user.username).then(function(data){
            $scope.user.repos = [];
            angular.forEach(data, function(repo){
                $scope.user.repos.push(repo.full_name.split("/").pop());
            });
        });
    }

    $scope.repoChanged = function(){
        $scope.user.branches = [];
        GithubAPI.getBranches($scope.user.username, $scope.user.currentRepo).then(function(data){
            angular.forEach(data, function(branch){
                $scope.user.branches.push(branch.name);
            });
			$scope.user.currentBranch = 'master';
        });
    }
	$scope.$watch("user.currentBranch", function(newVal){
		if (newVal){
			branchChanged();
		}
	});

    var branchChanged = function(){
        GithubAPI.getCommits($scope.user.username, $scope.user.currentRepo, $scope.user.currentBranch).then(function(data){
            $scope.user.currentCommits = [];

			// set log filename to most recent commit date
			if(data && data.length > 0){
				$scope.dbFilename="SV_" + data[0].commit.committer.date + ".log";
			}

			if($scope.dbClient.isAuthenticated()){
				for(var i = 0; i < data.length; i++){
					var commit = data[i];
					var commitDate = commit.commit.committer.date;
					var previousCommitDate = i + 1 < data.length ?
										data[i+1].commit.committer.date : null;
					$timeout(function(){
						$scope.user.currentCommits.push({
								'timestamp': commitDate,
								'hostId':  "Not found",
								'commit':  commit.sha,
								'previousCommitDate': previousCommitDate});
					});
				}

				angular.forEach($scope.user.currentCommits, function(currentCommit){
					GithubAPI.getCommit($scope.user.username, $scope.user.currentRepo,
										 currentCommit.commit).then(function(commitInfo){

					if(commitInfo.hasOwnProperty("files") &&
						commitInfo.files.length > 0){

						// grab first file in commit and retrieve DB host_id
						var filename = $scope.user.currentRepo + '/' + commitInfo.files[0].filename;

						$scope.dbClient.history(filename, function(error, revisions){
							var hostID;
							if(error){
								currentCommit.hostID = error.responseText;
							}
							else if(revisions && revisions.length > 0){
								for(var i = 0; i < revisions.length; i++){
									var revisionDate = revisions[i].modifiedAt;
									if(revisionDate <= new Date(currentCommit.timestamp) &&
										revisionDate >= new Date(currentCommit.previousCommitDate)){
											currentCommit.hostID = revisions[i]["host_id"];
											break;
										}
								}
							}
							else{
								hostId = "Unable to retrieve revision history for commit";
							}
						});
					}
					});

				});
			}
		});
    }

	$scope.saveToDropboxClick = function(){

		if(!$scope.dbClient){
			$scope.dbClient = new Dropbox.Client({ key: '4nl4o8v9y9wqv1i' });
		}

		if(!$scope.dbClient.isAuthenticated()){
			$scope.dbClient.authDriver(new Dropbox.AuthDriver.Popup({ receiverUrl:  'https://ronlaflamme.github.io/sv/oauth_receiver.html' }));
			$scope.dbClient.authenticate(function(authError){
			if(authError || !$scope.dbClient.isAuthenticated()){
				alert("Cannot login to Dropbox!");
			}});
		}

		if($scope.dbClient.isAuthenticated()){
			var filename = $scope.dbFilename ? $scope.dbFilename : Date() + ".log";
			filename = filename.replace(/:/g, "_").replace(/Z/g, "");
			$scope.dbClient.writeFile("sv_log/" + filename,
				JSON.stringify($scope.user.currentCommits),
				function(error, stat) {
				if (error) {
					alert(error);
				}
				else{
					alert("File saved");
				}
			});
		}
	};
  });
<commit_msg>fix for updating host_id<commit_after>'use strict';

angular.module('sv')
  .controller('MainCtrl', function ($scope, $timeout, GithubAPI) {

    $scope.user = {'username': '', 'repos':[], 'branches':[], 'currentRepo':'', 'currentBranch': '', 'currentCommits':[]}

	//var dbClient = new Dropbox.Client({ key: 'ul8h8jpx9o164n1'});
	if(!$scope.dbClient){
		$scope.dbClient = new Dropbox.Client({ key: '4nl4o8v9y9wqv1i' });
	}

	if(!$scope.dbClient.isAuthenticated()){
		$scope.dbClient.authDriver(new Dropbox.AuthDriver.Popup({ receiverUrl:  'https://ronlaflamme.github.io/sv/oauth_receiver.html' }));
		$scope.dbClient.authenticate(function(authError){
		if(authError || !$scope.dbClient.isAuthenticated()){
			alert("Cannot login to Dropbox!");
		}});
	}

	$scope.usernameChange = function(){
		$scope.user.branches = [];
		$scope.user.repos = [];
		$scope.user.currentRepo = '';
		$scope.user.currentBranch = '';
		$scope.user.currentCommits = [];

        GithubAPI.getRepos($scope.user.username).then(function(data){
            $scope.user.repos = [];
            angular.forEach(data, function(repo){
                $scope.user.repos.push(repo.full_name.split("/").pop());
            });
        });
    }

    $scope.repoChanged = function(){
        $scope.user.branches = [];
        GithubAPI.getBranches($scope.user.username, $scope.user.currentRepo).then(function(data){
            angular.forEach(data, function(branch){
                $scope.user.branches.push(branch.name);
            });
			$scope.user.currentBranch = 'master';
        });
    }
	$scope.$watch("user.currentBranch", function(newVal){
		if (newVal){
			branchChanged();
		}
	});

    var branchChanged = function(){
        GithubAPI.getCommits($scope.user.username, $scope.user.currentRepo, $scope.user.currentBranch).then(function(data){
            $scope.user.currentCommits = [];

			// set log filename to most recent commit date
			if(data && data.length > 0){
				$scope.dbFilename="SV_" + data[0].commit.committer.date + ".log";
			}

			if($scope.dbClient.isAuthenticated()){
				for(var i = 0; i < data.length; i++){
					var commit = data[i];
					var commitDate = commit.commit.committer.date;
					var previousCommitDate = i + 1 < data.length ?
										data[i+1].commit.committer.date : null;

					$scope.user.currentCommits.push({
							'timestamp': commitDate,
							'hostId':  "Not found",
							'commit':  commit.sha,
							'previousCommitDate': previousCommitDate});

				}

				angular.forEach($scope.user.currentCommits, function(currentCommit){
					GithubAPI.getCommit($scope.user.username, $scope.user.currentRepo,
										 currentCommit.commit).then(function(commitInfo){

					if(commitInfo.hasOwnProperty("files") &&
						commitInfo.files.length > 0){

						// grab first file in commit and retrieve DB host_id
						var filename = $scope.user.currentRepo + '/' + commitInfo.files[0].filename;

						$scope.dbClient.history(filename, function(error, revisions){
							var hostID;
							if(error){
								currentCommit.hostID = error.responseText;
							}
							else if(revisions && revisions.length > 0){
								for(var i = 0; i < revisions.length; i++){
									var revisionDate = revisions[i].modifiedAt;
									if(revisionDate <= new Date(currentCommit.timestamp) &&
										revisionDate >= new Date(currentCommit.previousCommitDate)){
											currentCommit.hostId = revisions[i]["host_id"];
											break;
										}
								}
							}
							else{
								hostId = "Unable to retrieve revision history for commit";
							}
						});
					}
					});

				});
			}
		});
    }

	$scope.saveToDropboxClick = function(){

		if(!$scope.dbClient){
			$scope.dbClient = new Dropbox.Client({ key: '4nl4o8v9y9wqv1i' });
		}

		if(!$scope.dbClient.isAuthenticated()){
			$scope.dbClient.authDriver(new Dropbox.AuthDriver.Popup({ receiverUrl:  'https://ronlaflamme.github.io/sv/oauth_receiver.html' }));
			$scope.dbClient.authenticate(function(authError){
			if(authError || !$scope.dbClient.isAuthenticated()){
				alert("Cannot login to Dropbox!");
			}});
		}

		if($scope.dbClient.isAuthenticated()){
			var filename = $scope.dbFilename ? $scope.dbFilename : Date() + ".log";
			filename = filename.replace(/:/g, "_").replace(/Z/g, "");
			$scope.dbClient.writeFile("sv_log/" + filename,
				JSON.stringify($scope.user.currentCommits),
				function(error, stat) {
				if (error) {
					alert(error);
				}
				else{
					alert("File saved");
				}
			});
		}
	};
  });
<|endoftext|>


<commit_before>/* jshint -W079 */
/* Related to https://github.com/linnovate/mean/issues/898 */
'use strict';

/**
 * Module dependencies.
 */
var expect = require('expect.js'),
        mongoose = require('mongoose'),
        Project = mongoose.model('Project'),
        Organisation = mongoose.model('Organisation');

var project;
var organisation;

describe('<Unit Test>', function () {
    describe('Model Project:', function () {
        beforeEach(function (done) {
            this.timeout(10000);
            organisation = new Organisation({
                "name": "Humanrights org",
                "representative": "Representative",
                "address": "Adress 123",
                "tel": "123445",
                "email": "email@org.com",
                "website": "www.org.com"});
            project = new Project({"title": "Human rights",
                "coordinator": "Keijo Koordinaattori",
                "organisation": organisation,
                "status": "approved",
                "reg_date": "12.10.2014",
                "funding": {
                    "applied_curr_local": "50 000",
                    "applied_curr_eur": "10 000",
                    "granted_curr_local": "50 000",
                    "granted_curr_eur": "10 000"},
                "duration_months": 30,
                "description": "A short description of project"},
            {"title": "Humans",
                "coordinator": "Keijo Koordi",
                "organisation": organisation,
                "status": "approved",
                "reg_date": "12.9.2014",
                "funding": {
                    "applied_curr_local": "50 000",
                    "applied_curr_eur": "11 000",
                    "granted_curr_local": "50 000",
                    "granted_curr_eur": "11 000"},
                "duration_months": 12,
                "description": "A short description of project"});
            project.save();
            done();
        });

        describe('Method All', function () {

            it('should list all projects', function (done) {
                this.timeout(10000);
                var query = Project
                return query.find(function (err, data) {
                    expect(err).to.be(null);
                    expect(data.length).to.be(2);
//                    expect(data[0].title).to.equal("Human rights");
//                    expect(data[1].project_info.status).to.be("approved");
                    done();
                });

            });
        });

//        describe('Method Show', function () {
//
//            it('should find given project', function (done) {
//                this.timeout(10000);
//                var query = Project;
//                return query.find
//            });
//        });

        afterEach(function (done) {
            this.timeout(10000);
            project = null;
            done();
        });
    });
});
<commit_msg>fixed projects back-end tests<commit_after>/* jshint -W079 */
/* Related to https://github.com/linnovate/mean/issues/898 */
'use strict';

/**
 * Module dependencies.
 */
var expect = require('expect.js'),
        mongoose = require('mongoose'),
        Project = mongoose.model('Project'),
        Organisation = mongoose.model('Organisation');

var project1;
var project2;
var project;
var organisation;

describe('<Unit Test>', function () {
    describe('Model Project:', function () {
        beforeEach(function (done) {
            this.timeout(10000);

            organisation = new Organisation({
                "name": "Humanrights org",
                "representative": "Representative",
                "address": "Adress 123",
                "tel": "123445",
                "email": "email@org.com",
                "website": "www.org.com"});
            project1 = new Project(
                    {"title": "Human rights",
                        "coordinator": "Keijo Koordinaattori",
                        "organisation": organisation,
                        "status": "approved",
                        "reg_date": "12.10.2014",
                        "funding": {
                            "applied_curr_local": "50 000",
                            "applied_curr_eur": "10 000",
                            "granted_curr_local": "50 000",
                            "granted_curr_eur": "10 000"},
                        "duration_months": 30,
                        "description": "A short description of project"});
            project1.save();
            project2 = new Project(
                    {"title": "Humans",
                        "coordinator": "Keijo Koordi",
                        "organisation": organisation,
                        "status": "approved",
                        "reg_date": "12.9.2014",
                        "funding": {
                            "applied_curr_local": "50 000",
                            "applied_curr_eur": "11 000",
                            "granted_curr_local": "50 000",
                            "granted_curr_eur": "11 000"},
                        "duration_months": 12,
                        "description": "A short description of project"});
            project2.save();
            done();
        });

        describe('Method All', function () {

            it('should list all projects', function (done) {

                this.timeout(10000);
                var query = Project
                return query.find(function (err, data) {
                    console.log(data);
                    expect(err).to.be(null);
                    expect(data.length).to.be(2);
//                    expect(data[0].title).to.equal("Human rights");
//                    expect(data[1].project_info.status).to.be("approved");
                    done();
                });

            });
        });

        describe('Method Show', function () {

            it('should find given project', function (done) {
                this.timeout(10000);
                var query = Project;
                return query.findOne(function (err, data) {
                    expect(err).to.be(null);
                    expect(data.title).to.be('Human rights');
                    done();
                });
            });
        });

        afterEach(function (done) {
            this.timeout(10000);
            project1.remove();
            project2.remove();
            done();
        });
    });
});
<|endoftext|>


<commit_before>angular.module( 'ripplecharts.validator', [
  'ui.state',
  'ui.bootstrap',
  'ui.route'
])

.config(function config( $stateProvider ) {
  $stateProvider
  .state('validator', {
    url: '/validators/:pubkey',
    views: {
      "main": {
        controller: 'ValidatorCtrl',
        templateUrl: 'validators/validator.tpl.html'
      }
    },
    data:{ pageTitle: 'Rippled Validator' }
  });
})

.controller('ValidatorCtrl', function ValidatorCtrl( $scope, $state, $location) {
  var apiHandler = new ApiHandler(API);

  $scope.reports = [];
  $scope.loading = true;
  $scope.status = 'Loading...';

  $scope.validator = {
    pubkey: $state.params.pubkey
  };

  apiHandler.getValidator($scope.validator.pubkey, function(err, validator) {
    if (err) {
      console.log('err');

    } else {
      $scope.validator.domain = validator.domain;
      $scope.validator.domain_state = validator.domain_state;
      $scope.$apply();
    }
  });

  apiHandler.getValidatorReports({
    pubkey: $scope.validator.pubkey
  }, function(err, reports) {
    $scope.loading = false;
    $scope.status = err || '';

    if (err) {
      console.log(err);
    }

    if (reports && reports.length) {
      reports.forEach(function(v) {
        v.date = moment.utc(v.date)
        .format('dddd, MMMM D YYYY');
        var disagreement = v.total_ledgers - v.main_net_ledgers;
        disagreement /= v.total_ledgers;
        v.main_net_disagreement = disagreement.toFixed(5);
      });
    }

    $scope.reports = reports;
    $scope.$apply();
  });
});
<commit_msg>fix bug with missing pubkey<commit_after>'use strict'

angular.module('ripplecharts.validator', [
  'ui.state',
  'ui.bootstrap',
  'ui.route'
])

.config(function config($stateProvider) {
  $stateProvider
  .state('validator', {
    url: '/validators/:pubkey',
    views: {
      main: {
        controller: 'ValidatorCtrl',
        templateUrl: 'validators/validator.tpl.html'
      }
    },
    data: {pageTitle: 'Rippled Validator'}
  })
})

.controller('ValidatorCtrl', function ValidatorCtrl($scope, $state) {

  if (!$state.params.pubkey) {
    $state.transitionTo('validators')
    return
  }

  var apiHandler = new ApiHandler(API)

  $scope.reports = []
  $scope.loading = true
  $scope.status = 'Loading...'

  $scope.validator = {
    pubkey: $state.params.pubkey
  }

  apiHandler.getValidator($scope.validator.pubkey, function(err, validator) {
    if (err) {
      console.log('err')

    } else {
      $scope.validator.domain = validator.domain
      $scope.validator.domain_state = validator.domain_state
      $scope.$apply()
    }
  })

  apiHandler.getValidatorReports({
    pubkey: $scope.validator.pubkey
  }, function(err, reports) {
    $scope.loading = false
    $scope.status = err || ''

    if (err) {
      console.log(err)
    }

    if (reports && reports.length) {
      reports.forEach(function(v) {
        v.date = moment.utc(v.date)
        .format('dddd, MMMM D YYYY')
        var disagreement = v.total_ledgers - v.main_net_ledgers
        disagreement /= v.total_ledgers
        v.main_net_disagreement = disagreement.toFixed(5)
      })
    }

    $scope.reports = reports
    $scope.$apply()
  })
})
<|endoftext|>


<commit_before>/**
 * authors: Björn Friedrichs, Andreas Bresser
 */

PIXI_UI.ScrollBar = function(scrollArea, theme) {
    this.scrollArea = scrollArea;
    this.skinName = this.skinName || PIXI_UI.ScrollBar.SKIN_NAME;
    this.mode = PIXI_UI.ScrollBar.DESKTOP_MODE;

    if (this.orientation === undefined) {
        this.orientation = PIXI_UI.ScrollBar.HORIZONTAL;
        if (scrollArea && scrollArea.content &&
            scrollArea.content.layout.alignment ===
                PIXI_UI.LayoutAlignment.VERTICAL_ALIGNMENT) {
            this.orientation = PIXI_UI.ScrollBar.VERTICAL;
        }
    }

    PIXI_UI.Skinable.call(this, theme);

    this.thumb = new PIXI_UI.ScrollThumb(this.orientation, theme);
    this.thumb.width = 20;
    this.thumb.height = 20;
    this.addChild(this.thumb);

    var scope = this;
    var down = this.thumb.mousedown;
    this.thumb.touchstart = this.thumb.mousedown = function (mouseData) {
        scope.handleDown(mouseData);
        down(mouseData);
    };
    this.thumb.touchmove = this.thumb.mousemove = function (mouseData) {
        scope.handleMove(mouseData);
    };
    var up = this.thumb.mouseup;
    this.thumb.touchend = this.thumb.touchendoutside =
        /* jshint unused: false */
        this.thumb.mouseup = this.thumb.mouseupoutside = function (mouseData) {
        scope.handleUp();
        up();
    };
    /*
    this.on('mousewheel', this.handleWheel, this);
    */

    this.invalidTrack = true;
    this._start = null;

    // # of pixel you scroll at a time (if the event delta is 1 / -1)
    this.scrolldelta = 10;

    this.thumb.touchmove = this.thumb.mousemove;
};

PIXI_UI.ScrollBar.prototype = Object.create( PIXI_UI.Skinable.prototype );
PIXI_UI.ScrollBar.prototype.constructor = PIXI_UI.ScrollBar;

PIXI_UI.ScrollBar.SKIN_NAME = 'scroll_bar';

PIXI_UI.ScrollBar.DESKTOP_MODE = 'desktop';
PIXI_UI.ScrollBar.MOBILE_MODE = 'mobile';

PIXI_UI.ScrollBar.HORIZONTAL = 'horizontal';
PIXI_UI.ScrollBar.VERTICAL = 'vertical';

PIXI_UI.ScrollBar.prototype.handleMove = function(mouseData) {
    if (this._start) {
        var local = mouseData.getLocalPosition(this);
        var x = this.thumb.x + local.x - this._start[0];
        var y = this.thumb.y + local.y - this._start[1];
        if (this.moveThumb(x, y)) {
            // do not override localX/localY in start
            // if we do not move the thumb
            this.scrollContent(x, y);
            this._start[0] = local.x;
            this._start[1] = local.y;
        }
    }
};

PIXI_UI.ScrollBar.prototype.handleDown = function(mouseData) {
    var local = mouseData.getLocalPosition(this);
    this._start = [local.x, local.y];
};
PIXI_UI.ScrollBar.prototype.handleUp = function() {
    this._start = null;
};

/**
 * scroll content to position
 */
PIXI_UI.ScrollBar.prototype.scrollContent = function(x, y) {
    if (this.scrollArea && this.scrollArea.content) {
        if (this.orientation === PIXI_UI.ScrollBar.HORIZONTAL) {
            this.scrollArea._scrollContent(
                -(this.scrollArea.content.width - this.scrollArea.width) *
                    (x / (this.scrollArea.width - this.thumb.width)),
                0);
        } else {
            this.scrollArea._scrollContent(
                0,
                -(this.scrollArea.content.height - this.scrollArea.height) *
                    (y / (this.scrollArea.height - this.thumb.height)));
        }
    }
};

PIXI_UI.ScrollBar.prototype.handleWheel = function (event) {
    var x = this.thumb.x - event.delta * this.scrolldelta;
    var y = this.thumb.y - event.delta * this.scrolldelta;
    if (this.moveThumb(x, y)) {
        this.scrollContent(x, y);
    }
};

/**
 * move the thumb on the scroll bar within its bounds
 * @param x new calculated x position of the thumb
 * @param y new calculated y position of the thumb
 * @returns {boolean} returns true if the position of the thumb has been
 * moved
 */
PIXI_UI.ScrollBar.prototype.moveThumb = function(x, y) {
    if(this.orientation === PIXI_UI.ScrollBar.HORIZONTAL) {
        x = Math.min(x, this.width - this.thumb.width);
        x = Math.max(x, 0);
        if (x !== this.thumb.x) {
            if (this.progressSkin) {
                this.progressSkin.width = x;
                this.progressSkin.height = this.skin.height;
            }
            this.thumb.x = x;
            return true;
        }
    } else {
        y = Math.min(y, this.height - this.thumb.height);
        y = Math.max(y, 0);
        if (y !== this.thumb.y) {
            this.thumb.y = y;
            if (this.progressSkin) {
                this.progressSkin.height = y;
                this.progressSkin.width = this.skin.width;
            }
            return true;
        }
    }
    return false;
};

PIXI_UI.ScrollBar.prototype.showTrack = function(skin) {
    if (this.skin !== skin) {
        if(this.skin) {
            this.removeChild(this.skin);
        }

        this.addChildAt(skin, 0);
        this.skin = skin;
    }
};

PIXI_UI.ScrollBar.prototype.showProgress = function(skin) {
    if (this.progressSkin !== skin) {
        if(this.progressSkin) {
            this.removeChild(this.progressSkin);
        }
        skin.width = skin.height = 0;
        this.addChildAt(skin, 1);
        this.progressSkin = skin;
    }
};

PIXI_UI.ScrollBar.prototype.redraw = function() {
    if (this.invalidTrack && this.thumb) {
        this.fromSkin('horizontal_progress', this.showProgress);
        this.fromSkin(this.orientation+'_track', this.showTrack);
        if (this.scrollArea && this.thumb) {
            if (this.orientation === PIXI_UI.ScrollBar.HORIZONTAL) {
                this.thumb.width = Math.max(20, this.scrollArea.width / (this.scrollArea.content.width / this.scrollArea.width));
            } else {
                this.thumb.height = Math.max(20, this.scrollArea.height / (this.scrollArea.content.height / this.scrollArea.height));
            }
        }
        if (this.skin) {
            if (this.orientation === PIXI_UI.ScrollBar.HORIZONTAL) {
                this.skin.width = this.width;
            } else {
                this.skin.height = this.height;
            }
            this.invalidTrack = false;
        }
    }
};

/**
 * The width of the ScrollBar, setting this will redraw the track and thumb.
 * (set invalidDimensions)
 *
 * @property width
 * @type Number
 */
Object.defineProperty(PIXI_UI.ScrollBar.prototype, 'width', {
    get: function() {
        return this._width;
    },
    set: function(width) {
        this._width = width;
        this.invalidTrack = true;
        if (this.thumb) {
            this.thumb.invalidTrack = true;
        }
    }
});

/**
 * The height of the ScrollBar, setting this will redraw the track and thumb.
 * (set invalidDimensions)
 *
 * @property height
 * @type Number
 */
Object.defineProperty(PIXI_UI.ScrollBar.prototype, 'height', {
    get: function() {
        return this._height;
    },
    set: function(height) {
        this._height = height;
        this.invalidTrack = true;
        if (this.thumb) {
            this.thumb.invalidTrack = true;
        }
    }
});
<commit_msg>allow scrollbar to be used as inverse progress bar<commit_after>/**
 * authors: Björn Friedrichs, Andreas Bresser
 */

PIXI_UI.ScrollBar = function(scrollArea, theme) {
    this.scrollArea = scrollArea;
    this.skinName = this.skinName || PIXI_UI.ScrollBar.SKIN_NAME;
    this.mode = PIXI_UI.ScrollBar.DESKTOP_MODE;

    if (this.orientation === undefined) {
        this.orientation = PIXI_UI.ScrollBar.HORIZONTAL;
        if (scrollArea && scrollArea.content &&
            scrollArea.content.layout.alignment ===
                PIXI_UI.LayoutAlignment.VERTICAL_ALIGNMENT) {
            this.orientation = PIXI_UI.ScrollBar.VERTICAL;
        }
    }

    PIXI_UI.Skinable.call(this, theme);

    this.thumb = new PIXI_UI.ScrollThumb(this.orientation, theme);
    this.thumb.width = 20;
    this.thumb.height = 20;
    this.addChild(this.thumb);

    var scope = this;
    var down = this.thumb.mousedown;
    this.thumb.touchstart = this.thumb.mousedown = function (mouseData) {
        scope.handleDown(mouseData);
        down(mouseData);
    };
    this.thumb.touchmove = this.thumb.mousemove = function (mouseData) {
        scope.handleMove(mouseData);
    };
    var up = this.thumb.mouseup;
    this.thumb.touchend = this.thumb.touchendoutside =
        /* jshint unused: false */
        this.thumb.mouseup = this.thumb.mouseupoutside = function (mouseData) {
        scope.handleUp();
        up();
    };
    /*
    this.on('mousewheel', this.handleWheel, this);
    */

    this.invalidTrack = true;
    this._inverse = false;
    this._start = null;

    // # of pixel you scroll at a time (if the event delta is 1 / -1)
    this.scrolldelta = 10;

    this.thumb.touchmove = this.thumb.mousemove;
};

PIXI_UI.ScrollBar.prototype = Object.create( PIXI_UI.Skinable.prototype );
PIXI_UI.ScrollBar.prototype.constructor = PIXI_UI.ScrollBar;

PIXI_UI.ScrollBar.SKIN_NAME = 'scroll_bar';

PIXI_UI.ScrollBar.DESKTOP_MODE = 'desktop';
PIXI_UI.ScrollBar.MOBILE_MODE = 'mobile';

PIXI_UI.ScrollBar.HORIZONTAL = 'horizontal';
PIXI_UI.ScrollBar.VERTICAL = 'vertical';

PIXI_UI.ScrollBar.prototype.handleMove = function(mouseData) {
    if (this._start) {
        var local = mouseData.getLocalPosition(this);
        var x = this.thumb.x + local.x - this._start[0];
        var y = this.thumb.y + local.y - this._start[1];
        if (this.moveThumb(x, y)) {
            // do not override localX/localY in start
            // if we do not move the thumb
            this.scrollContent(x, y);
            this._start[0] = local.x;
            this._start[1] = local.y;
        }
    }
};

PIXI_UI.ScrollBar.prototype.handleDown = function(mouseData) {
    var local = mouseData.getLocalPosition(this);
    this._start = [local.x, local.y];
};
PIXI_UI.ScrollBar.prototype.handleUp = function() {
    this._start = null;
};

/**
 * scroll content to position
 */
PIXI_UI.ScrollBar.prototype.scrollContent = function(x, y) {
    if (this.scrollArea && this.scrollArea.content) {
        if (this.orientation === PIXI_UI.ScrollBar.HORIZONTAL) {
            this.scrollArea._scrollContent(
                -(this.scrollArea.content.width - this.scrollArea.width) *
                    (x / (this.scrollArea.width - this.thumb.width)),
                0);
        } else {
            this.scrollArea._scrollContent(
                0,
                -(this.scrollArea.content.height - this.scrollArea.height) *
                    (y / (this.scrollArea.height - this.thumb.height)));
        }
    }
};

PIXI_UI.ScrollBar.prototype.handleWheel = function (event) {
    var x = this.thumb.x - event.delta * this.scrolldelta;
    var y = this.thumb.y - event.delta * this.scrolldelta;
    if (this.moveThumb(x, y)) {
        this.scrollContent(x, y);
    }
};

PIXI_UI.ScrollBar.prototype._updateProgressSkin = function() {
    if (!this.progressSkin) {
        return;
    }
    if(this.orientation === PIXI_UI.ScrollBar.HORIZONTAL) {
        if (this.inverse) {
            this.progressSkin.x = this.thumb.x + this.thumb.width / 2;
            this.progressSkin.width = this.width - this.thumb.x;
            this.progressSkin.height = this.skin.height;
        } else {
            this.progressSkin.width = this.thumb.x + this.thumb.width / 2;
            this.progressSkin.height = this.skin.height;
        }
    } else {
        if (this.inverse) {
            this.progressSkin.y = this.thumb.y + this.thumb.height / 2;
            this.progressSkin.height = this.height - this.thumb.y;
            this.progressSkin.width = this.skin.width;
        } else {
            this.progressSkin.height = this.thumb.y + this.thumb.height / 2;
            this.progressSkin.width = this.skin.width;
        }
    }
};

/**
 * move the thumb on the scroll bar within its bounds
 * @param x new calculated x position of the thumb
 * @param y new calculated y position of the thumb
 * @returns {boolean} returns true if the position of the thumb has been
 * moved
 */
PIXI_UI.ScrollBar.prototype.moveThumb = function(x, y) {
    if(this.orientation === PIXI_UI.ScrollBar.HORIZONTAL) {
        x = Math.min(x, this.width - this.thumb.width);
        x = Math.max(x, 0);
        if (x !== this.thumb.x) {
            this.thumb.x = x;
            this._updateProgressSkin();
            return true;
        }
    } else {
        y = Math.min(y, this.height - this.thumb.height);
        y = Math.max(y, 0);
        if (y !== this.thumb.y) {
            this.thumb.y = y;
            this._updateProgressSkin();
            return true;
        }
    }
    return false;
};

PIXI_UI.ScrollBar.prototype.showTrack = function(skin) {
    if (this.skin !== skin) {
        if(this.skin) {
            this.removeChild(this.skin);
        }

        this.addChildAt(skin, 0);
        this.skin = skin;
        if (this.progressSkin) {
            this._updateProgressSkin();
        }
    }
};

PIXI_UI.ScrollBar.prototype.showProgress = function(skin) {
    if (this.progressSkin !== skin) {
        if(this.progressSkin) {
            this.removeChild(this.progressSkin);
        }
        skin.width = skin.height = 0;
        this.addChildAt(skin, 0);
        this.progressSkin = skin;
        if (this.skin) {
            this._updateProgressSkin();
        }
    }
};

PIXI_UI.ScrollBar.prototype.redraw = function() {
    if (this.invalidTrack && this.thumb) {
        this.fromSkin(this.orientation+'_progress', this.showProgress);
        this.fromSkin(this.orientation+'_track', this.showTrack);
        if (this.scrollArea && this.thumb) {
            if (this.orientation === PIXI_UI.ScrollBar.HORIZONTAL) {
                this.thumb.width = Math.max(20, this.scrollArea.width / (this.scrollArea.content.width / this.scrollArea.width));
            } else {
                this.thumb.height = Math.max(20, this.scrollArea.height / (this.scrollArea.content.height / this.scrollArea.height));
            }
        }
        if (this.skin) {
            if (this.orientation === PIXI_UI.ScrollBar.HORIZONTAL) {
                this.skin.width = this.width;
            } else {
                this.skin.height = this.height;
            }
            this.invalidTrack = false;
        }
    }
};

/**
 * The width of the ScrollBar, setting this will redraw the track and thumb.
 * (set invalidDimensions)
 *
 * @property width
 * @type Number
 */
Object.defineProperty(PIXI_UI.ScrollBar.prototype, 'width', {
    get: function() {
        return this._width;
    },
    set: function(width) {
        this._width = width;
        this.invalidTrack = true;
        if (this.thumb) {
            this.thumb.invalidTrack = true;
        }
    }
});

/**
 * Inverse the progress bar
 *
 * @property inverse
 * @type Boolean
 */
Object.defineProperty(PIXI_UI.ScrollBar.prototype, 'inverse', {
    get: function() {
        return this._inverse;
    },
    set: function(inverse) {
        if (inverse !== this._inverse) {
            this._inverse = inverse;

            if (this.orientation === PIXI_UI.ScrollBar.HORIZONTAL) {
                this.moveThumb(0, this.width - this.thumb.x);
            } else {
                this.moveThumb(0, this.height - this.thumb.y);
            }

            this.invalidTrack = true;
            if (this.thumb) {
                this.thumb.invalidTrack = true;
            }
        }
    }
});

/**
 * The height of the ScrollBar, setting this will redraw the track and thumb.
 * (set invalidDimensions)
 *
 * @property height
 * @type Number
 */
Object.defineProperty(PIXI_UI.ScrollBar.prototype, 'height', {
    get: function() {
        return this._height;
    },
    set: function(height) {
        this._height = height;
        this.invalidTrack = true;
        if (this.thumb) {
            this.thumb.invalidTrack = true;
        }
    }
});
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc overview
 * @name loopbackApp
 * @description
 * # loopbackApp
 *
 * Main module of the application.
 */
angular.module('loopbackApp', [
  'angular.filter',
  'angularBootstrapNavTree',
  'angularFileUpload',
  'oitozero.ngSweetAlert',
  'config',
  'formly',
  'lbServices',
  'ngAnimate',
  'ngCookies',
  'ngResource',
  'ngRoute',
  'ngSanitize',
  'ngTouch',
  'ui.bootstrap',
  'ui.gravatar',
  'ui.markdown',
  'ui.router',
  'toasty'
])

  .controller('LayoutCtrl', function ($scope, Setting, ENV) {

    $scope.appName = 'LB-NG-BS';
    $scope.apiUrl = ENV.apiUrl;
    $scope.appTheme = 'skin-blue';
    $scope.appThemes = [
      {
        'name': 'Black',
        'class': 'skin-black'
      },
      {
        'name': 'Blue',
        'class': 'skin-blue'
      }
    ];
    $scope.appLayout = '';
    $scope.appLayouts = [
      {
        'name': 'Fixed',
        'class': 'fixed'
      },
      {
        'name': 'Scrolling',
        'class': 'not-fixed'
      }
    ];

    $scope.setTheme = function (theme) {
      $scope.appTheme = theme;
    };

    $scope.setLayout = function (layout) {
      $scope.appLayout = layout;
    };

    $scope.toggleSidebar = function () {
      var $ = angular.element;
      if ($(window).width() <= 992) {
        $('.row-offcanvas').toggleClass('active');
        $('.left-side').removeClass('collapse-left');
        $('.right-side').removeClass('strech');
        $('.row-offcanvas').toggleClass('relative');
      } else {
        // Else, enable content streching
        $('.left-side').toggleClass('collapse-left');
        $('.right-side').toggleClass('strech');
      }
    };

    $scope.settings = {};

    Setting.find(function (settings) {
      settings.forEach(function (item) {
        $scope.settings[item.key] = item.value;
      });
    });

  })

  .config(function ($stateProvider, $urlRouterProvider) {

    $stateProvider.state('login', {
      url: '/login',
      template: '<login></login>',
      controller: 'LoginCtrl'
    }).state('register', {
      url: '/register',
      template: '<register></register>',
      controller: 'LoginCtrl'
    });

    $urlRouterProvider.otherwise('/app');

  })

  .config(function ($routeProvider, $httpProvider) {

    // Intercept 401 responses and redirect to login screen
    $httpProvider.interceptors.push(function ($q, $location, AppAuth, toasty) {
      return {
        responseError: function (rejection) {

          if (rejection.status === 401) {
            AppAuth.currentUser = null;
            // save the current location so that login can redirect back
            $location.nextAfterLogin = $location.path();

            if ($location.path() !== '/register') {
              $location.path('/login');
            }

            toasty.pop.warning({title: 'Error 401 received', msg: 'We received a 401 error from the API! Redirecting to login', sound: false});
          }
          if (rejection.status === 0) {
            $location.path('/');
            toasty.pop.error({title: 'Connection Refused', msg: 'The connection to the API is refused. Please verify that the API is running!', sound: false});
          }
          return $q.reject(rejection);
        }
      };
    });
  }).config(function(formlyConfigProvider){
    var templates = 'views/elements/fields/';
    var formly = templates + 'formly-field-';
    var fields = ['checkbox', 'email', 'hidden', 'number', 'password', 'radio', 'select', 'text', 'textarea'];

    angular.forEach(fields, function(val){
      formlyConfigProvider.setTemplateUrl(val, formly+val+'.html');
    });

    formlyConfigProvider.setTemplateUrl('date', templates + 'date.html');
    formlyConfigProvider.setTemplateUrl('time', templates + 'time.html');

  });
<commit_msg>Catch 404 errors<commit_after>'use strict';

/**
 * @ngdoc overview
 * @name loopbackApp
 * @description
 * # loopbackApp
 *
 * Main module of the application.
 */
angular.module('loopbackApp', [
  'angular.filter',
  'angularBootstrapNavTree',
  'angularFileUpload',
  'oitozero.ngSweetAlert',
  'config',
  'formly',
  'lbServices',
  'ngAnimate',
  'ngCookies',
  'ngResource',
  'ngRoute',
  'ngSanitize',
  'ngTouch',
  'ui.bootstrap',
  'ui.gravatar',
  'ui.markdown',
  'ui.router',
  'toasty'
])

  .controller('LayoutCtrl', function ($scope, Setting, ENV) {

    $scope.appName = 'LB-NG-BS';
    $scope.apiUrl = ENV.apiUrl;
    $scope.appTheme = 'skin-blue';
    $scope.appThemes = [
      {
        'name': 'Black',
        'class': 'skin-black'
      },
      {
        'name': 'Blue',
        'class': 'skin-blue'
      }
    ];
    $scope.appLayout = '';
    $scope.appLayouts = [
      {
        'name': 'Fixed',
        'class': 'fixed'
      },
      {
        'name': 'Scrolling',
        'class': 'not-fixed'
      }
    ];

    $scope.setTheme = function (theme) {
      $scope.appTheme = theme;
    };

    $scope.setLayout = function (layout) {
      $scope.appLayout = layout;
    };

    $scope.toggleSidebar = function () {
      var $ = angular.element;
      if ($(window).width() <= 992) {
        $('.row-offcanvas').toggleClass('active');
        $('.left-side').removeClass('collapse-left');
        $('.right-side').removeClass('strech');
        $('.row-offcanvas').toggleClass('relative');
      } else {
        // Else, enable content streching
        $('.left-side').toggleClass('collapse-left');
        $('.right-side').toggleClass('strech');
      }
    };

    $scope.settings = {};

    Setting.find(function (settings) {
      settings.forEach(function (item) {
        $scope.settings[item.key] = item.value;
      });
    });

  })

  .config(function ($stateProvider, $urlRouterProvider) {

    $stateProvider.state('login', {
      url: '/login',
      template: '<login></login>',
      controller: 'LoginCtrl'
    }).state('register', {
      url: '/register',
      template: '<register></register>',
      controller: 'LoginCtrl'
    });

    $urlRouterProvider.otherwise('/app');

  })

  .config(function ($routeProvider, $httpProvider) {

    // Intercept 401 responses and redirect to login screen
    $httpProvider.interceptors.push(function ($q, $location, AppAuth, toasty) {
      return {
        responseError: function (rejection) {

          if (rejection.status === 401) {
            AppAuth.currentUser = null;
            // save the current location so that login can redirect back
            $location.nextAfterLogin = $location.path();

            if ($location.path() !== '/register') {
              $location.path('/login');
            }

            toasty.pop.warning({title: 'Error 401 received', msg: 'We received a 401 error from the API! Redirecting to login', sound: false});
          }
          if (rejection.status === 404) {
            console.log(rejection);
            toasty.pop.error({title: 'Error 404 received', msg: rejection.data.error.message, sound: false});
          }
          if (rejection.status === 0) {
            $location.path('/');
            toasty.pop.error({title: 'Connection Refused', msg: 'The connection to the API is refused. Please verify that the API is running!', sound: false});
          }
          return $q.reject(rejection);
        }
      };
    });
  }).config(function(formlyConfigProvider){
    var templates = 'views/elements/fields/';
    var formly = templates + 'formly-field-';
    var fields = ['checkbox', 'email', 'hidden', 'number', 'password', 'radio', 'select', 'text', 'textarea'];

    angular.forEach(fields, function(val){
      formlyConfigProvider.setTemplateUrl(val, formly+val+'.html');
    });

    formlyConfigProvider.setTemplateUrl('date', templates + 'date.html');
    formlyConfigProvider.setTemplateUrl('time', templates + 'time.html');

  });
<|endoftext|>