<commit_before>'use strict';

const VERSION = require('../package.json').version;
const net     = require('net');
const debug   = require('debug')('instrumental');

// config constants
const DEFAULT_HOST = 'collector.instrumentalapp.com';

class Instrumental {

  constructor() {
    this.queuedCalls = [];
    this.enabled = false;
  }

  /**
   * Setup your agent to start reporting metrics.
   * @param {Object} options - configuration options
   * @param {string} options.apiKey - the project api key - see: https://instrumentalapp.com/docs/tokens
   * @param {boolean} [options.enabled=true] - whether to report metrics to Instrumental or simply log them
   * @param {string} [options.host=collector.instrumentalapp.com] - the instrumental collector to which you wish to record metrics
   * @param {number} [options.timeout=undefined] - the socket timeout used by the agent when reporting metrics
   */
  configure(options) {
    this.apiKey  = options.apiKey;
    this.enabled = options.enabled === undefined ? true : options.enabled;
    this.host    = options.host || DEFAULT_HOST;
    this.timeout = options.timeout;
  }

  connect() {
    if (this.socket) { return; }

    debug('Opening Instrumental connection');

    this.socket = new net.Socket();
    this.socket.connect(8000, this.host);

    this.socket.setEncoding('ascii');

    if (this.timeout) { this.socket.setTimeout(this.timeout); }

    this.socket.on('connect', () => {
      debug('Authenticating Instrumental connection');
      this.socket.write('hello version node/instrumental_agent/' + VERSION + '\n' +
                        'authenticate ' + this.apiKey + '\n');
    });

    this.socket.on('timeout', () => {
      debug('Instrumental connection timed out');
      this.disconnect();
    });

    this.socket.on('error', (err) => {
      debug('Connection Error ' + err);
    });

    this.socket.on('close', (hadError) => {
      debug('Closing Instrumental connection - ' + hadError);
      this.disconnect(hadError);
      if (this.queuedCalls.length > 0) {
        setTimeout(() => { this.connect(); }, 5000);
      }
    });

    this.socket.on('data', (data) => {
      if (data === 'ok\nok\n') {
        debug('Instrumental connected!');
        this.connected = true;
        this.socket.write(this.queuedCalls.join('\n'));
        this.queuedCalls = [];
      } else if (data === 'ok\nfail\n') {
        debug('Instrumental authentication failed!');
        this.disconnect();
      } else {
        debug('Unexpected response received - ' + data);
      }
    });
  }

  disconnect(hard) {
    if (!this.socket) { return; }

    if (hard) {
      this.socket.destroy();
    } else {
      this.socket.end();
    }
    this.socket.removeAllListeners();
    this.socket.unref();
    this.connected = false;
    this.socket = null;
  }

  record(metricParts) {
    const line = metricParts.join(' ') + '\n';
    if (this.connected) {
      this.socket.write(line);
    } else {
      if (!this.socket) {
        this.connect();
      }
      if (this.queuedCalls.length > 1000) {
        debug('Queue too large - dropping event');
        return;
      }
      this.queuedCalls.push(line);
    }
  }

  metricApiCallInner(type, metric, value, time, count) {
    if (!metric) {
      debug('Metric name required');
      return;
    }

    value = Number(value);
    if (!isFinite(value)) {
      debug('Metric value is invalid');
      return;
    }

    if (count === null || count === undefined) { count = 1; }
    count = Number(count);
    if (!isFinite(count)) {
      debug('Metric count is invalid');
      return;
    }

    this.record([type, metric, value, time, count]);
  }

  gaugeApiCallInner() { this.metricApiCallInner.apply(this, arguments); }
  incrementApiCallInner() { this.metricApiCallInner.apply(this, arguments); }

  noticeApiCallInner(type, description, duration, time) {
    if (!description) {
      debug('Description required');
      return;
    }

    if (duration === null || duration === undefined) { duration = 0; }
    duration = Number(duration);
    if (duration < 0) {
      debug('duration cannot be negative');
      return;
    }
    if (!isFinite(duration)) {
      debug('duration is invalid');
      return;
    }

    this.record([type, time, duration, description]);
  }

  unixTimeSeconds(time) {
    if (!time) { time = Date.now(); }
    return Math.round(Number(time) / 1000);
  }

  apiCall(type, descriptor, value, time, count) {
    if (!this.enabled) { return; }
    time = this.unixTimeSeconds(time);
    setImmediate(() => { this[`${type}ApiCallInner`](type, descriptor, value, time, count); });
  }

  /**
   * Report an increment metric to Instrumental. See: https://instrumentalapp.com/docs/metrics#metric-types
   * @param {string} metric - metric to be incremented i.e. 'foo.bar'
   * @param {number} [value=1] - amount by which to increment
   * @param {number} [time=Date.now()] - time at which the increment is recorded - format: milliseconds since epoch
   * @param {number} [count=1] - integer number of increments this represents - useful in backfill situations where you report aggregated increment values and counts
   */
  increment(metric, value, time, count) {
    if (value === 0) { return; }
    if (value === null || value === undefined) { value = 1; }
    this.apiCall('increment', metric, value, time, count);
  }

  /**
   * Report a gauge metric to Instrumental. See: https://instrumentalapp.com/docs/metrics#metric-types
   * @param {string} metric - metric being measured i.e. 'foo.bar'
   * @param {number} value - value measured at point in time - for recording multiple (count > 1), the value should be the sum of all the measured points
   * @param {number} [time=Date.now()] - time at which the gauge is recorded - format: milliseconds since epoch
   * @param {integer} [count=1] - integer number of gauges this represents
   */
  gauge(metric, value, time, count) {
    this.apiCall('gauge', metric, value, time, count);
  }

  /**
   * Report a notice to Instrumental. See: https://instrumentalapp.com/docs/notices
   * @param {string} description - text of note to record
   * @param {number} [time=Date.now()] - time at which notice starts - format: milliseconds since epoch
   * @param {number} [duration=0] - the length of time the notice should span - format: seconds notice will span on graphs after the start time
   */
  notice(description, time, duration) {
    this.apiCall('notice', description, duration, time);
  }

}

module.exports = Instrumental;
<commit_msg>Make all socket writes in ASCII since `socket.setEncoding` only controls the read encoding<commit_after>'use strict';

const VERSION = require('../package.json').version;
const net     = require('net');
const debug   = require('debug')('instrumental');

// config constants
const DEFAULT_HOST = 'collector.instrumentalapp.com';

class Instrumental {

  constructor() {
    this.queuedCalls = [];
    this.enabled = false;
  }

  /**
   * Setup your agent to start reporting metrics.
   * @param {Object} options - configuration options
   * @param {string} options.apiKey - the project api key - see: https://instrumentalapp.com/docs/tokens
   * @param {boolean} [options.enabled=true] - whether to report metrics to Instrumental or simply log them
   * @param {string} [options.host=collector.instrumentalapp.com] - the instrumental collector to which you wish to record metrics
   * @param {number} [options.timeout=undefined] - the socket timeout used by the agent when reporting metrics
   */
  configure(options) {
    this.apiKey  = options.apiKey;
    this.enabled = options.enabled === undefined ? true : options.enabled;
    this.host    = options.host || DEFAULT_HOST;
    this.timeout = options.timeout;
  }

  connect() {
    if (this.socket) { return; }

    debug('Opening Instrumental connection');

    this.socket = new net.Socket();
    this.socket.connect(8000, this.host);

    this.socket.setEncoding('ascii');

    if (this.timeout) { this.socket.setTimeout(this.timeout); }

    this.socket.on('connect', () => {
      debug('Authenticating Instrumental connection');
      this.socket.write('hello version node/instrumental_agent/' + VERSION + '\n' +
                        'authenticate ' + this.apiKey + '\n', 'ascii');
    });

    this.socket.on('timeout', () => {
      debug('Instrumental connection timed out');
      this.disconnect();
    });

    this.socket.on('error', (err) => {
      debug('Connection Error ' + err);
    });

    this.socket.on('close', (hadError) => {
      debug('Closing Instrumental connection - ' + hadError);
      this.disconnect(hadError);
      if (this.queuedCalls.length > 0) {
        setTimeout(() => { this.connect(); }, 5000);
      }
    });

    this.socket.on('data', (data) => {
      if (data === 'ok\nok\n') {
        debug('Instrumental connected!');
        this.connected = true;
        this.socket.write(this.queuedCalls.join('\n'), 'ascii');
        this.queuedCalls = [];
      } else if (data === 'ok\nfail\n') {
        debug('Instrumental authentication failed!');
        this.disconnect();
      } else {
        debug('Unexpected response received - ' + data);
      }
    });
  }

  disconnect(hard) {
    if (!this.socket) { return; }

    if (hard) {
      this.socket.destroy();
    } else {
      this.socket.end();
    }
    this.socket.removeAllListeners();
    this.socket.unref();
    this.connected = false;
    this.socket = null;
  }

  record(metricParts) {
    const line = metricParts.join(' ') + '\n';
    if (this.connected) {
      this.socket.write(line, 'ascii');
    } else {
      if (!this.socket) {
        this.connect();
      }
      if (this.queuedCalls.length > 1000) {
        debug('Queue too large - dropping event');
        return;
      }
      this.queuedCalls.push(line);
    }
  }

  metricApiCallInner(type, metric, value, time, count) {
    if (!metric) {
      debug('Metric name required');
      return;
    }

    value = Number(value);
    if (!isFinite(value)) {
      debug('Metric value is invalid');
      return;
    }

    if (count === null || count === undefined) { count = 1; }
    count = Number(count);
    if (!isFinite(count)) {
      debug('Metric count is invalid');
      return;
    }

    this.record([type, metric, value, time, count]);
  }

  gaugeApiCallInner() { this.metricApiCallInner.apply(this, arguments); }
  incrementApiCallInner() { this.metricApiCallInner.apply(this, arguments); }

  noticeApiCallInner(type, description, duration, time) {
    if (!description) {
      debug('Description required');
      return;
    }

    if (duration === null || duration === undefined) { duration = 0; }
    duration = Number(duration);
    if (duration < 0) {
      debug('duration cannot be negative');
      return;
    }
    if (!isFinite(duration)) {
      debug('duration is invalid');
      return;
    }

    this.record([type, time, duration, description]);
  }

  unixTimeSeconds(time) {
    if (!time) { time = Date.now(); }
    return Math.round(Number(time) / 1000);
  }

  apiCall(type, descriptor, value, time, count) {
    if (!this.enabled) { return; }
    time = this.unixTimeSeconds(time);
    setImmediate(() => { this[`${type}ApiCallInner`](type, descriptor, value, time, count); });
  }

  /**
   * Report an increment metric to Instrumental. See: https://instrumentalapp.com/docs/metrics#metric-types
   * @param {string} metric - metric to be incremented i.e. 'foo.bar'
   * @param {number} [value=1] - amount by which to increment
   * @param {number} [time=Date.now()] - time at which the increment is recorded - format: milliseconds since epoch
   * @param {number} [count=1] - integer number of increments this represents - useful in backfill situations where you report aggregated increment values and counts
   */
  increment(metric, value, time, count) {
    if (value === 0) { return; }
    if (value === null || value === undefined) { value = 1; }
    this.apiCall('increment', metric, value, time, count);
  }

  /**
   * Report a gauge metric to Instrumental. See: https://instrumentalapp.com/docs/metrics#metric-types
   * @param {string} metric - metric being measured i.e. 'foo.bar'
   * @param {number} value - value measured at point in time - for recording multiple (count > 1), the value should be the sum of all the measured points
   * @param {number} [time=Date.now()] - time at which the gauge is recorded - format: milliseconds since epoch
   * @param {integer} [count=1] - integer number of gauges this represents
   */
  gauge(metric, value, time, count) {
    this.apiCall('gauge', metric, value, time, count);
  }

  /**
   * Report a notice to Instrumental. See: https://instrumentalapp.com/docs/notices
   * @param {string} description - text of note to record
   * @param {number} [time=Date.now()] - time at which notice starts - format: milliseconds since epoch
   * @param {number} [duration=0] - the length of time the notice should span - format: seconds notice will span on graphs after the start time
   */
  notice(description, time, duration) {
    this.apiCall('notice', description, duration, time);
  }

}

module.exports = Instrumental;
<|endoftext|>


<commit_before><commit_msg>HtS tracking<commit_after><|endoftext|>


<commit_before>/*jslint white: true nomen: true plusplus: true */
/*global mx, mxui, mendix, dojo, require, console, define, module, logger */
/**
	Signature
	========================

	@file      : Signature.js
	@version   : 2.0
	@author    : Maxim Oei, Richard Edens, Roeland Salij
	@date      : 22-08-2014
	@copyright : Mendix Technology BV
	@license   : Apache License, Version 2.0, January 2004

	Documentation
    ========================
	Complete any delivery service App with this Signature widget.
    This widget allows you to save a signature to an attribute.
*/
(function() {
    require([

        'mxui/widget/_WidgetBase', 'dijit/_Widget', 'dijit/_TemplatedMixin',
        'mxui/dom', 'dojo/dom', 'dojo/dom-construct', 'dojo/ready', 'dojo/query', 'dojo/dom-prop', 'dojo/dom-geometry', 'dojo/dom-class', 'dojo/dom-style', 'dojo/on', 'dojo/_base/lang', 'dojo/_base/declare', 'dojo/text'

    ], function(_WidgetBase, _Widget, _Templated, domMx,dom, domConstruct, domReady, domQuery, domProp, domGeom, domClass, domStyle, on, lang, declare, text) {

        return declare('Signature.widget.Signature', [ _WidgetBase, _Widget, _Templated ], {
            _contextGuid: null,
            _contextObj: null,
            _handle: null,

            _smoothingpct: 0.9,

            _mxObject: null,
            _attribute: null,
            _path: null,

            _canvas: null,
            _reset: null,
            _context: null,

            _timer: null,

            _touchSupport: false,
            _bezierBuf: null,

            templatePath: dojo.moduleUrl('Signature', 'widget/templates/Signature.html'),

            postCreate: function() {
                console.log('Signature - postCreate');

                this._setupWidget();
                this._createUI();
                this._setupEvents();
            },

            startup: function() {
                this.set('disabled', this.readonly);

                var path = this.dataUrl.split('/');
                this._attribute = path[path.length - 1];
                this._path = path.splice(0, path.length - 1);
            },

            update: function(obj, callback) {
                if (obj) {
                    obj.fetch(this._path, dojo.hitch(this, function(obj) {
                        this._updateObject(obj, callback);
                    }));
                } else {
                    this._updateObject(null, callback);
                }
            },

            enable: function() {
                dojo.attr(this._reset, 'disabled', false);
                dojo.removeClass(this.domNode, 'signhereSignature_disabled');
            },

            disable: function() {
                dojo.attr(this._reset, 'disabled', true);
                dojo.addClass(this.domNode, 'signhereSignature_disabled');
            },

            _setupWidget: function() {
                var t = this._smoothingpct,
                    u = 1 - t;

                this._bezier1 = t * t * t;
                this._bezier2 = 3 * t * t * u;
                this._bezier3 = 3 * t * u * u;
                this._bezier4 = u * u * u;

                this._bezierBuf = [];

                this._touchSupport = window.hasOwnProperty('ontouchstart');
            },

            _createUI: function() {
                var $ = domConstruct.create,
                    sizeProperties = {
                        'width': this.width + 'px',
                        'height': this.height + 'px'
                    },
                    allProperties = lang.mixin(sizeProperties, {
                        'style': 'border: ' + this.gridborder + 'px solid ' + this.gridcolor
                    });

                this._canvas = $('canvas', allProperties);
                this._image  = $('img', allProperties);

                this._reset = $('button', {
                    'class': 'btn',
                    'style': {
                        'width': (this.width + 4) + 'px'
                    },
                    'innerHTML':  this.resetcaption
                });

                this.domNode.appendChild(this._canvas);
                this.domNode.appendChild(this._image);
                this.domNode.appendChild(this._reset);

                domStyle.set(this.domNode, sizeProperties);

                this._context = this._canvas.getContext('2d');
            },

            _updateObject: function(obj, callback) {
                this._mxObject = obj;

                this._resetCanvas();

                if (this._attribute && obj && obj.get(this._attribute)) {
                    this._showImage();
                } else {
                    this._hideImage();
                }

                this.set('disabled', obj ? false : true);

                mendix.lang.nullExec(callback);
            },

            _showImage: function() {
                this._image.src = this._mxObject.get(this.dataUrl);

                dojo.replaceClass(this.domNode, 'signature_set', 'signature_unset');
            },

            _hideImage: function() {
                this._image.src = '';

                domClass.replace(this.domNode, 'signature_unset', 'signature_set');
            },

            _drawGrid: function() {
                if (!this.showgrid) {
                    return;
                }

                var x = this.gridx,
                    y = this.gridy,
                    context = this._context,
                    width   = this._canvas.width,
                    height  = this._canvas.height;

                context.beginPath();

                for (x; x < width; x += this.gridx) {
                    context.moveTo(x, 0);
                    context.lineTo(x, this._canvas.height);
                }

                for (y; y < height; y += this.gridy) {
                    context.moveTo(0, y);
                    context.lineTo(this._canvas.width, y);
                }

                context.lineWidth   = 1;
                context.strokeStyle = this.gridcolor;
                context.stroke();
            },

            _setupEvents: function() {
                this.connect(this._canvas, (this._touchSupport ? 'touchstart' : 'mousedown'), '_eventMouseDown');
                this.connect(this._reset, 'click', dojo.hitch(this, this._eventResetClicked));

                // This prevents the 'dragging image' annoyance when someone tries to
                // draw on the image.
                this.connect(
                    this._image,
                    this._touchSupport ? 'touchstart' : 'mousedown',
                    function(e) {
                        dojo.stopEvent(e);
                        return false;
                    }
                );
            },

            _getCoords: function(e) {
                var pos   = dojo.position(this._canvas, true),
                    pageX = e.targetTouches ? e.targetTouches[0].pageX : e.pageX,
                    pageY = e.targetTouches ? e.targetTouches[0].pageY : e.pageY,
                    x     = Math.floor(pageX - pos.x),
                    y     = Math.floor(pageY - pos.y);

                return { x: x, y: y };
            },

            _beginCurve: function(e) {
                this._bezierBuf = [];
                this._handlers = [];

                this._stopTimeout();

                this._context.strokeStyle = this.pencolor;
                this._context.lineJoin    = 'round';
                this._context.lineWidth   = this.pensize;

                this._context.beginPath();

                this._handlers.push(this.connect(window, this._touchSupport ? 'touchmove' : 'mousemove', dojo.hitch(this, this._eventMouseMove)));
                this._handlers.push(this.connect(window, this._touchSupport ? 'touchend' : 'mouseup', dojo.hitch(this, this._eventMouseUp)));
            },

            _updateCurve: function(e) {
                console.log(this.id + '.updateCurve');

                var context = this._context,
                    buf = this._bezierBuf,
                    pos = this._getCoords(e),
                    bp = null;

                this._stopTimeout();

                if (this._movedTo) {
                    buf.push(pos);

                    if (buf.length === 4) {
                        bp = this._bezierPoint.apply(this, buf);

                        context.lineTo(bp.x, bp.y);
                        context.stroke();

                        buf.shift();
                        buf[0] = bp;
                    }
                } else {
                    context.moveTo(pos.x, pos.y);
                    this._movedTo = true;
                }
            },

            _endCurve: function() {
                var buf = this._bezierBuf,
                    i = 0,
                    pos = null,
                    j = 0,
                    handlers = null;

                this._stopTimeout();

                // Finish last points in Bezier buffer
                while(buf[i]) {
                    pos = buf[i];
                    this._context.lineTo(pos.x, pos.y);
                    i++;
                }
                this._context.stroke();

                this._bezierBuf = null;

                while(this._handlers[j]){
                    handlers = this._handlers[j];
                    this.disconnect(handlers);
                    j++;
                }

                this._timer = setTimeout(dojo.hitch(this, this._finalizeSignature), this.timeout);
            },

            _eventMouseDown: function(e) {
                console.log(this.id + '._eventMouseDown');

                dojo.stopEvent(e);

                if (!this.get('disabled')) {
                    this._beginCurve(e);
                }
            },

            _eventMouseMove: function(e) {
                console.log(this.id + '._eventMouseMove');

                dojo.stopEvent(e);

                this._updateCurve(e);
            },

            _eventMouseUp: function(e) {
                console.log(this.id + '._eventMouseUp');

                dojo.stopEvent(e);

                this._endCurve();
            },

            _eventResetClicked: function(e) {
                console.log(this.id + '._eventResetClicked');

                if (!this.get('disabled')) {
                    this._resetMxObject();
                    this._resetCanvas();

                    this._hideImage();
                }
            },

            _resetCanvas: function() {
                console.log(this.id + '.resetCanvas');

                this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);

                this._bezierBuf = [];

                this._drawGrid();
            },

            _resetMxObject: function() {
                console.log(this.id + '.resetMxObject');

                this._mxObject.set(this.dataUrl, '');
            },

            _stopTimeout: function() {
                console.log(this.id + '._stopTimeout');

                if (this._timer) {
                    clearTimeout(this._timer);
                }
            },

            _finalizeSignature: function() {
                console.log(this.id + '.finalizeSignature');

                var mxobj = this._mxObject;
                if (mxobj) {
                    if (mxobj.has(this.dataUrl)) {
                        mxobj.set(this.dataUrl, this._canvas.toDataURL());
                    } else {
                        logger.error(this.id + '.finalizeSignature: no dataUrl attribute found.');
                    }
                }

                this._showImage();
            },

            _bezierPoint: function(c1, c2, c3, c4) {
                return {
                    x: c1.x * this._bezier1 + c2.x * this._bezier2 +
                        c3.x * this._bezier3 + c4.x * this._bezier4,
                    y: c1.y * this._bezier1 + c2.y * this._bezier2 +
                        c3.y * this._bezier3 + c4.y * this._bezier4
                };
            },

            _setDisabledAttr: function(value) {
                var argumentsCopy = [];

                if (typeof this._attribute === 'undefined' || this._attribute === null) {
                    this._attribute = '';
                }
                if (this.readonly || !this._mxObject || this._mxObject.isReadonlyAttr(this._attribute)) {
                    value = true;
                }

                return this.inherited(arguments, [ value ]);
            }
        });
    });
}());<commit_msg>Remove unused dependency on dojo/text<commit_after>/*jslint white: true nomen: true plusplus: true */
/*global mx, mxui, mendix, dojo, require, console, define, module, logger */
/**
	Signature
	========================

	@file      : Signature.js
	@version   : 2.0
	@author    : Maxim Oei, Richard Edens, Roeland Salij
	@date      : 22-08-2014
	@copyright : Mendix Technology BV
	@license   : Apache License, Version 2.0, January 2004

	Documentation
    ========================
	Complete any delivery service App with this Signature widget.
    This widget allows you to save a signature to an attribute.
*/
(function() {
    require([
        'mxui/widget/_WidgetBase', 'dijit/_Widget', 'dijit/_TemplatedMixin',
        'mxui/dom', 'dojo/dom', 'dojo/dom-construct', 'dojo/ready', 'dojo/query', 'dojo/dom-prop', 'dojo/dom-geometry', 'dojo/dom-class', 'dojo/dom-style', 'dojo/on', 'dojo/_base/lang', 'dojo/_base/declare'
    ], function(_WidgetBase, _Widget, _Templated, domMx,dom, domConstruct, domReady, domQuery, domProp, domGeom, domClass, domStyle, on, lang, declare) {

        return declare('Signature.widget.Signature', [ _WidgetBase, _Widget, _Templated ], {
            _contextGuid: null,
            _contextObj: null,
            _handle: null,

            _smoothingpct: 0.9,

            _mxObject: null,
            _attribute: null,
            _path: null,

            _canvas: null,
            _reset: null,
            _context: null,

            _timer: null,

            _touchSupport: false,
            _bezierBuf: null,

            templatePath: dojo.moduleUrl('Signature', 'widget/templates/Signature.html'),

            postCreate: function() {
                console.log('Signature - postCreate');

                this._setupWidget();
                this._createUI();
                this._setupEvents();
            },

            startup: function() {
                this.set('disabled', this.readonly);

                var path = this.dataUrl.split('/');
                this._attribute = path[path.length - 1];
                this._path = path.splice(0, path.length - 1);
            },

            update: function(obj, callback) {
                if (obj) {
                    obj.fetch(this._path, dojo.hitch(this, function(obj) {
                        this._updateObject(obj, callback);
                    }));
                } else {
                    this._updateObject(null, callback);
                }
            },

            enable: function() {
                dojo.attr(this._reset, 'disabled', false);
                dojo.removeClass(this.domNode, 'signhereSignature_disabled');
            },

            disable: function() {
                dojo.attr(this._reset, 'disabled', true);
                dojo.addClass(this.domNode, 'signhereSignature_disabled');
            },

            _setupWidget: function() {
                var t = this._smoothingpct,
                    u = 1 - t;

                this._bezier1 = t * t * t;
                this._bezier2 = 3 * t * t * u;
                this._bezier3 = 3 * t * u * u;
                this._bezier4 = u * u * u;

                this._bezierBuf = [];

                this._touchSupport = window.hasOwnProperty('ontouchstart');
            },

            _createUI: function() {
                var $ = domConstruct.create,
                    sizeProperties = {
                        'width': this.width + 'px',
                        'height': this.height + 'px'
                    },
                    allProperties = lang.mixin(sizeProperties, {
                        'style': 'border: ' + this.gridborder + 'px solid ' + this.gridcolor
                    });

                this._canvas = $('canvas', allProperties);
                this._image  = $('img', allProperties);

                this._reset = $('button', {
                    'class': 'btn',
                    'style': {
                        'width': (this.width + 4) + 'px'
                    },
                    'innerHTML':  this.resetcaption
                });

                this.domNode.appendChild(this._canvas);
                this.domNode.appendChild(this._image);
                this.domNode.appendChild(this._reset);

                domStyle.set(this.domNode, sizeProperties);

                this._context = this._canvas.getContext('2d');
            },

            _updateObject: function(obj, callback) {
                this._mxObject = obj;

                this._resetCanvas();

                if (this._attribute && obj && obj.get(this._attribute)) {
                    this._showImage();
                } else {
                    this._hideImage();
                }

                this.set('disabled', obj ? false : true);

                mendix.lang.nullExec(callback);
            },

            _showImage: function() {
                this._image.src = this._mxObject.get(this.dataUrl);

                dojo.replaceClass(this.domNode, 'signature_set', 'signature_unset');
            },

            _hideImage: function() {
                this._image.src = '';

                domClass.replace(this.domNode, 'signature_unset', 'signature_set');
            },

            _drawGrid: function() {
                if (!this.showgrid) {
                    return;
                }

                var x = this.gridx,
                    y = this.gridy,
                    context = this._context,
                    width   = this._canvas.width,
                    height  = this._canvas.height;

                context.beginPath();

                for (x; x < width; x += this.gridx) {
                    context.moveTo(x, 0);
                    context.lineTo(x, this._canvas.height);
                }

                for (y; y < height; y += this.gridy) {
                    context.moveTo(0, y);
                    context.lineTo(this._canvas.width, y);
                }

                context.lineWidth   = 1;
                context.strokeStyle = this.gridcolor;
                context.stroke();
            },

            _setupEvents: function() {
                this.connect(this._canvas, (this._touchSupport ? 'touchstart' : 'mousedown'), '_eventMouseDown');
                this.connect(this._reset, 'click', dojo.hitch(this, this._eventResetClicked));

                // This prevents the 'dragging image' annoyance when someone tries to
                // draw on the image.
                this.connect(
                    this._image,
                    this._touchSupport ? 'touchstart' : 'mousedown',
                    function(e) {
                        dojo.stopEvent(e);
                        return false;
                    }
                );
            },

            _getCoords: function(e) {
                var pos   = dojo.position(this._canvas, true),
                    pageX = e.targetTouches ? e.targetTouches[0].pageX : e.pageX,
                    pageY = e.targetTouches ? e.targetTouches[0].pageY : e.pageY,
                    x     = Math.floor(pageX - pos.x),
                    y     = Math.floor(pageY - pos.y);

                return { x: x, y: y };
            },

            _beginCurve: function(e) {
                this._bezierBuf = [];
                this._handlers = [];

                this._stopTimeout();

                this._context.strokeStyle = this.pencolor;
                this._context.lineJoin    = 'round';
                this._context.lineWidth   = this.pensize;

                this._context.beginPath();

                this._handlers.push(this.connect(window, this._touchSupport ? 'touchmove' : 'mousemove', dojo.hitch(this, this._eventMouseMove)));
                this._handlers.push(this.connect(window, this._touchSupport ? 'touchend' : 'mouseup', dojo.hitch(this, this._eventMouseUp)));
            },

            _updateCurve: function(e) {
                console.log(this.id + '.updateCurve');

                var context = this._context,
                    buf = this._bezierBuf,
                    pos = this._getCoords(e),
                    bp = null;

                this._stopTimeout();

                if (this._movedTo) {
                    buf.push(pos);

                    if (buf.length === 4) {
                        bp = this._bezierPoint.apply(this, buf);

                        context.lineTo(bp.x, bp.y);
                        context.stroke();

                        buf.shift();
                        buf[0] = bp;
                    }
                } else {
                    context.moveTo(pos.x, pos.y);
                    this._movedTo = true;
                }
            },

            _endCurve: function() {
                var buf = this._bezierBuf,
                    i = 0,
                    pos = null,
                    j = 0,
                    handlers = null;

                this._stopTimeout();

                // Finish last points in Bezier buffer
                while(buf[i]) {
                    pos = buf[i];
                    this._context.lineTo(pos.x, pos.y);
                    i++;
                }
                this._context.stroke();

                this._bezierBuf = null;

                while(this._handlers[j]){
                    handlers = this._handlers[j];
                    this.disconnect(handlers);
                    j++;
                }

                this._timer = setTimeout(dojo.hitch(this, this._finalizeSignature), this.timeout);
            },

            _eventMouseDown: function(e) {
                console.log(this.id + '._eventMouseDown');

                dojo.stopEvent(e);

                if (!this.get('disabled')) {
                    this._beginCurve(e);
                }
            },

            _eventMouseMove: function(e) {
                console.log(this.id + '._eventMouseMove');

                dojo.stopEvent(e);

                this._updateCurve(e);
            },

            _eventMouseUp: function(e) {
                console.log(this.id + '._eventMouseUp');

                dojo.stopEvent(e);

                this._endCurve();
            },

            _eventResetClicked: function(e) {
                console.log(this.id + '._eventResetClicked');

                if (!this.get('disabled')) {
                    this._resetMxObject();
                    this._resetCanvas();

                    this._hideImage();
                }
            },

            _resetCanvas: function() {
                console.log(this.id + '.resetCanvas');

                this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);

                this._bezierBuf = [];

                this._drawGrid();
            },

            _resetMxObject: function() {
                console.log(this.id + '.resetMxObject');

                this._mxObject.set(this.dataUrl, '');
            },

            _stopTimeout: function() {
                console.log(this.id + '._stopTimeout');

                if (this._timer) {
                    clearTimeout(this._timer);
                }
            },

            _finalizeSignature: function() {
                console.log(this.id + '.finalizeSignature');

                var mxobj = this._mxObject;
                if (mxobj) {
                    if (mxobj.has(this.dataUrl)) {
                        mxobj.set(this.dataUrl, this._canvas.toDataURL());
                    } else {
                        logger.error(this.id + '.finalizeSignature: no dataUrl attribute found.');
                    }
                }

                this._showImage();
            },

            _bezierPoint: function(c1, c2, c3, c4) {
                return {
                    x: c1.x * this._bezier1 + c2.x * this._bezier2 +
                        c3.x * this._bezier3 + c4.x * this._bezier4,
                    y: c1.y * this._bezier1 + c2.y * this._bezier2 +
                        c3.y * this._bezier3 + c4.y * this._bezier4
                };
            },

            _setDisabledAttr: function(value) {
                var argumentsCopy = [];

                if (typeof this._attribute === 'undefined' || this._attribute === null) {
                    this._attribute = '';
                }
                if (this.readonly || !this._mxObject || this._mxObject.isReadonlyAttr(this._attribute)) {
                    value = true;
                }

                return this.inherited(arguments, [ value ]);
            }
        });
    });
}());<|endoftext|>


<commit_before>require('dotenv').config();

const {DATABASE_URL} = process.env

module.exports = {
  production: {
    url: DATABASE_URL,
    dialect: "postgres",
  },
  development: {
    url: "postgres://respass:@localhost/respass-dev",
    dialect: "postgres",
  },
  test: {
    url: "postgres://respass:@localhost/respass-test",
    dialect: "postgres",
  },
}
<commit_msg>silent dotenv if .env is missing<commit_after>require('dotenv').config({silent: true});

const {DATABASE_URL} = process.env

module.exports = {
  production: {
    url: DATABASE_URL,
    dialect: "postgres",
  },
  development: {
    url: "postgres://respass:@localhost/respass-dev",
    dialect: "postgres",
  },
  test: {
    url: "postgres://respass:@localhost/respass-test",
    dialect: "postgres",
  },
}
<|endoftext|>


<commit_before>/*jslint white: true nomen: true plusplus: true */
/*global mx, mxui, window, document, mendix, dojo, require, console, define, module, logger */
/**
	Signature
	========================
	@copyright : Mendix bv
	@license   : Apache License, Version 2.0, January 2004
*/
require([
    "mxui/widget/_WidgetBase",
    "dijit/_Widget",
    "dijit/_TemplatedMixin",
    "mxui/dom",
    "dojo/dom",
    "dojo/dom-construct",
    "dojo/_base/event",
    "dojo/ready",
    "dojo/query",
    "dojo/dom-prop",
    "dojo/dom-geometry",
    "dojo/dom-class",
    "dojo/dom-style",
    "dojo/touch",
    "dojo/on",
    "dojo/_base/lang",
    "dojo/_base/declare"
], function(_WidgetBase, _Widget, _Templated, domMx, dom, domConstruct, domEvent, domReady, domQuery, domProp, domGeom, domClass, domStyle, dojoTouch, on, lang, declare) {

    return declare("Signature.widget.Signature", [ _WidgetBase, _Widget, _Templated ], {
        _contextGuid: null,
        _contextObj: null,
        _handle: null,

        _smoothingpct: 0.9,

        _mxObject: null,
        _attribute: null,
        _path: null,

        _canvas: null,
        _reset: null,
        _context: null,

        _timer: null,
        _bezierBuf: null,

        templatePath: dojo.moduleUrl("Signature", "widget/templates/Signature.html"),

        postCreate: function() {
            this._setupWidget();
            this._createUI();
            this._setupEvents();
        },

        startup: function() {
            this.set("disabled", this.readonly);

            var path = this.dataUrl.split("/");
            this._attribute = path[path.length - 1];
            this._path = path.splice(0, path.length - 1);
        },

        update: function(obj, callback) {
            if (obj) {
                obj.fetch(this._path, dojo.hitch(this, function(obj) {
                    this._updateObject(obj, callback);
                }));
            } else {
                this._updateObject(null, callback);
            }
        },

        enable: function() {
            dojo.attr(this._reset, "disabled", false);
            dojo.removeClass(this.domNode, "signhereSignature_disabled");
        },

        disable: function() {
            dojo.attr(this._reset, "disabled", true);
            dojo.addClass(this.domNode, "signhereSignature_disabled");
        },

        _setupWidget: function() {
            var t = this._smoothingpct,
                u = 1 - t;

            this._bezier1 = t * t * t;
            this._bezier2 = 3 * t * t * u;
            this._bezier3 = 3 * t * u * u;
            this._bezier4 = u * u * u;

            this._bezierBuf = [];
        },

        _createUI: function() {
            var $ = domConstruct.create,
                sizeProperties = {
                    "width": this.width + "px",
                    "height": this.height + "px"
                },
                allProperties = lang.mixin(sizeProperties, {
                    "style": "border: " + this.gridborder + "px solid " + this.gridcolor
                });

            this._canvas = $("canvas", allProperties);
            this._image  = $("img", allProperties);

            this._reset = $("button", {
                "class": "btn",
                "style": {
                    "width": (this.width + 4) + "px"
                },
                "innerHTML":  this.resetcaption
            });

            this.domNode.appendChild(this._canvas);
            this.domNode.appendChild(this._image);
            this.domNode.appendChild(this._reset);

            domStyle.set(this.domNode, sizeProperties);

            this._context = this._canvas.getContext("2d");
        },

        _updateObject: function(obj, callback) {
            this._mxObject = obj;

            this._resetCanvas();

            if (this._attribute && obj && obj.get(this._attribute)) {
                this._showImage();
            } else {
                this._hideImage();
            }

            this.set("disabled", obj ? false : true);

            mendix.lang.nullExec(callback);
        },

        _showImage: function() {
            this._image.src = this._mxObject.get(this.dataUrl);

            dojo.replaceClass(this.domNode, "signature_set", "signature_unset");
        },

        _hideImage: function() {
            this._image.src = "";

            domClass.replace(this.domNode, "signature_unset", "signature_set");
        },

        _drawGrid: function() {
            if (!this.showgrid) return;

            var x = this.gridx,
                y = this.gridy,
                context = this._context,
                width   = this._canvas.width,
                height  = this._canvas.height;

            context.beginPath();

            for (; x < width; x += this.gridx) {
                context.moveTo(x, 0);
                context.lineTo(x, this._canvas.height);
            }

            for (; y < height; y += this.gridy) {
                context.moveTo(0, y);
                context.lineTo(this._canvas.width, y);
            }

            context.lineWidth = 1;
            context.strokeStyle = this.gridcolor;
            context.stroke();
        },

        _setupEvents: function() {
            on(this._canvas, dojoTouch.press, lang.hitch(this, this._beginCurve));
            on(this._reset, "click", lang.hitch(this, this._eventResetClicked));

            // This prevents the "dragging image" annoyance when someone tries to
            // draw on the image.
            on(this._image, dojoTouch.press, function(e) {
                domEvent.stop(e);
                return false;
            });
        },

        _getCoords: function(e) {
            var pos   = dojo.position(this._canvas, true),
                pageX = e.targetTouches ? e.targetTouches[0].pageX : e.pageX,
                pageY = e.targetTouches ? e.targetTouches[0].pageY : e.pageY,
                x     = Math.floor(pageX - pos.x),
                y     = Math.floor(pageY - pos.y);

            return { x: x, y: y };
        },

        _beginCurve: function(e) {
            domEvent.stop(e);

            if (this.get("disabled")) return;

            this._bezierBuf = [];

            this._stopTimeout();

            this._context.strokeStyle = this.pencolor;
            this._context.lineJoin    = "round";
            this._context.lineWidth   = this.pensize;

            this._context.beginPath();

            this._handlers = [
                on(window, dojoTouch.move, lang.hitch(this, this._updateCurve)),
                on(window, dojoTouch.release, lang.hitch(this, this._endCurve))
            ];
        },

        _updateCurve: function(e) {
            domEvent.stop(e);

            var context = this._context,
                buf = this._bezierBuf,
                pos = this._getCoords(e),
                bp = null;

            this._stopTimeout();

            if (this._movedTo) {
                buf.push(pos);

                if (buf.length === 4) {
                    bp = this._bezierPoint.apply(this, buf);

                    context.lineTo(bp.x, bp.y);
                    context.stroke();

                    buf.shift();
                    buf[0] = bp;
                }
            } else {
                context.moveTo(pos.x, pos.y);
                this._movedTo = true;
            }
        },

        _endCurve: function() {
            domEvent.stop(e);

            this._stopTimeout();

            // Finish last points in Bezier buffer
            dojoArray.forEach(this._bezierBuf, function(position) {
                this._context.lineTo(position.x, position.y);
            }, this);

            this._context.stroke();

            dojoArray.forEach(this._handlers, function(handler) {
                handler.remove();
            });

            this._timer = setTimeout(dojo.hitch(this, this._finalizeSignature), this.timeout);
        },

        _eventResetClicked: function(e) {
            if (!this.get("disabled")) {
                this._resetMxObject();
                this._resetCanvas();

                this._hideImage();
            }
        },

        _resetCanvas: function() {
            this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);

            this._bezierBuf = [];

            this._drawGrid();
        },

        _resetMxObject: function() {
            this._mxObject.set(this.dataUrl, "");
        },

        _stopTimeout: function() {
            if (this._timer) {
                clearTimeout(this._timer);
            }
        },

        _finalizeSignature: function() {
            var mxobj = this._mxObject;
            if (mxobj) {
                if (mxobj.has(this.dataUrl)) {
                    mxobj.set(this.dataUrl, this._canvas.toDataURL());
                } else {
                    logger.error(this.id + ".finalizeSignature: no dataUrl attribute found.");
                }
            }

            this._showImage();
        },

        _bezierPoint: function(c1, c2, c3, c4) {
            return {
                x: c1.x * this._bezier1 + c2.x * this._bezier2 +
                    c3.x * this._bezier3 + c4.x * this._bezier4,
                y: c1.y * this._bezier1 + c2.y * this._bezier2 +
                    c3.y * this._bezier3 + c4.y * this._bezier4
            };
        },

        _setDisabledAttr: function(value) {
            var isDisabled = this.readonly ||
                !this._mxObject ||
                !this._attribute ||
                this._mxObject.isReadonlyAttr(this._attribute) ||
                value;
            return this.inherited(arguments, [ isDisabled ]);
        }
    });
});
<commit_msg>Inline a number of variables<commit_after>/*jslint white: true nomen: true plusplus: true */
/*global mx, mxui, window, document, mendix, dojo, require, console, define, module, logger */
/**
	Signature
	========================
	@copyright : Mendix bv
	@license   : Apache License, Version 2.0, January 2004
*/
require([
    "mxui/widget/_WidgetBase",
    "dijit/_Widget",
    "dijit/_TemplatedMixin",
    "mxui/dom",
    "dojo/dom",
    "dojo/dom-construct",
    "dojo/_base/event",
    "dojo/ready",
    "dojo/query",
    "dojo/dom-prop",
    "dojo/dom-geometry",
    "dojo/dom-class",
    "dojo/dom-style",
    "dojo/touch",
    "dojo/on",
    "dojo/_base/lang",
    "dojo/_base/declare"
], function(_WidgetBase, _Widget, _Templated, domMx, dom, domConstruct, domEvent, domReady, domQuery, domProp, domGeom, domClass, domStyle, dojoTouch, on, lang, declare) {

    return declare("Signature.widget.Signature", [ _WidgetBase, _Widget, _Templated ], {
        _contextGuid: null,
        _contextObj: null,
        _handle: null,

        _smoothingpct: 0.9,

        _mxObject: null,
        _attribute: null,
        _path: null,

        _canvas: null,
        _reset: null,
        _context: null,

        _timer: null,
        _bezierBuf: null,

        templatePath: dojo.moduleUrl("Signature", "widget/templates/Signature.html"),

        postCreate: function() {
            this._setupWidget();
            this._createUI();
            this._setupEvents();
        },

        startup: function() {
            this.set("disabled", this.readonly);

            var path = this.dataUrl.split("/");
            this._attribute = path[path.length - 1];
            this._path = path.splice(0, path.length - 1);
        },

        update: function(obj, callback) {
            if (obj) {
                obj.fetch(this._path, dojo.hitch(this, function(obj) {
                    this._updateObject(obj, callback);
                }));
            } else {
                this._updateObject(null, callback);
            }
        },

        enable: function() {
            dojo.attr(this._reset, "disabled", false);
            dojo.removeClass(this.domNode, "signhereSignature_disabled");
        },

        disable: function() {
            dojo.attr(this._reset, "disabled", true);
            dojo.addClass(this.domNode, "signhereSignature_disabled");
        },

        _setupWidget: function() {
            var t = this._smoothingpct,
                u = 1 - t;

            this._bezier1 = t * t * t;
            this._bezier2 = 3 * t * t * u;
            this._bezier3 = 3 * t * u * u;
            this._bezier4 = u * u * u;

            this._bezierBuf = [];
        },

        _createUI: function() {
            var $ = domConstruct.create,
                sizeProperties = {
                    "width": this.width + "px",
                    "height": this.height + "px"
                },
                allProperties = lang.mixin(sizeProperties, {
                    "style": "border: " + this.gridborder + "px solid " + this.gridcolor
                });

            this._canvas = $("canvas", allProperties);
            this._image  = $("img", allProperties);

            this._reset = $("button", {
                "class": "btn",
                "style": {
                    "width": (this.width + 4) + "px"
                },
                "innerHTML":  this.resetcaption
            });

            this.domNode.appendChild(this._canvas);
            this.domNode.appendChild(this._image);
            this.domNode.appendChild(this._reset);

            domStyle.set(this.domNode, sizeProperties);

            this._context = this._canvas.getContext("2d");
        },

        _updateObject: function(obj, callback) {
            this._mxObject = obj;

            this._resetCanvas();

            if (this._attribute && obj && obj.get(this._attribute)) {
                this._showImage();
            } else {
                this._hideImage();
            }

            this.set("disabled", obj ? false : true);

            mendix.lang.nullExec(callback);
        },

        _showImage: function() {
            this._image.src = this._mxObject.get(this.dataUrl);

            dojo.replaceClass(this.domNode, "signature_set", "signature_unset");
        },

        _hideImage: function() {
            this._image.src = "";

            domClass.replace(this.domNode, "signature_unset", "signature_set");
        },

        _drawGrid: function() {
            if (!this.showgrid) return;

            var x = this.gridx,
                y = this.gridy,
                context = this._context,
                width   = this._canvas.width,
                height  = this._canvas.height;

            context.beginPath();

            for (; x < width; x += this.gridx) {
                context.moveTo(x, 0);
                context.lineTo(x, this._canvas.height);
            }

            for (; y < height; y += this.gridy) {
                context.moveTo(0, y);
                context.lineTo(this._canvas.width, y);
            }

            context.lineWidth = 1;
            context.strokeStyle = this.gridcolor;
            context.stroke();
        },

        _setupEvents: function() {
            on(this._canvas, dojoTouch.press, lang.hitch(this, this._beginCurve));
            on(this._reset, "click", lang.hitch(this, this._eventResetClicked));

            // This prevents the "dragging image" annoyance when someone tries to
            // draw on the image.
            on(this._image, dojoTouch.press, function(e) {
                domEvent.stop(e);
                return false;
            });
        },

        _getCoords: function(e) {
            var pos   = dojo.position(this._canvas, true),
                pageX = e.targetTouches ? e.targetTouches[0].pageX : e.pageX,
                pageY = e.targetTouches ? e.targetTouches[0].pageY : e.pageY,
                x     = Math.floor(pageX - pos.x),
                y     = Math.floor(pageY - pos.y);

            return { x: x, y: y };
        },

        _beginCurve: function(e) {
            domEvent.stop(e);

            if (this.get("disabled")) return;

            this._bezierBuf = [];

            this._stopTimeout();

            this._context.strokeStyle = this.pencolor;
            this._context.lineJoin    = "round";
            this._context.lineWidth   = this.pensize;

            this._context.beginPath();

            this._handlers = [
                on(window, dojoTouch.move, lang.hitch(this, this._updateCurve)),
                on(window, dojoTouch.release, lang.hitch(this, this._endCurve))
            ];
        },

        _updateCurve: function(e) {
            domEvent.stop(e);

            this._stopTimeout();

            if (this._movedTo) {
                this._bezierBuf.push(this._getCoords(e));

                if (this._bezierBuf.length === 4) {
                    var point = this._bezierPoint.apply(this, this._bezierBuf);

                    this._context.lineTo(point.x, point.y);
                    this._context.stroke();

                    this._bezierBuf.shift();
                    this._bezierBuf[0] = point;
                }
            } else {
                this._context.moveTo(this._getCoords(e).x, this._getCoords(e).y);
                this._movedTo = true;
            }
        },

        _endCurve: function() {
            domEvent.stop(e);

            this._stopTimeout();

            // Finish last points in Bezier buffer
            dojoArray.forEach(this._bezierBuf, function(position) {
                this._context.lineTo(position.x, position.y);
            }, this);

            this._context.stroke();

            dojoArray.forEach(this._handlers, function(handler) {
                handler.remove();
            });

            this._timer = setTimeout(dojo.hitch(this, this._finalizeSignature), this.timeout);
        },

        _eventResetClicked: function(e) {
            if (!this.get("disabled")) {
                this._resetMxObject();
                this._resetCanvas();

                this._hideImage();
            }
        },

        _resetCanvas: function() {
            this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);

            this._bezierBuf = [];

            this._drawGrid();
        },

        _resetMxObject: function() {
            this._mxObject.set(this.dataUrl, "");
        },

        _stopTimeout: function() {
            if (this._timer) {
                clearTimeout(this._timer);
            }
        },

        _finalizeSignature: function() {
            if (this._mxObject) {
                if (this._mxObject.has(this.dataUrl)) {
                    this._mxObject.set(this.dataUrl, this._canvas.toDataURL());
                } else {
                    logger.error(this.id + ".finalizeSignature: no dataUrl attribute found.");
                }
            }

            this._showImage();
        },

        _bezierPoint: function(c1, c2, c3, c4) {
            return {
                x: c1.x * this._bezier1 + c2.x * this._bezier2 +
                    c3.x * this._bezier3 + c4.x * this._bezier4,
                y: c1.y * this._bezier1 + c2.y * this._bezier2 +
                    c3.y * this._bezier3 + c4.y * this._bezier4
            };
        },

        _setDisabledAttr: function(value) {
            var isDisabled = this.readonly ||
                !this._mxObject ||
                !this._attribute ||
                this._mxObject.isReadonlyAttr(this._attribute) ||
                value;
            return this.inherited(arguments, [ isDisabled ]);
        }
    });
});
<|endoftext|>


<commit_before>var DOMAIN = 'http://molgenis27.target.rug.nl';

module.exports.domain = DOMAIN;

module.exports.menuItems = [{
    name: 'HOME',
    route: '/'
}, {
    name: 'HOW IT WORKS',
    route: '/how'
}, {
    name: 'ABOUT',
    route: '/about'
}, {
    name: 'API',
    route: '/api'
}];

module.exports.urls = {
    main: module.exports.domain,
    gene: DOMAIN + '/api/v1/gene',
    genes: DOMAIN + '/api/v1/genes',
    transcript: DOMAIN + '/api/v1/transcript',
    transcriptBars: DOMAIN + '/api/v1/transcriptBars',
    pathway: DOMAIN + '/api/v1/pathway',
    coregulation: DOMAIN + '/api/v1/coregulation',
    tissues: DOMAIN + '/api/v1/tissues',
    cofunction: DOMAIN + '/api/v1/cofunction',
    pc: DOMAIN + '/api/v1/pc',

    suggest: DOMAIN + '/socketapi/suggest',
    diagnosisSuggest: DOMAIN + '/socketapi/diagnosisSuggest',
    pathwayanalysis: DOMAIN + '/socketapi/pathwayanalysis',
    geneprediction: DOMAIN + '/socketapi/geneprediction',
    network: DOMAIN + '/socketapi/network',
    genescores: DOMAIN + '/socketapi/genescores',
    genevsnetwork: DOMAIN + '/socketapi/genevsnetwork',

    prioritization: DOMAIN + '/api/v1/prioritization',

    genePage: DOMAIN + '/gene/',
    termPage: DOMAIN + '/term/',
    networkPage: DOMAIN + '/network/',
    diagnosisPage: DOMAIN + '/diagnosis',

    svg2pdf: DOMAIN + '/api/v1/svg2pdf',
    // diagnosisResults: DOMAIN + '/api/v1/diagnosisResults',
    tabdelim: DOMAIN + '/api/v1/tabdelim',

    diagnosisVCF: DOMAIN + '/api/v1/vcf',
};

module.exports.pageTitleSuffix = ' - Gene Network';
<commit_msg>centralised domain configuration<commit_after>let domain = require('./domain').domain;

module.exports.domain = domain;

module.exports.menuItems = [{
    name: 'HOME',
    route: '/'
}, {
    name: 'HOW IT WORKS',
    route: '/how'
}, {
    name: 'ABOUT',
    route: '/about'
}, {
    name: 'API',
    route: '/api'
}];

module.exports.urls = {
    main: module.exports.domain,
    gene: domain + '/api/v1/gene',
    genes: domain + '/api/v1/genes',
    transcript: domain + '/api/v1/transcript',
    transcriptBars: domain + '/api/v1/transcriptBars',
    pathway: domain + '/api/v1/pathway',
    coregulation: domain + '/api/v1/coregulation',
    tissues: domain + '/api/v1/tissues',
    cofunction: domain + '/api/v1/cofunction',
    pc: domain + '/api/v1/pc',

    suggest: domain + '/socketapi/suggest',
    diagnosisSuggest: domain + '/socketapi/diagnosisSuggest',
    pathwayanalysis: domain + '/socketapi/pathwayanalysis',
    geneprediction: domain + '/socketapi/geneprediction',
    network: domain + '/socketapi/network',
    genescores: domain + '/socketapi/genescores',
    genevsnetwork: domain + '/socketapi/genevsnetwork',

    prioritization: domain + '/api/v1/prioritization',

    genePage: domain + '/gene/',
    termPage: domain + '/term/',
    networkPage: domain + '/network/',
    diagnosisPage: domain + '/diagnosis',

    svg2pdf: domain + '/api/v1/svg2pdf',
    // diagnosisResults: domain + '/api/v1/diagnosisResults',
    tabdelim: domain + '/api/v1/tabdelim',

    diagnosisVCF: domain + '/api/v1/vcf',
};

module.exports.pageTitleSuffix = ' - Gene Network';
<|endoftext|>


<commit_before>/*jslint white: true nomen: true plusplus: true */
/*global mx, mxui, window, document, mendix, dojo, require, console, define, module, logger */
/**
	Signature
	========================

	@file      : Signature.js
	@version   : 2.1
	@author    : Maxim Oei, Richard Edens, Roeland Salij
	@date      : 22-08-2014
	@copyright : Mendix Technology BV
	@license   : Apache License, Version 2.0, January 2004

	Documentation
    ========================
	Complete any delivery service App with this Signature widget.
    This widget allows you to save a signature to an attribute.
*/
(function() {
    require([
        'mxui/widget/_WidgetBase', 'dijit/_Widget', 'dijit/_TemplatedMixin',
        'mxui/dom', 'dojo/dom', 'dojo/dom-construct', 'dojo/_base/event', 'dojo/ready', 'dojo/query', 'dojo/dom-prop', 'dojo/dom-geometry', 'dojo/dom-class', 'dojo/dom-style', 'dojo/on', 'dojo/_base/lang', 'dojo/_base/declare'
    ], function(_WidgetBase, _Widget, _Templated, domMx,dom, domConstruct, domEvent, domReady, domQuery, domProp, domGeom, domClass, domStyle, on, lang, declare) {

        return declare('Signature.widget.Signature', [ _WidgetBase, _Widget, _Templated ], {
            _contextGuid: null,
            _contextObj: null,
            _handle: null,

            _smoothingpct: 0.9,

            _mxObject: null,
            _attribute: null,
            _path: null,

            _canvas: null,
            _reset: null,
            _context: null,

            _timer: null,

            _touchSupport: false,
            _bezierBuf: null,

            templatePath: dojo.moduleUrl('Signature', 'widget/templates/Signature.html'),

            postCreate: function() {
                this._setupWidget();
                this._createUI();
                this._setupEvents();
            },

            startup: function() {
                this.set('disabled', this.readonly);

                var path = this.dataUrl.split('/');
                this._attribute = path[path.length - 1];
                this._path = path.splice(0, path.length - 1);
            },

            update: function(obj, callback) {
                if (obj) {
                    obj.fetch(this._path, dojo.hitch(this, function(obj) {
                        this._updateObject(obj, callback);
                    }));
                } else {
                    this._updateObject(null, callback);
                }
            },

            enable: function() {
                dojo.attr(this._reset, 'disabled', false);
                dojo.removeClass(this.domNode, 'signhereSignature_disabled');
            },

            disable: function() {
                dojo.attr(this._reset, 'disabled', true);
                dojo.addClass(this.domNode, 'signhereSignature_disabled');
            },

            _setupWidget: function() {
                var t = this._smoothingpct,
                    u = 1 - t;

                this._bezier1 = t * t * t;
                this._bezier2 = 3 * t * t * u;
                this._bezier3 = 3 * t * u * u;
                this._bezier4 = u * u * u;

                this._bezierBuf = [];

                this._touchSupport = ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
            },

            _createUI: function() {
                var $ = domConstruct.create,
                    sizeProperties = {
                        'width': this.width + 'px',
                        'height': this.height + 'px'
                    },
                    allProperties = lang.mixin(sizeProperties, {
                        'style': 'border: ' + this.gridborder + 'px solid ' + this.gridcolor
                    });

                this._canvas = $('canvas', allProperties);
                this._image  = $('img', allProperties);

                this._reset = $('button', {
                    'class': 'btn',
                    'style': {
                        'width': (this.width + 4) + 'px'
                    },
                    'innerHTML':  this.resetcaption
                });

                this.domNode.appendChild(this._canvas);
                this.domNode.appendChild(this._image);
                this.domNode.appendChild(this._reset);

                domStyle.set(this.domNode, sizeProperties);

                this._context = this._canvas.getContext('2d');
            },

            _updateObject: function(obj, callback) {
                this._mxObject = obj;

                this._resetCanvas();

                if (this._attribute && obj && obj.get(this._attribute)) {
                    this._showImage();
                } else {
                    this._hideImage();
                }

                this.set('disabled', obj ? false : true);

                mendix.lang.nullExec(callback);
            },

            _showImage: function() {
                this._image.src = this._mxObject.get(this.dataUrl);

                dojo.replaceClass(this.domNode, 'signature_set', 'signature_unset');
            },

            _hideImage: function() {
                this._image.src = '';

                domClass.replace(this.domNode, 'signature_unset', 'signature_set');
            },

            _drawGrid: function() {
                if (!this.showgrid) return;

                var x = this.gridx,
                    y = this.gridy,
                    context = this._context,
                    width   = this._canvas.width,
                    height  = this._canvas.height;

                context.beginPath();

                for (; x < width; x += this.gridx) {
                    context.moveTo(x, 0);
                    context.lineTo(x, this._canvas.height);
                }

                for (; y < height; y += this.gridy) {
                    context.moveTo(0, y);
                    context.lineTo(this._canvas.width, y);
                }

                context.lineWidth = 1;
                context.strokeStyle = this.gridcolor;
                context.stroke();
            },

            _setupEvents: function() {
                this.connect(this._canvas, (this._touchSupport ? 'touchstart' : 'mousedown'), this._beginCurve);
                this.connect(this._reset, 'click', this._eventResetClicked);

                // This prevents the 'dragging image' annoyance when someone tries to
                // draw on the image.
                this.connect(
                    this._image,
                    this._touchSupport ? 'touchstart' : 'mousedown',
                    function(e) {
                        domEvent.stop(e);
                        return false;
                    }
                );
            },

            _getCoords: function(e) {
                var pos   = dojo.position(this._canvas, true),
                    pageX = e.targetTouches ? e.targetTouches[0].pageX : e.pageX,
                    pageY = e.targetTouches ? e.targetTouches[0].pageY : e.pageY,
                    x     = Math.floor(pageX - pos.x),
                    y     = Math.floor(pageY - pos.y);

                return { x: x, y: y };
            },

            _beginCurve: function(e) {
                domEvent.stop(e);

                if (this.get('disabled')) return;

                this._bezierBuf = [];
                this._handlers = [];

                this._stopTimeout();

                this._context.strokeStyle = this.pencolor;
                this._context.lineJoin    = 'round';
                this._context.lineWidth   = this.pensize;

                this._context.beginPath();

                this._handlers.push(this.connect(window, this._touchSupport ? 'touchmove' : 'mousemove', this._updateCurve));
                this._handlers.push(this.connect(window, this._touchSupport ? 'touchend' : 'mouseup', this._endCurve));
            },

            _updateCurve: function(e) {
                domEvent.stop(e);

                var context = this._context,
                    buf = this._bezierBuf,
                    pos = this._getCoords(e),
                    bp = null;

                this._stopTimeout();

                if (this._movedTo) {
                    buf.push(pos);

                    if (buf.length === 4) {
                        bp = this._bezierPoint.apply(this, buf);

                        context.lineTo(bp.x, bp.y);
                        context.stroke();

                        buf.shift();
                        buf[0] = bp;
                    }
                } else {
                    context.moveTo(pos.x, pos.y);
                    this._movedTo = true;
                }
            },

            _endCurve: function() {
                domEvent.stop(e);

                var buf = this._bezierBuf,
                    i = 0,
                    pos = null,
                    j = 0,
                    handlers = null;

                this._stopTimeout();

                // Finish last points in Bezier buffer
                while (buf[i]) {
                    pos = buf[i];
                    this._context.lineTo(pos.x, pos.y);
                    i++;
                }

                this._context.stroke();

                this._bezierBuf = null;

                while(this._handlers[j]){
                    handlers = this._handlers[j];
                    this.disconnect(handlers);
                    j++;
                }

                this._timer = setTimeout(dojo.hitch(this, this._finalizeSignature), this.timeout);
            },

            _eventResetClicked: function(e) {
                if (!this.get('disabled')) {
                    this._resetMxObject();
                    this._resetCanvas();

                    this._hideImage();
                }
            },

            _resetCanvas: function() {
                this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);

                this._bezierBuf = [];

                this._drawGrid();
            },

            _resetMxObject: function() {
                this._mxObject.set(this.dataUrl, '');
            },

            _stopTimeout: function() {
                if (this._timer) {
                    clearTimeout(this._timer);
                }
            },

            _finalizeSignature: function() {
                var mxobj = this._mxObject;
                if (mxobj) {
                    if (mxobj.has(this.dataUrl)) {
                        mxobj.set(this.dataUrl, this._canvas.toDataURL());
                    } else {
                        logger.error(this.id + '.finalizeSignature: no dataUrl attribute found.');
                    }
                }

                this._showImage();
            },

            _bezierPoint: function(c1, c2, c3, c4) {
                return {
                    x: c1.x * this._bezier1 + c2.x * this._bezier2 +
                        c3.x * this._bezier3 + c4.x * this._bezier4,
                    y: c1.y * this._bezier1 + c2.y * this._bezier2 +
                        c3.y * this._bezier3 + c4.y * this._bezier4
                };
            },

            _setDisabledAttr: function(value) {
                var isDisabled = this.readonly ||
                    !this._mxObject ||
                    !this._attribute ||
                    this._mxObject.isReadonlyAttr(this._attribute) ||
                    value;
                return this.inherited(arguments, [ isDisabled ]);
            }
        });
    });
}());
<commit_msg>Replace single quotes by double quotes<commit_after>/*jslint white: true nomen: true plusplus: true */
/*global mx, mxui, window, document, mendix, dojo, require, console, define, module, logger */
/**
	Signature
	========================

	@file      : Signature.js
	@version   : 2.1
	@author    : Maxim Oei, Richard Edens, Roeland Salij
	@date      : 22-08-2014
	@copyright : Mendix Technology BV
	@license   : Apache License, Version 2.0, January 2004

	Documentation
    ========================
	Complete any delivery service App with this Signature widget.
    This widget allows you to save a signature to an attribute.
*/
(function() {
    require([
        "mxui/widget/_WidgetBase", "dijit/_Widget", "dijit/_TemplatedMixin",
        "mxui/dom", "dojo/dom", "dojo/dom-construct", "dojo/_base/event", "dojo/ready", "dojo/query", "dojo/dom-prop", "dojo/dom-geometry", "dojo/dom-class", "dojo/dom-style", "dojo/on", "dojo/_base/lang", "dojo/_base/declare"
    ], function(_WidgetBase, _Widget, _Templated, domMx,dom, domConstruct, domEvent, domReady, domQuery, domProp, domGeom, domClass, domStyle, on, lang, declare) {

        return declare("Signature.widget.Signature", [ _WidgetBase, _Widget, _Templated ], {
            _contextGuid: null,
            _contextObj: null,
            _handle: null,

            _smoothingpct: 0.9,

            _mxObject: null,
            _attribute: null,
            _path: null,

            _canvas: null,
            _reset: null,
            _context: null,

            _timer: null,

            _touchSupport: false,
            _bezierBuf: null,

            templatePath: dojo.moduleUrl("Signature", "widget/templates/Signature.html"),

            postCreate: function() {
                this._setupWidget();
                this._createUI();
                this._setupEvents();
            },

            startup: function() {
                this.set("disabled", this.readonly);

                var path = this.dataUrl.split("/");
                this._attribute = path[path.length - 1];
                this._path = path.splice(0, path.length - 1);
            },

            update: function(obj, callback) {
                if (obj) {
                    obj.fetch(this._path, dojo.hitch(this, function(obj) {
                        this._updateObject(obj, callback);
                    }));
                } else {
                    this._updateObject(null, callback);
                }
            },

            enable: function() {
                dojo.attr(this._reset, "disabled", false);
                dojo.removeClass(this.domNode, "signhereSignature_disabled");
            },

            disable: function() {
                dojo.attr(this._reset, "disabled", true);
                dojo.addClass(this.domNode, "signhereSignature_disabled");
            },

            _setupWidget: function() {
                var t = this._smoothingpct,
                    u = 1 - t;

                this._bezier1 = t * t * t;
                this._bezier2 = 3 * t * t * u;
                this._bezier3 = 3 * t * u * u;
                this._bezier4 = u * u * u;

                this._bezierBuf = [];

                this._touchSupport = ("ontouchstart" in window) || window.DocumentTouch && document instanceof DocumentTouch;
            },

            _createUI: function() {
                var $ = domConstruct.create,
                    sizeProperties = {
                        "width": this.width + "px",
                        "height": this.height + "px"
                    },
                    allProperties = lang.mixin(sizeProperties, {
                        "style": "border: " + this.gridborder + "px solid " + this.gridcolor
                    });

                this._canvas = $("canvas", allProperties);
                this._image  = $("img", allProperties);

                this._reset = $("button", {
                    "class": "btn",
                    "style": {
                        "width": (this.width + 4) + "px"
                    },
                    "innerHTML":  this.resetcaption
                });

                this.domNode.appendChild(this._canvas);
                this.domNode.appendChild(this._image);
                this.domNode.appendChild(this._reset);

                domStyle.set(this.domNode, sizeProperties);

                this._context = this._canvas.getContext("2d");
            },

            _updateObject: function(obj, callback) {
                this._mxObject = obj;

                this._resetCanvas();

                if (this._attribute && obj && obj.get(this._attribute)) {
                    this._showImage();
                } else {
                    this._hideImage();
                }

                this.set("disabled", obj ? false : true);

                mendix.lang.nullExec(callback);
            },

            _showImage: function() {
                this._image.src = this._mxObject.get(this.dataUrl);

                dojo.replaceClass(this.domNode, "signature_set", "signature_unset");
            },

            _hideImage: function() {
                this._image.src = "";

                domClass.replace(this.domNode, "signature_unset", "signature_set");
            },

            _drawGrid: function() {
                if (!this.showgrid) return;

                var x = this.gridx,
                    y = this.gridy,
                    context = this._context,
                    width   = this._canvas.width,
                    height  = this._canvas.height;

                context.beginPath();

                for (; x < width; x += this.gridx) {
                    context.moveTo(x, 0);
                    context.lineTo(x, this._canvas.height);
                }

                for (; y < height; y += this.gridy) {
                    context.moveTo(0, y);
                    context.lineTo(this._canvas.width, y);
                }

                context.lineWidth = 1;
                context.strokeStyle = this.gridcolor;
                context.stroke();
            },

            _setupEvents: function() {
                this.connect(this._canvas, (this._touchSupport ? "touchstart" : "mousedown"), this._beginCurve);
                this.connect(this._reset, "click", this._eventResetClicked);

                // This prevents the "dragging image" annoyance when someone tries to
                // draw on the image.
                this.connect(
                    this._image,
                    this._touchSupport ? "touchstart" : "mousedown",
                    function(e) {
                        domEvent.stop(e);
                        return false;
                    }
                );
            },

            _getCoords: function(e) {
                var pos   = dojo.position(this._canvas, true),
                    pageX = e.targetTouches ? e.targetTouches[0].pageX : e.pageX,
                    pageY = e.targetTouches ? e.targetTouches[0].pageY : e.pageY,
                    x     = Math.floor(pageX - pos.x),
                    y     = Math.floor(pageY - pos.y);

                return { x: x, y: y };
            },

            _beginCurve: function(e) {
                domEvent.stop(e);

                if (this.get("disabled")) return;

                this._bezierBuf = [];
                this._handlers = [];

                this._stopTimeout();

                this._context.strokeStyle = this.pencolor;
                this._context.lineJoin    = "round";
                this._context.lineWidth   = this.pensize;

                this._context.beginPath();

                this._handlers.push(this.connect(window, this._touchSupport ? "touchmove" : "mousemove", this._updateCurve));
                this._handlers.push(this.connect(window, this._touchSupport ? "touchend" : "mouseup", this._endCurve));
            },

            _updateCurve: function(e) {
                domEvent.stop(e);

                var context = this._context,
                    buf = this._bezierBuf,
                    pos = this._getCoords(e),
                    bp = null;

                this._stopTimeout();

                if (this._movedTo) {
                    buf.push(pos);

                    if (buf.length === 4) {
                        bp = this._bezierPoint.apply(this, buf);

                        context.lineTo(bp.x, bp.y);
                        context.stroke();

                        buf.shift();
                        buf[0] = bp;
                    }
                } else {
                    context.moveTo(pos.x, pos.y);
                    this._movedTo = true;
                }
            },

            _endCurve: function() {
                domEvent.stop(e);

                var buf = this._bezierBuf,
                    i = 0,
                    pos = null,
                    j = 0,
                    handlers = null;

                this._stopTimeout();

                // Finish last points in Bezier buffer
                while (buf[i]) {
                    pos = buf[i];
                    this._context.lineTo(pos.x, pos.y);
                    i++;
                }

                this._context.stroke();

                this._bezierBuf = null;

                while(this._handlers[j]){
                    handlers = this._handlers[j];
                    this.disconnect(handlers);
                    j++;
                }

                this._timer = setTimeout(dojo.hitch(this, this._finalizeSignature), this.timeout);
            },

            _eventResetClicked: function(e) {
                if (!this.get("disabled")) {
                    this._resetMxObject();
                    this._resetCanvas();

                    this._hideImage();
                }
            },

            _resetCanvas: function() {
                this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);

                this._bezierBuf = [];

                this._drawGrid();
            },

            _resetMxObject: function() {
                this._mxObject.set(this.dataUrl, "");
            },

            _stopTimeout: function() {
                if (this._timer) {
                    clearTimeout(this._timer);
                }
            },

            _finalizeSignature: function() {
                var mxobj = this._mxObject;
                if (mxobj) {
                    if (mxobj.has(this.dataUrl)) {
                        mxobj.set(this.dataUrl, this._canvas.toDataURL());
                    } else {
                        logger.error(this.id + ".finalizeSignature: no dataUrl attribute found.");
                    }
                }

                this._showImage();
            },

            _bezierPoint: function(c1, c2, c3, c4) {
                return {
                    x: c1.x * this._bezier1 + c2.x * this._bezier2 +
                        c3.x * this._bezier3 + c4.x * this._bezier4,
                    y: c1.y * this._bezier1 + c2.y * this._bezier2 +
                        c3.y * this._bezier3 + c4.y * this._bezier4
                };
            },

            _setDisabledAttr: function(value) {
                var isDisabled = this.readonly ||
                    !this._mxObject ||
                    !this._attribute ||
                    this._mxObject.isReadonlyAttr(this._attribute) ||
                    value;
                return this.inherited(arguments, [ isDisabled ]);
            }
        });
    });
}());
<|endoftext|>


<commit_before>var sp = require('./sitemap_parser'),
    crawler = require('./crawler'),
    cp = require('child_process'),
    net = require('net'),
    fs = require('fs'),
    queue = [],
    conCount = 0,
    successCount = 0, failureCount = 0, totalCount = 0, server, url, config;

// parse arguments
url = process.argv[2];
config = JSON.parse(process.argv[3]);

var checkEnd = function() {
  if (totalCount !== 0 && conCount === 0 && totalCount == (successCount + failureCount)) {
    return process.exit(0);
  }
};

var cleanup = function() {

  server.close();

  if (fs.existsSync(config.pid)) {
    fs.unlinkSync(config.pid);
  }

  if (fs.existsSync(config.socket)) {
   fs.unlinkSync(config.socket);
  }
};

// open server for status check
var statsServer = function() {
  server = net.createServer(function(con) {
    con.write('status: \r\n');
    con.write('success: ' + successCount + '\tfailed: ' + failureCount + '\ttotal: ' + totalCount + '\tfinish: ' + Math.round(successCount * 100 / totalCount) + '\r\n');
    con.write('concurrency: ' + conCount + '\r\n');
    con.pipe(con);
  });

  server.listen(config.socket, function() {

  });

};

// start preparing to crawl
var urls = sp.downloadAll('http://www.yachtico.com/index.xml')
            .then(function(xmls) {
              return sp.parseAllUrls(xmls);
            });

// start child
urls.then(function(urls) {
  var options = crawler.genOptions(urls, config);

  totalCount = options.length;

  function stepForward(request) {
      request.spread(statsCounter);
      request.error(errorHandler);
      request.finally(finalHandler);
  }

  function finalHandler() {

    var opt;
    conCount -= 1;

    if (queue.length > 0 && conCount < config.concurrency) {

      conCount += 1;
      opt = queue.shift();
      //var child = cp.fork(__dirname + '/subjob.js', [JSON.stringify(opt)]);
      var request = crawler.crawlOne(opt);
      stepForward(request);
    }
    checkEnd();
  }

  function errorHandler(e) {
    failureCount +=1;
    console.log(e);
  }

  function statsCounter(result, body) {
    if (result.statusCode === 200) {
      //console.log('finished: ' + result.request.href);
      successCount += 1;
    } else {
      failureCount += 1;
    }
  }

  options.forEach(function(opt) {

    if (conCount < config.concurrency) {
      conCount += 1;
      //var child = cp.fork(__dirname + '/subjob.js', [JSON.stringify(opt)]);
      var request = crawler.crawlOne(opt);
      stepForward(request);
    } else {
      queue.push(opt);
    }

  });

});

urls.then(statsServer);

process.on('exit', function() {
  cleanup();
});

process.on('SIGTERM', function() {
  cleanup();
});

// FIXME: better method needed
//setInterval(checkEnd, 1000);
<commit_msg>clean up code<commit_after>var sp = require('./sitemap_parser'),
    crawler = require('./crawler'),
    cp = require('child_process'),
    net = require('net'),
    fs = require('fs'),
    queue = [],
    conCount = 0,
    successCount = 0, failureCount = 0, totalCount = 0, server, url, config;

// parse arguments
url = process.argv[2];
config = JSON.parse(process.argv[3]);

var checkEnd = function() {
  if (totalCount !== 0 && conCount === 0 && totalCount == (successCount + failureCount)) {
    return process.exit(0);
  }
};

var cleanup = function() {

  server.close();

  if (fs.existsSync(config.pid)) {
    fs.unlinkSync(config.pid);
  }

  if (fs.existsSync(config.socket)) {
   fs.unlinkSync(config.socket);
  }
};

// open server for status check
var statsServer = function() {
  server = net.createServer(function(con) {
    con.write('status: \r\n');
    con.write('success: ' + successCount + '\tfailed: ' + failureCount + '\ttotal: ' + totalCount + '\tfinish: ' + Math.round(successCount * 100 / totalCount) + '\r\n');
    con.write('concurrency: ' + conCount + '\r\n');
    con.pipe(con);
  });

  server.listen(config.socket, function() {

  });

};

// start preparing to crawl
var urls = sp.downloadAll('http://www.yachtico.com/index.xml')
            .then(function(xmls) {
              return sp.parseAllUrls(xmls);
            });

// start child
urls.then(function(urls) {
  var options = crawler.genOptions(urls, config);

  totalCount = options.length;

  function stepForward(request) {
      request.spread(statsCounter);
      request.error(errorHandler);
      request.finally(finalHandler);
  }

  function finalHandler() {

    var opt;
    conCount -= 1;

    if (queue.length > 0 && conCount < config.concurrency) {

      conCount += 1;
      opt = queue.shift();
      //var child = cp.fork(__dirname + '/subjob.js', [JSON.stringify(opt)]);
      var request = crawler.crawlOne(opt);
      stepForward(request);
    }
    checkEnd();
  }

  function errorHandler(e) {
    failureCount +=1;
    console.log(e);
  }

  function statsCounter(result, body) {
    if (result.statusCode === 200) {
      //console.log('finished: ' + result.request.href);
      successCount += 1;
    } else {
      failureCount += 1;
    }
  }

  options.forEach(function(opt) {

    if (conCount < config.concurrency) {
      conCount += 1;
      //var child = cp.fork(__dirname + '/subjob.js', [JSON.stringify(opt)]);
      var request = crawler.crawlOne(opt);
      stepForward(request);
    } else {
      queue.push(opt);
    }

  });

});

urls.then(statsServer);

process.on('exit', function() {
  cleanup();
});

process.on('SIGTERM', function() {
  cleanup();
});
<|endoftext|>