<commit_before>var request = require('request');
var fs = require('fs');
var _ = require('underscore');
var q = require('q');
/*
 * grunt-jenkins
 * https://github.com/sghill/grunt-jenkins
 *
 * Copyright (c) 2012 sghill
 * Licensed under the MIT license.
 */

module.exports = function(grunt) {

  var SERVER = 'http://192.168.241.137';
  var PIPELINE_DIRECTORY = 'pipeline';

  function logJobName(job) {
    grunt.log.writeln(job.name);
  }

  function logError(e) {
    grunt.log.error(e);
  }

  function isLast(item, collection) {
    return _.isEqual(item, _.last(collection));
  }

  function withDot(filename) {
    return /\./.test(filename);
  }

  function fetchDirectoriesOf(directory) {
    var deferred = q.defer();
    fs.readdir(directory, function(e, contents) {
      if(e) { deferred.reject(e); }
      // assumption: we don't have periods in our job names
      var directories = _.reject(contents, withDot);
      deferred.resolve(directories);
    });
    return deferred.promise;
  }

  function fetchJobConfigurationStrategy(job) {
    var deferred = q.defer();
    var url = [SERVER, 'job', job, 'config.xml'].join('/');
    request(url, function(e, r, b) {
      var strategy = r.statusCode === 200 ? 'update' : 'create';
      grunt.log.writeln(strategy + ': ' + job);
      deferred.resolve({strategy: strategy, jobName: job});
    });
    return deferred.promise;
  }

  function fetchFileContents (fileAndJob) {
    var deferred = q.defer();
    fs.readFile(fileAndJob.fileName, function(e, contents) {
      if(e) { deferred.reject(e); }
      deferred.resolve({fileContents: contents, jobName: fileAndJob.jobName });
    })
    return deferred.promise;
  }

  function createJob (config) {
    var deferred = q.defer();
    var options = {
      url: [SERVER, 'createItem'].join('/'),
      method: 'POST',
      qs: {
        name: config.jobName
      },
      headers: {
        'Content-Type': 'text/xml'
      },
      body: config.fileContents
    };

    request(options, function(e, r, b) {
      if(e) { deferred.reject(e); }
      deferred.resolve(r.statusCode === 200);
    })

    return deferred.promise;
  }

  function updateJob (config) {
    var deferred = q.defer(),
        options = {
      url: [SERVER, 'job', config.jobName, 'config.xml'].join('/'),
      method: 'POST',
      body: config.fileContents
    };

    request(options, function(e, r, b) {
      if(e) { deferred.reject(e); }
      deferred.resolve(r.statusCode === 200);
    });

    return deferred.promise;
  }

  function applyStrategy (strategyObj) {
    var deferred = q.defer(),
        filename = [PIPELINE_DIRECTORY, strategyObj.jobName, 'config.xml'].join('/'),
        fileStrategy = {fileName: filename, jobName: strategyObj.jobName};

    function resolve (val) {
      deferred.resolve(val);
    }

    if(strategyObj.strategy === 'create') {
      fetchFileContents(fileStrategy).
        then(createJob).
        then(resolve);
    } else if (strategyObj.strategy === 'update') {
      fetchFileContents(fileStrategy).
        then(updateJob).
        then(resolve);
    }

    return deferred.promise;
  }

  function createOrUpdateJobs(directories) {
    var deferred = q.defer();

    function resolve (val) {
      deferred.resolve(val);
    }

    _.each(directories, function(folder) {
      fetchJobConfigurationStrategy(folder).
        then(applyStrategy).
        then(resolve);
    });

    return deferred.promise;
  }

  function fetchPluginsFrom(directory) {
    var deferred = q.defer();
    fs.readFile([directory, 'plugins.json'].join('/'), function(e, contents) {
      if(e) { deferred.reject(e); }
      deferred.resolve(JSON.parse(contents));
    });
    return deferred.promise;
  }

  function transformToJenkinsXml(plugins) {
    var attributes = _.map(plugins, function(p) {
      return ['<install plugin="', p.id, '@', p.version, '" />'].join('');
    }).join('\n');
    return ['<jenkins>', attributes, '</jenkins>'].join('\n');
  }

  function installPlugins(xml) {
    var deferred = q.defer(),
        options = {
      url: [SERVER, 'pluginManager', 'installNecessaryPlugins'].join('/'),
      method: 'POST',
      body: xml
    };

    request(options, function(e, r, b) {
      if(e) { deferred.reject(e); }
      deferred.resolve(r.statusCode === 200);
    });

    return deferred.promise;
  }

  function fetchEnabledPluginsOf(server) {
    var url = [SERVER, 'pluginManager', 'api', 'json?depth=1'].join('/');
    var deferred = q.defer();

    request(url, function(e, r, body) {
      var result = _.filter(JSON.parse(body).plugins, function(p) { return p.enabled; });
      var plugins = _.map(result, function(p) { return { id: p.shortName, version: p.version }; });

      deferred.resolve(plugins);
    });

    return deferred.promise;
  }

  function writeFileToPipelineDirectory(plugins) {
    var deferred = q.defer();
    var filename = [PIPELINE_DIRECTORY, 'plugins.json'].join('/');
    var body = JSON.stringify(plugins, null, 2);
    fs.writeFile(filename, body, 'utf8', function(e) {
      if(e) { deferred.reject(e); }

      grunt.log.writeln('created file: ' + filename);
      deferred.resolve();
    });

    return deferred.promise;
  }

  // ==========================================================================
  // TASKS
  // ==========================================================================

  grunt.registerTask('jenkins-install-jobs', 'good mode', function() {
    var done = this.async();
    fetchDirectoriesOf(PIPELINE_DIRECTORY).
      then(createOrUpdateJobs).
      then(function() {
        done(true);
      }, logError).
      end();
  });

  grunt.registerTask('jenkins-install-plugins', 'good mode plugins', function() {
    var done = this.async();
    fetchPluginsFrom(PIPELINE_DIRECTORY).
      then(transformToJenkinsXml).
      then(installPlugins).
      then(function() { done(true); });
  });

  grunt.registerTask('jenkins-backup-configs', 'backup listed projects on jenkins server', function() {
    var done = this.async();
    request(SERVER + '/api/json', function(e, r, body) {
      var isSuccess = !e && r.statusCode === 200;
      if(isSuccess) {
        var jobs = JSON.parse(body).jobs;

        _.each(jobs, function(job) {
          var jobConfigurationUrl = [job.url, 'config.xml'].join('/');

          request(jobConfigurationUrl, function(e, r, body) {
            var directoryName = [PIPELINE_DIRECTORY, job.name].join('/');
            var filename = [PIPELINE_DIRECTORY, job.name, 'config.xml'].join('/');

            if(!fs.existsSync(PIPELINE_DIRECTORY)) {
              fs.mkdirSync(PIPELINE_DIRECTORY);
            }

            if(!fs.existsSync(directoryName)) {
              fs.mkdirSync(directoryName);
            }

            fs.writeFile(filename, body, 'utf8', function(err) {
              if(err) { throw err; }

              grunt.log.writeln('created file: ' + filename);
              if(isLast(job, jobs)) {
                done(isSuccess);
              }
            });

          });
        });

      }
    });
  });

  grunt.registerTask('jenkins-backup-plugins', 'backup the enabled plugins', function() {
    var done = this.async();
    fetchEnabledPluginsOf(SERVER).
      then(writeFileToPipelineDirectory).
      then(function(x) { done(true); });
  });

  grunt.registerTask('jenkins-list-projects', 'list projects on jenkins server', function() {
    var done = this.async();
    grunt.helper('getProjectNames', logJobName, done);
 });

  // ==========================================================================
  // HELPERS
  // ==========================================================================

  grunt.registerHelper('getProjectNames', function(callback, done) {
    request(SERVER + '/api/json', function(e, r, body) {
      var isSuccess = !e & r.statusCode === 200;
      if(isSuccess) {
        var jobs = JSON.parse(body).jobs;
        jobs.forEach(callback);
      }
      done(isSuccess);
    });
  });

};
<commit_msg>promises for job backup too<commit_after>var request = require('request');
var fs = require('fs');
var _ = require('underscore');
var q = require('q');
/*
 * grunt-jenkins
 * https://github.com/sghill/grunt-jenkins
 *
 * Copyright (c) 2012 sghill
 * Licensed under the MIT license.
 */

module.exports = function(grunt) {

  var SERVER = 'http://192.168.241.137';
  var PIPELINE_DIRECTORY = 'pipeline';

  function logError(e) {
    grunt.log.error(e);
  }

  function isLast(item, collection) {
    return _.isEqual(item, _.last(collection));
  }

  function withDot(filename) {
    return /\./.test(filename);
  }

  function loadJobsFromDisk() {
    var deferred = q.defer();
    fs.readdir(PIPELINE_DIRECTORY, function(e, contents) {
      if(e) { deferred.reject(e); }
      // assumption: we don't have periods in our job names
      var directories = _.reject(contents, withDot);
      deferred.resolve(directories);
    });
    return deferred.promise;
  }

  function fetchJobConfigurationStrategy(job) {
    var deferred = q.defer();
    var url = [SERVER, 'job', job, 'config.xml'].join('/');
    request(url, function(e, r, b) {
      var strategy = r.statusCode === 200 ? 'update' : 'create';
      grunt.log.writeln(strategy + ': ' + job);
      deferred.resolve({strategy: strategy, jobName: job});
    });
    return deferred.promise;
  }

  function fetchFileContents (fileAndJob) {
    var deferred = q.defer();
    fs.readFile(fileAndJob.fileName, function(e, contents) {
      if(e) { deferred.reject(e); }
      deferred.resolve({fileContents: contents, jobName: fileAndJob.jobName });
    })
    return deferred.promise;
  }

  function createJob (config) {
    var deferred = q.defer();
    var options = {
      url: [SERVER, 'createItem'].join('/'),
      method: 'POST',
      qs: {
        name: config.jobName
      },
      headers: {
        'Content-Type': 'text/xml'
      },
      body: config.fileContents
    };

    request(options, function(e, r, b) {
      if(e) { deferred.reject(e); }
      deferred.resolve(r.statusCode === 200);
    })

    return deferred.promise;
  }

  function updateJob (config) {
    var deferred = q.defer(),
        options = {
      url: [SERVER, 'job', config.jobName, 'config.xml'].join('/'),
      method: 'POST',
      body: config.fileContents
    };

    request(options, function(e, r, b) {
      if(e) { deferred.reject(e); }
      deferred.resolve(r.statusCode === 200);
    });

    return deferred.promise;
  }

  function applyStrategy (strategyObj) {
    var deferred = q.defer(),
        filename = [PIPELINE_DIRECTORY, strategyObj.jobName, 'config.xml'].join('/'),
        fileStrategy = {fileName: filename, jobName: strategyObj.jobName};

    function resolve (val) {
      deferred.resolve(val);
    }

    if(strategyObj.strategy === 'create') {
      fetchFileContents(fileStrategy).
        then(createJob).
        then(resolve);
    } else if (strategyObj.strategy === 'update') {
      fetchFileContents(fileStrategy).
        then(updateJob).
        then(resolve);
    }

    return deferred.promise;
  }

  function createOrUpdateJobs(directories) {
    var deferred = q.defer();

    function resolve (val) {
      deferred.resolve(val);
    }

    _.each(directories, function(folder) {
      fetchJobConfigurationStrategy(folder).
        then(applyStrategy).
        then(resolve);
    });

    return deferred.promise;
  }

  function loadPluginsFromDisk() {
    var deferred = q.defer();
    fs.readFile([PIPELINE_DIRECTORY, 'plugins.json'].join('/'), function(e, contents) {
      if(e) { deferred.reject(e); }
      deferred.resolve(JSON.parse(contents));
    });
    return deferred.promise;
  }

  function transformToJenkinsXml(plugins) {
    var attributes = _.map(plugins, function(p) {
      return ['<install plugin="', p.id, '@', p.version, '" />'].join('');
    }).join('\n');
    return ['<jenkins>', attributes, '</jenkins>'].join('\n');
  }

  function installPlugins(xml) {
    var deferred = q.defer(),
        options = {
          url: [SERVER, 'pluginManager', 'installNecessaryPlugins'].join('/'),
          method: 'POST',
          body: xml
        };

    request(options, function(e, r, b) {
      if(e) { deferred.reject(e); }
      deferred.resolve(r.statusCode === 200);
    });

    return deferred.promise;
  }

  function fetchEnabledPluginsFromServer() {
    var url = [SERVER, 'pluginManager', 'api', 'json?depth=1'].join('/');
    var deferred = q.defer();

    request(url, function(e, r, body) {
      var result = _.filter(JSON.parse(body).plugins, function(p) { return p.enabled; });
      var plugins = _.map(result, function(p) { return { id: p.shortName, version: p.version }; });

      deferred.resolve(plugins);
    });

    return deferred.promise;
  }

  function writeFileToPipelineDirectory(plugins) {
    var deferred = q.defer();
    var filename = [PIPELINE_DIRECTORY, 'plugins.json'].join('/');
    var body = JSON.stringify(plugins, null, 2);
    fs.writeFile(filename, body, 'utf8', function(e) {
      if(e) { deferred.reject(e); }

      grunt.log.writeln('created file: ' + filename);
      deferred.resolve();
    });

    return deferred.promise;
  }

  function fetchJobsFromServer() {
    var deferred = q.defer();
    var url = [SERVER, 'api', 'json'].join('/');

    request(url, function(e, r, body) {
      if(e) { deferred.reject(e); }
      var jobs = JSON.parse(body).jobs;
      deferred.resolve(_.map(jobs, function(j) { return { name: j.name, url: j.url }}));
    });

    return deferred.promise;
  }

  function fetchJobConfigurations(jobs) {
    var deferred = q.defer();
    var jobConfigurations = [];
    var errors = [];
    var responseCodes = [];
    _.each(jobs, function(j) {
      request([j.url, 'config.xml'].join(''), function(e, r, body) {
        errors.push(e);
        responseCodes.push(r.statusCode);
        j.config = body;
        jobConfigurations.push(j)
        if(isLast(j, jobs)) {
          if(_.any(errors, function(e) { return e; }) ||
             _.any(responseCodes, function(c) { return c !== 200; })) {
            deferred.reject();
          }
          deferred.resolve(jobConfigurations);
        }
      });
    });
    return deferred.promise;
  }

  function writeToJobDirectories(jobs) {
    var deferred = q.defer();
    _.each(jobs, function(j) {
      var directoryName = [PIPELINE_DIRECTORY, j.name].join('/');
      var filename = [directoryName, 'config.xml'].join('/');

      if(!fs.existsSync(PIPELINE_DIRECTORY)) {
        fs.mkdirSync(PIPELINE_DIRECTORY);
      }

      if(!fs.existsSync(directoryName)) {
        fs.mkdirSync(directoryName);
      }

      fs.writeFile(filename, j.config, 'utf8', function(e) {
        if(e) { deferred.reject(e); }
        if(isLast(j, jobs)) {
          deferred.resolve(jobs);
        }
      });
    });
    return deferred.promise;
  }

  // ==========================================================================
  // TASKS
  // ==========================================================================

  grunt.registerTask('jenkins-install-jobs', 'install all jobs', function() {
    var done = this.async();
    loadJobsFromDisk().
      then(createOrUpdateJobs).
      then(function() { done(true); }, logError);
  });

  grunt.registerTask('jenkins-install-plugins', 'install all plugins', function() {
    var done = this.async();
    loadPluginsFromDisk().
      then(transformToJenkinsXml).
      then(installPlugins).
      then(function() { done(true); }, logError);
  });

  grunt.registerTask('jenkins-backup-projects', 'backup all projects', function() {
    var done = this.async();
    fetchJobsFromServer().
      then(fetchJobConfigurations).
      then(writeToJobDirectories).
      then(function() { done(true); }, logError);
  });

  grunt.registerTask('jenkins-backup-plugins', 'backup all enabled plugins', function() {
    var done = this.async();
    fetchEnabledPluginsFromServer().
      then(writeFileToPipelineDirectory).
      then(function() { done(true); }, logError);
  });

};
<|endoftext|>


<commit_before>import Component from '@ember/component';

export default Component.extend({
  tagName: '',
});
<commit_msg>freestyle/DatetimePicker: Convert to Glimmer component<commit_after>import Component from '@glimmer/component';

export default class extends Component {
  takeoffTime = new Date();
}
<|endoftext|>


<commit_before>/**
 * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
 * @fileoverview Shape component
 */
import fabric from 'fabric/dist/fabric.require';
import Promise from 'core-js/library/es6/promise';
import Component from '../interface/component';
import consts from '../consts';
import resizeHelper from '../helper/shapeResizeHelper';
import {extend, inArray} from 'tui-code-snippet';

const {rejectMessages, eventNames} = consts;
const KEY_CODES = consts.keyCodes;

const DEFAULT_TYPE = 'rect';
const DEFAULT_OPTIONS = {
    strokeWidth: 1,
    stroke: '#000000',
    fill: '#ffffff',
    width: 1,
    height: 1,
    rx: 0,
    ry: 0,
    lockSkewingX: true,
    lockSkewingY: true,
    lockUniScaling: false,
    bringForward: true,
    isRegular: false
};

const shapeType = ['rect', 'circle', 'triangle'];

/**
 * Shape
 * @class Shape
 * @param {Graphics} graphics - Graphics instance
 * @extends {Component}
 * @ignore
 */
class Shape extends Component {
    constructor(graphics) {
        super(consts.componentNames.SHAPE, graphics);

        /**
         * Object of The drawing shape
         * @type {fabric.Object}
         * @private
         */
        this._shapeObj = null;

        /**
         * Type of the drawing shape
         * @type {string}
         * @private
         */
        this._type = DEFAULT_TYPE;

        /**
         * Options to draw the shape
         * @type {Object}
         * @private
         */
        this._options = extend({}, DEFAULT_OPTIONS);

        /**
         * Whether the shape object is selected or not
         * @type {boolean}
         * @private
         */
        this._isSelected = false;

        /**
         * Pointer for drawing shape (x, y)
         * @type {Object}
         * @private
         */
        this._startPoint = {};

        /**
         * Using shortcut on drawing shape
         * @type {boolean}
         * @private
         *
        this._withShiftKey = false;

        /**
         * Event handler list
         * @type {Object}
         * @private
         */
        this._handlers = {
            mousedown: this._onFabricMouseDown.bind(this),
            mousemove: this._onFabricMouseMove.bind(this),
            mouseup: this._onFabricMouseUp.bind(this),
            keydown: this._onKeyDown.bind(this),
            keyup: this._onKeyUp.bind(this)
        };
    }

    /**
     * Start to draw the shape on canvas
     * @ignore
     */
    start() {
        const canvas = this.getCanvas();

        this._isSelected = false;

        canvas.defaultCursor = 'crosshair';
        canvas.selection = false;
        canvas.uniScaleTransform = true;
        canvas.on({
            'mouse:down': this._handlers.mousedown
        });

        fabric.util.addListener(document, 'keydown', this._handlers.keydown);
        fabric.util.addListener(document, 'keyup', this._handlers.keyup);
    }

    /**
     * End to draw the shape on canvas
     * @ignore
     */
    end() {
        const canvas = this.getCanvas();

        this._isSelected = false;

        canvas.defaultCursor = 'default';

        canvas.selection = true;
        canvas.uniScaleTransform = false;
        canvas.off({
            'mouse:down': this._handlers.mousedown
        });

        fabric.util.removeListener(document, 'keydown', this._handlers.keydown);
        fabric.util.removeListener(document, 'keyup', this._handlers.keyup);
    }

    /**
     * Set states of the current drawing shape
     * @ignore
     * @param {string} type - Shape type (ex: 'rect', 'circle')
     * @param {Object} [options] - Shape options
     *      @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
     *      @param {string} [options.stoke] - Shape outline color
     *      @param {number} [options.strokeWidth] - Shape outline width
     *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
     *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
     *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
     *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
     */
    setStates(type, options) {
        this._type = type;

        if (options) {
            this._options = extend(this._options, options);
        }
    }

    /**
     * Add the shape
     * @ignore
     * @param {string} type - Shape type (ex: 'rect', 'circle')
     * @param {Object} options - Shape options
     *      @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
     *      @param {string} [options.stroke] - Shape outline color
     *      @param {number} [options.strokeWidth] - Shape outline width
     *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
     *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
     *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
     *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
     *      @param {number} [options.isRegular] - Whether scaling shape has 1:1 ratio or not
     * @returns {Promise}
     */
    add(type, options) {
        return new Promise(resolve => {
            const canvas = this.getCanvas();
            options = this._createOptions(options);
            const shapeObj = this._createInstance(type, options);

            this._bindEventOnShape(shapeObj);

            canvas.add(shapeObj).setActiveObject(shapeObj);
            resolve(this.graphics.createObjectProperties(shapeObj));
        });
    }

    /**
     * Change the shape
     * @ignore
     * @param {fabric.Object} shapeObj - Selected shape object on canvas
     * @param {Object} options - Shape options
     *      @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
     *      @param {string} [options.stroke] - Shape outline color
     *      @param {number} [options.strokeWidth] - Shape outline width
     *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
     *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
     *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
     *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
     *      @param {number} [options.isRegular] - Whether scaling shape has 1:1 ratio or not
     * @returns {Promise}
     */
    change(shapeObj, options) {
        return new Promise((resolve, reject) => {
            if (inArray(shapeObj.get('type'), shapeType) < 0) {
                reject(rejectMessages.unsupportedType);
            }

            shapeObj.set(options);
            this.getCanvas().renderAll();
            resolve();
        });
    }

    /**
     * Create the instance of shape
     * @param {string} type - Shape type
     * @param {Object} options - Options to creat the shape
     * @returns {fabric.Object} Shape instance
     * @private
     */
    _createInstance(type, options) {
        let instance;

        switch (type) {
            case 'rect':
                instance = new fabric.Rect(options);
                break;
            case 'circle':
                instance = new fabric.Ellipse(extend({
                    type: 'circle'
                }, options));
                break;
            case 'triangle':
                instance = new fabric.Triangle(options);
                break;
            default:
                instance = {};
        }

        return instance;
    }

    /**
     * Get the options to create the shape
     * @param {Object} options - Options to creat the shape
     * @returns {Object} Shape options
     * @private
     */
    _createOptions(options) {
        const selectionStyles = consts.fObjectOptions.SELECTION_STYLE;

        options = extend({}, DEFAULT_OPTIONS, this._options, selectionStyles, options);

        if (options.isRegular) {
            options.lockUniScaling = true;
        }

        return options;
    }

    /**
     * Bind fabric events on the creating shape object
     * @param {fabric.Object} shapeObj - Shape object
     * @private
     */
    _bindEventOnShape(shapeObj) {
        const self = this;
        const canvas = this.getCanvas();

        shapeObj.on({
            added() {
                self._shapeObj = this;
                resizeHelper.setOrigins(self._shapeObj);
            },
            selected() {
                self._isSelected = true;
                self._shapeObj = this;
                canvas.uniScaleTransform = true;
                canvas.defaultCursor = 'default';
                resizeHelper.setOrigins(self._shapeObj);
            },
            deselected() {
                self._isSelected = false;
                self._shapeObj = null;
                canvas.defaultCursor = 'crosshair';
                canvas.uniScaleTransform = false;
            },
            modified() {
                const currentObj = self._shapeObj;

                resizeHelper.adjustOriginToCenter(currentObj);
                resizeHelper.setOrigins(currentObj);
            },
            scaling(fEvent) {
                const pointer = canvas.getPointer(fEvent.e);
                const currentObj = self._shapeObj;

                canvas.setCursor('crosshair');
                resizeHelper.resize(currentObj, pointer, true);
            }
        });
    }

    /**
     * MouseDown event handler on canvas
     * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object
     * @private
     */
    _onFabricMouseDown(fEvent) {
        if (!fEvent.target) {
            this._isSelected = false;
            this._shapeObj = false;
        }

        if (!this._isSelected && !this._shapeObj) {
            const canvas = this.getCanvas();
            this._startPoint = canvas.getPointer(fEvent.e);

            canvas.on({
                'mouse:move': this._handlers.mousemove,
                'mouse:up': this._handlers.mouseup
            });
        }
    }

    /**
     * MouseDown event handler on canvas
     * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object
     * @private
     */
    _onFabricMouseMove(fEvent) {
        const canvas = this.getCanvas();
        const pointer = canvas.getPointer(fEvent.e);
        const startPointX = this._startPoint.x;
        const startPointY = this._startPoint.y;
        const width = startPointX - pointer.x;
        const height = startPointY - pointer.y;
        const shape = this._shapeObj;

        if (!shape) {
            this.add(this._type, {
                left: startPointX,
                top: startPointY,
                width,
                height
            }).then(objectProps => {
                this.fire(eventNames.ADD_OBJECT, objectProps);
            });
        } else {
            this._shapeObj.set({
                isRegular: this._withShiftKey
            });
            resizeHelper.resize(shape, pointer);
            canvas.renderAll();
        }
    }

    /**
     * MouseUp event handler on canvas
     * @private
     */
    _onFabricMouseUp() {
        const canvas = this.getCanvas();
        const shape = this._shapeObj;

        if (shape) {
            resizeHelper.adjustOriginToCenter(shape);
        }

        this.fire(eventNames.ADD_OBJECT_AFTER, this.graphics.createObjectProperties(shape));

        canvas.off({
            'mouse:move': this._handlers.mousemove,
            'mouse:up': this._handlers.mouseup
        });
    }

    /**
     * Keydown event handler on document
     * @param {KeyboardEvent} e - Event object
     * @private
     */
    _onKeyDown(e) {
        if (e.keyCode === KEY_CODES.SHIFT) {
            this._withShiftKey = true;

            if (this._shapeObj) {
                this._shapeObj.isRegular = true;
            }
        }
    }

    /**
     * Keyup event handler on document
     * @param {KeyboardEvent} e - Event object
     * @private
     */
    _onKeyUp(e) {
        if (e.keyCode === KEY_CODES.SHIFT) {
            this._withShiftKey = false;

            if (this._shapeObj) {
                this._shapeObj.isRegular = false;
            }
        }
    }
}

module.exports = Shape;
<commit_msg>fixed typpo<commit_after>/**
 * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
 * @fileoverview Shape component
 */
import fabric from 'fabric/dist/fabric.require';
import Promise from 'core-js/library/es6/promise';
import Component from '../interface/component';
import consts from '../consts';
import resizeHelper from '../helper/shapeResizeHelper';
import {extend, inArray} from 'tui-code-snippet';

const {rejectMessages, eventNames} = consts;
const KEY_CODES = consts.keyCodes;

const DEFAULT_TYPE = 'rect';
const DEFAULT_OPTIONS = {
    strokeWidth: 1,
    stroke: '#000000',
    fill: '#ffffff',
    width: 1,
    height: 1,
    rx: 0,
    ry: 0,
    lockSkewingX: true,
    lockSkewingY: true,
    lockUniScaling: false,
    bringForward: true,
    isRegular: false
};

const shapeType = ['rect', 'circle', 'triangle'];

/**
 * Shape
 * @class Shape
 * @param {Graphics} graphics - Graphics instance
 * @extends {Component}
 * @ignore
 */
class Shape extends Component {
    constructor(graphics) {
        super(consts.componentNames.SHAPE, graphics);

        /**
         * Object of The drawing shape
         * @type {fabric.Object}
         * @private
         */
        this._shapeObj = null;

        /**
         * Type of the drawing shape
         * @type {string}
         * @private
         */
        this._type = DEFAULT_TYPE;

        /**
         * Options to draw the shape
         * @type {Object}
         * @private
         */
        this._options = extend({}, DEFAULT_OPTIONS);

        /**
         * Whether the shape object is selected or not
         * @type {boolean}
         * @private
         */
        this._isSelected = false;

        /**
         * Pointer for drawing shape (x, y)
         * @type {Object}
         * @private
         */
        this._startPoint = {};

        /**
         * Using shortcut on drawing shape
         * @type {boolean}
         * @private
         */
        this._withShiftKey = false;

        /**
         * Event handler list
         * @type {Object}
         * @private
         */
        this._handlers = {
            mousedown: this._onFabricMouseDown.bind(this),
            mousemove: this._onFabricMouseMove.bind(this),
            mouseup: this._onFabricMouseUp.bind(this),
            keydown: this._onKeyDown.bind(this),
            keyup: this._onKeyUp.bind(this)
        };
    }

    /**
     * Start to draw the shape on canvas
     * @ignore
     */
    start() {
        const canvas = this.getCanvas();

        this._isSelected = false;

        canvas.defaultCursor = 'crosshair';
        canvas.selection = false;
        canvas.uniScaleTransform = true;
        canvas.on({
            'mouse:down': this._handlers.mousedown
        });

        fabric.util.addListener(document, 'keydown', this._handlers.keydown);
        fabric.util.addListener(document, 'keyup', this._handlers.keyup);
    }

    /**
     * End to draw the shape on canvas
     * @ignore
     */
    end() {
        const canvas = this.getCanvas();

        this._isSelected = false;

        canvas.defaultCursor = 'default';

        canvas.selection = true;
        canvas.uniScaleTransform = false;
        canvas.off({
            'mouse:down': this._handlers.mousedown
        });

        fabric.util.removeListener(document, 'keydown', this._handlers.keydown);
        fabric.util.removeListener(document, 'keyup', this._handlers.keyup);
    }

    /**
     * Set states of the current drawing shape
     * @ignore
     * @param {string} type - Shape type (ex: 'rect', 'circle')
     * @param {Object} [options] - Shape options
     *      @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
     *      @param {string} [options.stoke] - Shape outline color
     *      @param {number} [options.strokeWidth] - Shape outline width
     *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
     *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
     *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
     *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
     */
    setStates(type, options) {
        this._type = type;

        if (options) {
            this._options = extend(this._options, options);
        }
    }

    /**
     * Add the shape
     * @ignore
     * @param {string} type - Shape type (ex: 'rect', 'circle')
     * @param {Object} options - Shape options
     *      @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
     *      @param {string} [options.stroke] - Shape outline color
     *      @param {number} [options.strokeWidth] - Shape outline width
     *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
     *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
     *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
     *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
     *      @param {number} [options.isRegular] - Whether scaling shape has 1:1 ratio or not
     * @returns {Promise}
     */
    add(type, options) {
        return new Promise(resolve => {
            const canvas = this.getCanvas();
            options = this._createOptions(options);
            const shapeObj = this._createInstance(type, options);

            this._bindEventOnShape(shapeObj);

            canvas.add(shapeObj).setActiveObject(shapeObj);
            resolve(this.graphics.createObjectProperties(shapeObj));
        });
    }

    /**
     * Change the shape
     * @ignore
     * @param {fabric.Object} shapeObj - Selected shape object on canvas
     * @param {Object} options - Shape options
     *      @param {string} [options.fill] - Shape foreground color (ex: '#fff', 'transparent')
     *      @param {string} [options.stroke] - Shape outline color
     *      @param {number} [options.strokeWidth] - Shape outline width
     *      @param {number} [options.width] - Width value (When type option is 'rect', this options can use)
     *      @param {number} [options.height] - Height value (When type option is 'rect', this options can use)
     *      @param {number} [options.rx] - Radius x value (When type option is 'circle', this options can use)
     *      @param {number} [options.ry] - Radius y value (When type option is 'circle', this options can use)
     *      @param {number} [options.isRegular] - Whether scaling shape has 1:1 ratio or not
     * @returns {Promise}
     */
    change(shapeObj, options) {
        return new Promise((resolve, reject) => {
            if (inArray(shapeObj.get('type'), shapeType) < 0) {
                reject(rejectMessages.unsupportedType);
            }

            shapeObj.set(options);
            this.getCanvas().renderAll();
            resolve();
        });
    }

    /**
     * Create the instance of shape
     * @param {string} type - Shape type
     * @param {Object} options - Options to creat the shape
     * @returns {fabric.Object} Shape instance
     * @private
     */
    _createInstance(type, options) {
        let instance;

        switch (type) {
            case 'rect':
                instance = new fabric.Rect(options);
                break;
            case 'circle':
                instance = new fabric.Ellipse(extend({
                    type: 'circle'
                }, options));
                break;
            case 'triangle':
                instance = new fabric.Triangle(options);
                break;
            default:
                instance = {};
        }

        return instance;
    }

    /**
     * Get the options to create the shape
     * @param {Object} options - Options to creat the shape
     * @returns {Object} Shape options
     * @private
     */
    _createOptions(options) {
        const selectionStyles = consts.fObjectOptions.SELECTION_STYLE;

        options = extend({}, DEFAULT_OPTIONS, this._options, selectionStyles, options);

        if (options.isRegular) {
            options.lockUniScaling = true;
        }

        return options;
    }

    /**
     * Bind fabric events on the creating shape object
     * @param {fabric.Object} shapeObj - Shape object
     * @private
     */
    _bindEventOnShape(shapeObj) {
        const self = this;
        const canvas = this.getCanvas();

        shapeObj.on({
            added() {
                self._shapeObj = this;
                resizeHelper.setOrigins(self._shapeObj);
            },
            selected() {
                self._isSelected = true;
                self._shapeObj = this;
                canvas.uniScaleTransform = true;
                canvas.defaultCursor = 'default';
                resizeHelper.setOrigins(self._shapeObj);
            },
            deselected() {
                self._isSelected = false;
                self._shapeObj = null;
                canvas.defaultCursor = 'crosshair';
                canvas.uniScaleTransform = false;
            },
            modified() {
                const currentObj = self._shapeObj;

                resizeHelper.adjustOriginToCenter(currentObj);
                resizeHelper.setOrigins(currentObj);
            },
            scaling(fEvent) {
                const pointer = canvas.getPointer(fEvent.e);
                const currentObj = self._shapeObj;

                canvas.setCursor('crosshair');
                resizeHelper.resize(currentObj, pointer, true);
            }
        });
    }

    /**
     * MouseDown event handler on canvas
     * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object
     * @private
     */
    _onFabricMouseDown(fEvent) {
        if (!fEvent.target) {
            this._isSelected = false;
            this._shapeObj = false;
        }

        if (!this._isSelected && !this._shapeObj) {
            const canvas = this.getCanvas();
            this._startPoint = canvas.getPointer(fEvent.e);

            canvas.on({
                'mouse:move': this._handlers.mousemove,
                'mouse:up': this._handlers.mouseup
            });
        }
    }

    /**
     * MouseDown event handler on canvas
     * @param {{target: fabric.Object, e: MouseEvent}} fEvent - Fabric event object
     * @private
     */
    _onFabricMouseMove(fEvent) {
        const canvas = this.getCanvas();
        const pointer = canvas.getPointer(fEvent.e);
        const startPointX = this._startPoint.x;
        const startPointY = this._startPoint.y;
        const width = startPointX - pointer.x;
        const height = startPointY - pointer.y;
        const shape = this._shapeObj;

        if (!shape) {
            this.add(this._type, {
                left: startPointX,
                top: startPointY,
                width,
                height
            }).then(objectProps => {
                this.fire(eventNames.ADD_OBJECT, objectProps);
            });
        } else {
            this._shapeObj.set({
                isRegular: this._withShiftKey
            });
            resizeHelper.resize(shape, pointer);
            canvas.renderAll();
        }
    }

    /**
     * MouseUp event handler on canvas
     * @private
     */
    _onFabricMouseUp() {
        const canvas = this.getCanvas();
        const shape = this._shapeObj;

        if (shape) {
            resizeHelper.adjustOriginToCenter(shape);
        }

        this.fire(eventNames.ADD_OBJECT_AFTER, this.graphics.createObjectProperties(shape));

        canvas.off({
            'mouse:move': this._handlers.mousemove,
            'mouse:up': this._handlers.mouseup
        });
    }

    /**
     * Keydown event handler on document
     * @param {KeyboardEvent} e - Event object
     * @private
     */
    _onKeyDown(e) {
        if (e.keyCode === KEY_CODES.SHIFT) {
            this._withShiftKey = true;

            if (this._shapeObj) {
                this._shapeObj.isRegular = true;
            }
        }
    }

    /**
     * Keyup event handler on document
     * @param {KeyboardEvent} e - Event object
     * @private
     */
    _onKeyUp(e) {
        if (e.keyCode === KEY_CODES.SHIFT) {
            this._withShiftKey = false;

            if (this._shapeObj) {
                this._shapeObj.isRegular = false;
            }
        }
    }
}

module.exports = Shape;
<|endoftext|>


<commit_before>'use strict';

var childProcess = require('child_process');
var gulp = require('gulp');
var createHash = require("crypto").createHash;
var createReadStream = require("fs").createReadStream;
var writeFile = require("fs").writeFile;
var safeDump = require("js-yaml").safeDump;
var path = require("path");

gulp.task('makeyml', function () {
    var installerFilename = "Sideka Setup 0.0.2.exe";
    var version = "0.0.2";
    sha256(path.join("dist",installerFilename)).then(sha2 => {
        writeFile(path.join("dist", 'latest.yml'), safeDump({
            version: version,
            path: installerFilename,
            sha2: sha2,
        }))
    });
});

function sha256(file) {
  return new Promise((resolve, reject) => {
    const hash = createHash("sha256")
    hash
      .on("error", reject)
      .setEncoding("hex")

    createReadStream(file)
      .on("error", reject)
      .on("end", () => {
        hash.end()
        resolve(hash.read())
      })
      .pipe(hash, {end: false})
  })
}<commit_msg>read version from package json<commit_after>'use strict';

var childProcess = require('child_process');
var gulp = require('gulp');
var createHash = require("crypto").createHash;
var createReadStream = require("fs").createReadStream;
var writeFile = require("fs").writeFile;
var safeDump = require("js-yaml").safeDump;
var path = require("path");
var pjson = require("../app/package.json");

gulp.task('makeyml', function () {
    var version = pjson.version;
    var installerFilename = "Sideka Setup "+version+".exe";
    sha256(path.join("dist",installerFilename)).then(sha2 => {
        writeFile(path.join("dist", 'latest.yml'), safeDump({
            version: version,
            path: installerFilename,
            sha2: sha2,
        }))
    });
});

function sha256(file) {
  return new Promise((resolve, reject) => {
    const hash = createHash("sha256")
    hash
      .on("error", reject)
      .setEncoding("hex")

    createReadStream(file)
      .on("error", reject)
      .on("end", () => {
        hash.end()
        resolve(hash.read())
      })
      .pipe(hash, {end: false})
  })
}<|endoftext|>


<commit_before>'use strict';

var http = require('http');
var https = require('https');
var path = require('path');
var when = require('when');

var utils = require('./utils');
var Error = require('./Error');

var hasOwn = {}.hasOwnProperty;

var BLACKLISTED_FINGERPRINTS = require('fs').readFileSync(
  path.join(__dirname, '../data/blacklisted_fingerprints'), 'utf8'
).replace(/^\s+|\s+$/g, '').split('\n');

// Provide extension mechanism for Pingpp Resource Sub-Classes
PingppResource.extend = utils.protoExtend;

// Expose method-creator & prepared (basic) methods
PingppResource.method = require('./PingppMethod');
PingppResource.BASIC_METHODS = require('./PingppMethod.basic');

/**
 * Encapsulates request logic for a Pingpp Resource
 */
function PingppResource(pingpp, urlData) {
  this._pingpp = pingpp;
  this._urlData = urlData || {};

  this.basePath = utils.makeURLInterpolator(pingpp.getApiField('basePath'));
  this.path = utils.makeURLInterpolator(this.path);

  if (this.includeBasic) {
    this.includeBasic.forEach(function(methodName) {
      this[methodName] = PingppResource.BASIC_METHODS[methodName];
    }, this);
  }

  this.initialize.apply(this, arguments);
}

PingppResource.prototype = {
  path: '',

  initialize: function() {},

  createFullPath: function(commandPath, urlData) {
    return path.join(
      this.basePath(urlData),
      this.path(urlData),
      typeof commandPath == 'function' ?
        commandPath(urlData) : commandPath
    ).replace(/\\/g, '/'); // ugly workaround for Windows
  },

  createUrlData: function(callback) {
    var urlData = {};
    for (var i in this._urlData) {
      if (hasOwn.call(this._urlData, i)) {
        urlData[i] = this._urlData[i];
      }
    }

    return urlData;
  },

  createDeferred: function(callback) {
    var deferred = when.defer();

    if (callback) {
      // Callback, if provided, is a simply translated to Promise'esque:
      // (Ensure callback is called outside of promise stack)
      deferred.promise.then(function(res) {
        setTimeout(function(){ callback(null, res); }, 0);
      }, function(err) {
        setTimeout(function(){ callback(err, null); }, 0);
      });
    }

    return deferred;
  },

  _timeoutHandler: function(timeout, reg, callback) {
    var self = this;
    return function() {
      var timeoutErr = new Error('ETIMEOUT');
      timeoutErr.code = 'ETIMEOUT';

      req._isAborted = true;
      req.abort();

      callback.call(
        self,
        new Error.PingppConnectionError({
          message: 'Request aborted due to timeout being reached (' + timeout + 'ms)',
          detail: timeoutErr
        }),
        null
      );
    }
  },

  _responseHandler: function(req, callback) {
    var self = this;
    return function(res) {
      var response = '';

      res.setEncoding('utf8');
      res.on('data', function(chunk) {
        response += chunk;
      });
      res.on('end', function() {
        try {
          response = JSON.parse(response);
          if (response.error) {
            var err;
            if (res.statusCode === 401) {
              err = new Error.PingppAuthenticationError(response.error);
            } else {
              err = Error.PingppError.generate(response.error);
            }
            return callback.call(self, err, null);
          }
        } catch (e) {
          return callback.call(
            self,
            new Error.PingppAPIError({
              message: 'Invalid JSON received from the Pingpp API',
              response: response,
              exception: e
            }),
            null
          );
        }
        callback.call(self, null, response);
      });
    };
  },

  _errorHandler: function(req, callback) {
    var self = this;
    return function(error) {
      if (req._isAborted) return; // already handled
      callback.call(
        self,
        new Error.PingppConnectionError({
          message: 'An error occurred with our connection to Pingpp',
          detail: error
        }),
        null
      );
    }
  },

  _request: function(method, path, data, auth, callback) {
    var requestData = utils.stringifyRequestData(data || {});
    var self = this;

    if ((method == 'GET' || method == 'DELETE') && requestData != '') {
      path = path + '?' + requestData;
      requestData = '';
    }

    var apiVersion = this._pingpp.getApiField('version');
    var headers = {
      'Authorization': auth ?
        'Basic ' + new Buffer(auth + ':').toString('base64') :
        this._pingpp.getApiField('auth'),
      'Accept': 'application/json',
      'Content-Type': 'application/x-www-form-urlencoded',
      'User-Agent': 'Pingpp/v1 NodeBindings/' + this._pingpp.getConstant('PACKAGE_VERSION')
    };

    if (apiVersion) {
      headers['Pingplusplus-Version'] = apiVersion;
    }

    this._pingpp.getClientUserAgent(function(cua) {
      headers['X-Pingpp-Client-User-Agent'] = cua;
      makeRequest();
    });

    function makeRequest() {
      var timeout = self._pingpp.getApiField('timeout');
      var isInsecureConnection = self._pingpp.getApiField('protocal') == 'http';

      var req = (
        isInsecureConnection ? http : https
      ).request({
        host: self._pingpp.getApiField('host'),
        port: self._pingpp.getApiField('port'),
        path: path,
        method: method,
        headers: headers,
        ciphers: 'DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:!MD5',
        secureProtocol: 'TLSv1_method'
      });

      req.setTimeout(timeout, self._timeoutHandler(timeout, req, callback));
      req.on('response', self._responseHandler(req, callback));
      req.on('error', self._errorHandler(req, callback));

      req.on('socket', function(socket) {
        socket.on(isInsecureConnection ? 'connect' : 'secureConnect', function() {
          if (!isInsecureConnection &&
            BLACKLISTED_FINGERPRINTS.indexOf(socket.getPeerCertificate().fingerprint) > -1) {
            req.abort();
            return callback.call(self,
              new Error.PingppError({
                message: 'Revoked SSL Certificate',
                detail: 'Invalid server certificate. You tried to connect to ' +
                        'a server that has a revoked SSL certificate, which ' +
                        'means we cannot securely send data to that server. ' +
                        'Please email support@pingplusplus.com if you need ' +
                        'help connecting to the correct API server.'
              })
            );
          }
          req.write(requestData);
          req.end();
        });
      });
    }
  }
};

module.exports = PingppResource;<commit_msg>change content-type to application/json for POST method<commit_after>'use strict';

var http = require('http');
var https = require('https');
var path = require('path');
var when = require('when');

var utils = require('./utils');
var Error = require('./Error');

var hasOwn = {}.hasOwnProperty;

var BLACKLISTED_FINGERPRINTS = require('fs').readFileSync(
  path.join(__dirname, '../data/blacklisted_fingerprints'), 'utf8'
).replace(/^\s+|\s+$/g, '').split('\n');

// Provide extension mechanism for Pingpp Resource Sub-Classes
PingppResource.extend = utils.protoExtend;

// Expose method-creator & prepared (basic) methods
PingppResource.method = require('./PingppMethod');
PingppResource.BASIC_METHODS = require('./PingppMethod.basic');

/**
 * Encapsulates request logic for a Pingpp Resource
 */
function PingppResource(pingpp, urlData) {
  this._pingpp = pingpp;
  this._urlData = urlData || {};

  this.basePath = utils.makeURLInterpolator(pingpp.getApiField('basePath'));
  this.path = utils.makeURLInterpolator(this.path);

  if (this.includeBasic) {
    this.includeBasic.forEach(function(methodName) {
      this[methodName] = PingppResource.BASIC_METHODS[methodName];
    }, this);
  }

  this.initialize.apply(this, arguments);
}

PingppResource.prototype = {
  path: '',

  initialize: function() {},

  createFullPath: function(commandPath, urlData) {
    return path.join(
      this.basePath(urlData),
      this.path(urlData),
      typeof commandPath == 'function' ?
        commandPath(urlData) : commandPath
    ).replace(/\\/g, '/'); // ugly workaround for Windows
  },

  createUrlData: function(callback) {
    var urlData = {};
    for (var i in this._urlData) {
      if (hasOwn.call(this._urlData, i)) {
        urlData[i] = this._urlData[i];
      }
    }

    return urlData;
  },

  createDeferred: function(callback) {
    var deferred = when.defer();

    if (callback) {
      // Callback, if provided, is a simply translated to Promise'esque:
      // (Ensure callback is called outside of promise stack)
      deferred.promise.then(function(res) {
        setTimeout(function(){ callback(null, res); }, 0);
      }, function(err) {
        setTimeout(function(){ callback(err, null); }, 0);
      });
    }

    return deferred;
  },

  _timeoutHandler: function(timeout, reg, callback) {
    var self = this;
    return function() {
      var timeoutErr = new Error('ETIMEOUT');
      timeoutErr.code = 'ETIMEOUT';

      req._isAborted = true;
      req.abort();

      callback.call(
        self,
        new Error.PingppConnectionError({
          message: 'Request aborted due to timeout being reached (' + timeout + 'ms)',
          detail: timeoutErr
        }),
        null
      );
    }
  },

  _responseHandler: function(req, callback) {
    var self = this;
    return function(res) {
      var response = '';

      res.setEncoding('utf8');
      res.on('data', function(chunk) {
        response += chunk;
      });
      res.on('end', function() {
        try {
          response = JSON.parse(response);
          if (response.error) {
            var err;
            if (res.statusCode === 401) {
              err = new Error.PingppAuthenticationError(response.error);
            } else {
              err = Error.PingppError.generate(response.error);
            }
            return callback.call(self, err, null);
          }
        } catch (e) {
          return callback.call(
            self,
            new Error.PingppAPIError({
              message: 'Invalid JSON received from the Pingpp API',
              response: response,
              exception: e
            }),
            null
          );
        }
        callback.call(self, null, response);
      });
    };
  },

  _errorHandler: function(req, callback) {
    var self = this;
    return function(error) {
      if (req._isAborted) return; // already handled
      callback.call(
        self,
        new Error.PingppConnectionError({
          message: 'An error occurred with our connection to Pingpp',
          detail: error
        }),
        null
      );
    }
  },

  _request: function(method, path, data, auth, callback) {
    var requestData = method == 'POST' ? JSON.stringify(data || {}) : utils.stringifyRequestData(data || {});
    var self = this;

    if ((method == 'GET' || method == 'DELETE') && requestData != '') {
      path = path + '?' + requestData;
      requestData = '';
    }

    var apiVersion = this._pingpp.getApiField('version');
    var headers = {
      'Authorization': auth ?
        'Basic ' + new Buffer(auth + ':').toString('base64') :
        this._pingpp.getApiField('auth'),
      'Accept': 'application/json',
      'Content-Type': method == 'POST' ? 'application/json' : 'application/x-www-form-urlencoded',
      'User-Agent': 'Pingpp/v1 NodeBindings/' + this._pingpp.getConstant('PACKAGE_VERSION')
    };

    if (apiVersion) {
      headers['Pingplusplus-Version'] = apiVersion;
    }

    this._pingpp.getClientUserAgent(function(cua) {
      headers['X-Pingpp-Client-User-Agent'] = cua;
      makeRequest();
    });

    function makeRequest() {
      var timeout = self._pingpp.getApiField('timeout');
      var isInsecureConnection = self._pingpp.getApiField('protocal') == 'http';

      var req = (
        isInsecureConnection ? http : https
      ).request({
        host: self._pingpp.getApiField('host'),
        port: self._pingpp.getApiField('port'),
        path: path,
        method: method,
        headers: headers,
        ciphers: 'DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:!MD5',
        secureProtocol: 'TLSv1_method'
      });

      req.setTimeout(timeout, self._timeoutHandler(timeout, req, callback));
      req.on('response', self._responseHandler(req, callback));
      req.on('error', self._errorHandler(req, callback));

      req.on('socket', function(socket) {
        socket.on(isInsecureConnection ? 'connect' : 'secureConnect', function() {
          if (!isInsecureConnection &&
            BLACKLISTED_FINGERPRINTS.indexOf(socket.getPeerCertificate().fingerprint) > -1) {
            req.abort();
            return callback.call(self,
              new Error.PingppError({
                message: 'Revoked SSL Certificate',
                detail: 'Invalid server certificate. You tried to connect to ' +
                        'a server that has a revoked SSL certificate, which ' +
                        'means we cannot securely send data to that server. ' +
                        'Please email support@pingplusplus.com if you need ' +
                        'help connecting to the correct API server.'
              })
            );
          }
          req.write(requestData);
          req.end();
        });
      });
    }
  }
};

module.exports = PingppResource;<|endoftext|>


<commit_before>
/*
 *  Copyright 2013 outaTiME.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

module.exports = function (grunt) {

  'use strict';

  var path = require('path');
  var fs = require('fs');

  grunt.registerMultiTask('replace', 'Replace text patterns with a given string.', function () {

    var
      _ = grunt.util._,
      options = this.options({
        variables: {},
        patterns: [],
        prefix: '@@',
        force: false,
        mode: false
      }),
      variables = options.variables,
      patterns = options.patterns,
      locals = [];

    grunt.verbose.writeflags(options, 'Options');

    // backward compatible support

    Object.keys(variables).sort(function (a, b) {
      // sort variables (prevents replace issues like head, header)
      return b.length - a.length;
    }).forEach(function (variable) {
      // grunt.log.writeln('Use the new patterns option instead of variables.'.yellow);
      grunt.fail.warn('Use the new patterns option instead of variables.');
      patterns.push({
        match: grunt.template.process(variable),
        replacement: variables[variable],
        expression: false
      });
    });

    // process patterns

    patterns.forEach(function (pattern) {
      var match = pattern.match, replacement = pattern.replacement,
        expression = pattern.expression === true;
      // match
      if (_.isRegExp(match)) {
        if (expression === false) {
          /* grunt.fail.warn('RegExp found in match, we force expression for: ' +
            match); */
          expression = true;
        }
      } else if (_.isString(match)) {
        if (match.length > 0) {
          if (expression === true) {
            var index = match.lastIndexOf('/');
            if (match[0] === '/' && index > 0) {
              try {
                match = new RegExp(match.slice(1, index), match.slice(index + 1));
              } catch (error) {
                grunt.fail.fatal(error);
                return;
              }
            } else {
              grunt.fail.fatal('Invalid expression found for match: ' + match);
              return;
            }
          } else {
            // old school
            try {
              match = new RegExp(options.prefix + match, "g");
            } catch (error) {
              grunt.fail.fatal(error);
              return;
            }
          }
        } else {
          // invalid
          grunt.fail.fatal('Empty value found for match: ' + match);
        }
      } else {
        grunt.fail.fatal('Unsupported type for match (RegExp or String expected).');
        return;
      }
      // replacement
      /* if (_.isFunction(replacement)) {
        replacement = replacement.apply(this, [match]);
      } */
      // create new object to preserve pattern instance
      locals.push({
        match: match,
        replacement: replacement,
        expression: expression
      });
    });

    /* locals.forEach(function (local) {
      grunt.verbose.writeln(local.match.toString());
    }); */

    if (locals.length === 0 && options.force === false) {
      grunt.fail.warn('Not found valid patterns to be replaced.');
    }

    // took code from copy task

    var dest;
    var isExpandedPair;

    this.files.forEach(function(filePair) {
      isExpandedPair = filePair.orig.expand || false;
      filePair.src.forEach(function(src) {
        if (detectDestType(filePair.dest) === 'directory') {
          dest = (isExpandedPair) ? filePair.dest : unixifyPath(path.join(filePair.dest, src));
        } else {
          dest = filePair.dest;
        }
        if (grunt.file.isDir(src)) {
          grunt.file.mkdir(dest);
        } else {
          replace(src, dest, options, locals);
          if (options.mode !== false) {
            fs.chmodSync(dest, (options.mode === true) ? fs.lstatSync(src).mode : options.mode);
          }
        }
      });
    });

  });

  var detectDestType = function (dest) {
    if (grunt.util._.endsWith(dest, '/')) {
      return 'directory';
    } else {
      return 'file';
    }
  };

  var unixifyPath = function (filepath) {
    if (process.platform === 'win32') {
      return filepath.replace(/\\/g, '/');
    } else {
      return filepath;
    }
  };

  var replace = function (srcFile, destFile, options, patterns) {
    grunt.file.copy(srcFile, destFile, {
      process: function (contents) {
        var updated = false;
        patterns.forEach(function (pattern) {
          var re = pattern.match, replacement = pattern.replacement;
          updated = updated || contents.match(re);
          // only for backward compatible support
          /* if (pattern.expression === false) {
            // escape $ to $$, otherwise it would be used as special replacement pattern as described here:
            // https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/String/replace
            replacement = replacement.replace(/\$/g, '$$$$');
          } */
          contents = contents.replace(re, replacement);
        });
        if (!updated && options.force === false) {
          return false;
        }
        grunt.log.writeln('Replace ' + srcFile.cyan + ' -> ' + destFile.cyan);
        return contents;
      }
    });
  };

};
<commit_msg>Version 0.5.0 released.<commit_after>
/*
 *  Copyright 2013 outaTiME.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

module.exports = function (grunt) {

  'use strict';

  var path = require('path');
  var fs = require('fs');

  grunt.registerMultiTask('replace', 'Replace text patterns with a given string.', function () {

    var
      _ = grunt.util._,
      options = this.options({
        variables: {},
        patterns: [],
        prefix: '@@',
        force: false,
        mode: false
      }),
      variables = options.variables,
      patterns = options.patterns,
      locals = [];

    grunt.verbose.writeflags(options, 'Options');

    // backward compatible support

    Object.keys(variables).sort(function (a, b) {
      // sort variables (prevents replace issues like head, header)
      return b.length - a.length;
    }).forEach(function (variable) {
      //  grunt.log.writeln('Use the new patterns option instead of variables.'.yellow);
      grunt.fail.warn('Use the new patterns option instead of variables, will be deprecated soon.');
      patterns.push({
        match: grunt.template.process(variable),
        replacement: variables[variable],
        expression: false
      });
    });

    // process patterns

    patterns.forEach(function (pattern) {
      var match = pattern.match, replacement = pattern.replacement,
        expression = pattern.expression === true;
      // match
      if (_.isRegExp(match)) {
        if (expression === false) {
          /* grunt.fail.warn('RegExp found in match, we force expression for: ' +
            match); */
          expression = true;
        }
      } else if (_.isString(match)) {
        if (match.length > 0) {
          if (expression === true) {
            var index = match.lastIndexOf('/');
            if (match[0] === '/' && index > 0) {
              try {
                match = new RegExp(match.slice(1, index), match.slice(index + 1));
              } catch (error) {
                grunt.fail.fatal(error);
                return;
              }
            } else {
              grunt.fail.fatal('Invalid expression found for match: ' + match);
              return;
            }
          } else {
            // old school
            try {
              match = new RegExp(options.prefix + match, "g");
            } catch (error) {
              grunt.fail.fatal(error);
              return;
            }
          }
        } else {
          // invalid
          grunt.fail.fatal('Empty value found for match: ' + match);
        }
      } else {
        grunt.fail.fatal('Unsupported type for match (RegExp or String expected).');
        return;
      }
      // replacement
      /* if (_.isFunction(replacement)) {
        replacement = replacement.apply(this, [match]);
      } */
      // create new object to preserve pattern instance
      locals.push({
        match: match,
        replacement: replacement,
        expression: expression
      });
    });

    /* locals.forEach(function (local) {
      grunt.verbose.writeln(local.match.toString());
    }); */

    if (locals.length === 0 && options.force === false) {
      grunt.fail.warn('Not found valid patterns to be replaced.');
    }

    // took code from copy task

    var dest;
    var isExpandedPair;

    this.files.forEach(function(filePair) {
      isExpandedPair = filePair.orig.expand || false;
      filePair.src.forEach(function(src) {
        if (detectDestType(filePair.dest) === 'directory') {
          dest = (isExpandedPair) ? filePair.dest : unixifyPath(path.join(filePair.dest, src));
        } else {
          dest = filePair.dest;
        }
        if (grunt.file.isDir(src)) {
          grunt.file.mkdir(dest);
        } else {
          replace(src, dest, options, locals);
          if (options.mode !== false) {
            fs.chmodSync(dest, (options.mode === true) ? fs.lstatSync(src).mode : options.mode);
          }
        }
      });
    });

  });

  var detectDestType = function (dest) {
    if (grunt.util._.endsWith(dest, '/')) {
      return 'directory';
    } else {
      return 'file';
    }
  };

  var unixifyPath = function (filepath) {
    if (process.platform === 'win32') {
      return filepath.replace(/\\/g, '/');
    } else {
      return filepath;
    }
  };

  var replace = function (srcFile, destFile, options, patterns) {
    grunt.file.copy(srcFile, destFile, {
      process: function (contents) {
        var updated = false;
        patterns.forEach(function (pattern) {
          var re = pattern.match, replacement = pattern.replacement;
          updated = updated || contents.match(re);
          // only for backward compatible support
          /* if (pattern.expression === false) {
            // escape $ to $$, otherwise it would be used as special replacement pattern as described here:
            // https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/String/replace
            replacement = replacement.replace(/\$/g, '$$$$');
          } */
          contents = contents.replace(re, replacement);
        });
        if (!updated && options.force === false) {
          return false;
        }
        grunt.log.writeln('Replace ' + srcFile.cyan + ' -> ' + destFile.cyan);
        return contents;
      }
    });
  };

};
<|endoftext|>


<commit_before>App.info({
  id: "cc.newspring.newspringapp",
  name: "NewSpring",
  description: "App for NewSpring Church",
  author: "NewSpring Church",
  email: "web@newspring.cc",
  website: "https://newspring.cc",
  version: "0.0.3",
  buildNumber: "146"
});

App.icons({
  // iOS
  "iphone_2x": "assets/icons/ios/icon-60x60@2x.png",
  "iphone_3x": "assets/icons/ios/icon-60x60@3x.png",
  "ipad": "assets/icons/ios/icon-76x76.png",
  "ipad_2x": "assets/icons/ios/icon-76x76@2x.png",
  "ipad_pro": "assets/icons/ios/icon-83.5x83.5@2x.png",
  "ios_settings": "assets/icons/ios/icon-29x29.png",
  "ios_settings_2x": "assets/icons/ios/icon-29x29@2x.png",
  "ios_settings_3x": "assets/icons/ios/icon-29x29@3x.png",
  "ios_spotlight": "assets/icons/ios/icon-40x40.png",
  "ios_spotlight_2x": "assets/icons/ios/icon-40x40@2x.png",

  // Android
  "android_mdpi": "assets/icons/android/icon-48x48-mdpi.png",
  "android_hdpi": "assets/icons/android/icon-72x72-hdpi.png",
  "android_xhdpi": "assets/icons/android/icon-96x96-xhdpi.png",
  "android_xxhdpi": "assets/icons/android/icon-144x144-xxhdpi.png",
  "android_xxxhdpi": "assets/icons/android/icon-192x192-xxxhpdi.png"
});

App.launchScreens({
  // iOS
  "iphone_2x": "assets/splash/ios/splash-320x480@2x.png",
  "iphone5": "assets/splash/ios/splash-320x568@2x.png",
  "iphone6": "assets/splash/ios/splash-667h.png",
  "iphone6p_portrait": "assets/splash/ios/splash-1242h-portrait.png",
  "iphone6p_landscape": "assets/splash/ios/splash-1242h-landscape.png",
  "ipad_portrait": "assets/splash/ios/splash-768x1024.png",
  "ipad_portrait_2x": "assets/splash/ios/splash-768x1024@2x.png",
  "ipad_landscape": "assets/splash/ios/splash-1024x768.png",
  "ipad_landscape_2x": "assets/splash/ios/splash-1024x768@2x.png",

  // Android
  "android_mdpi_portrait": "assets/splash/android/splash-320x470.png",
  "android_mdpi_landscape": "assets/splash/android/splash-470x320.png",
  "android_hdpi_portrait": "assets/splash/android/splash-480x640.png",
  "android_hdpi_landscape": "assets/splash/android/splash-640x480.png",
  "android_xhdpi_portrait": "assets/splash/android/splash-720x960.png",
  "android_xhdpi_landscape": "assets/splash/android/splash-960x720.png",
  "android_xxhdpi_portrait": "assets/splash/android/splash-1080x1440.png",
  "android_xxhdpi_landscape": "assets/splash/android/splash-1440x1080.png"
});

App.accessRule("*");

App.setPreference("EnableBitcode", false);
App.setPreference("ShowSplashScreenSpinner", false);
App.setPreference("SplashMaintainAspectRatio", true);

App.setPreference("StatusBarBackgroundColor", "#6bac43");
App.setPreference("StatusBarStyle", "lightcontent");

App.setPreference("Orientation", "portrait");
<commit_msg>build bump<commit_after>App.info({
  id: "cc.newspring.newspringapp",
  name: "NewSpring",
  description: "App for NewSpring Church",
  author: "NewSpring Church",
  email: "web@newspring.cc",
  website: "https://newspring.cc",
  version: "0.0.3",
  buildNumber: "147"
});

App.icons({
  // iOS
  "iphone_2x": "assets/icons/ios/icon-60x60@2x.png",
  "iphone_3x": "assets/icons/ios/icon-60x60@3x.png",
  "ipad": "assets/icons/ios/icon-76x76.png",
  "ipad_2x": "assets/icons/ios/icon-76x76@2x.png",
  "ipad_pro": "assets/icons/ios/icon-83.5x83.5@2x.png",
  "ios_settings": "assets/icons/ios/icon-29x29.png",
  "ios_settings_2x": "assets/icons/ios/icon-29x29@2x.png",
  "ios_settings_3x": "assets/icons/ios/icon-29x29@3x.png",
  "ios_spotlight": "assets/icons/ios/icon-40x40.png",
  "ios_spotlight_2x": "assets/icons/ios/icon-40x40@2x.png",

  // Android
  "android_mdpi": "assets/icons/android/icon-48x48-mdpi.png",
  "android_hdpi": "assets/icons/android/icon-72x72-hdpi.png",
  "android_xhdpi": "assets/icons/android/icon-96x96-xhdpi.png",
  "android_xxhdpi": "assets/icons/android/icon-144x144-xxhdpi.png",
  "android_xxxhdpi": "assets/icons/android/icon-192x192-xxxhpdi.png"
});

App.launchScreens({
  // iOS
  "iphone_2x": "assets/splash/ios/splash-320x480@2x.png",
  "iphone5": "assets/splash/ios/splash-320x568@2x.png",
  "iphone6": "assets/splash/ios/splash-667h.png",
  "iphone6p_portrait": "assets/splash/ios/splash-1242h-portrait.png",
  "iphone6p_landscape": "assets/splash/ios/splash-1242h-landscape.png",
  "ipad_portrait": "assets/splash/ios/splash-768x1024.png",
  "ipad_portrait_2x": "assets/splash/ios/splash-768x1024@2x.png",
  "ipad_landscape": "assets/splash/ios/splash-1024x768.png",
  "ipad_landscape_2x": "assets/splash/ios/splash-1024x768@2x.png",

  // Android
  "android_mdpi_portrait": "assets/splash/android/splash-320x470.png",
  "android_mdpi_landscape": "assets/splash/android/splash-470x320.png",
  "android_hdpi_portrait": "assets/splash/android/splash-480x640.png",
  "android_hdpi_landscape": "assets/splash/android/splash-640x480.png",
  "android_xhdpi_portrait": "assets/splash/android/splash-720x960.png",
  "android_xhdpi_landscape": "assets/splash/android/splash-960x720.png",
  "android_xxhdpi_portrait": "assets/splash/android/splash-1080x1440.png",
  "android_xxhdpi_landscape": "assets/splash/android/splash-1440x1080.png"
});

App.accessRule("*");

App.setPreference("EnableBitcode", false);
App.setPreference("ShowSplashScreenSpinner", false);
App.setPreference("SplashMaintainAspectRatio", true);

App.setPreference("StatusBarBackgroundColor", "#6bac43");
App.setPreference("StatusBarStyle", "lightcontent");

App.setPreference("Orientation", "portrait");
<|endoftext|>