<commit_before>FLOW.MonitoringDataTableView = FLOW.View.extend({
  showingDetailsDialog: false,
  cursorStart: null,

  pageNumber: function(){
	return FLOW.surveyedLocaleControl.get('pageNumber');
  }.property('FLOW.surveyedLocaleControl.pageNumber'),

  showDetailsDialog: function (evt) {
	FLOW.surveyInstanceControl.set('content', FLOW.store.findQuery(FLOW.SurveyInstance, {
		surveyedLocaleId: evt.context.get('keyId')
	}));
    this.toggleProperty('showingDetailsDialog');
  },

  closeDetailsDialog: function () {
    this.toggleProperty('showingDetailsDialog');
  },

  showSurveyInstanceDetails: function (evt) {
    FLOW.questionAnswerControl.doQuestionAnswerQuery(evt.context.get('keyId'));
    $('.si_details').hide();
    $('tr[data-flow-id="si_details_' + evt.context.get('keyId') + '"]').show();
  },

  showSurveyedLocaleDeleteButton: function() {
    return FLOW.surveyedLocaleControl.get('userCanDelete');
  }.property(),

  findSurveyedLocale: function (evt) {
	  var ident = this.get('identifier'),
	      displayName = this.get('displayName'),
	      sgId = FLOW.selectedControl.get('selectedSurveyGroup'),
	      cursorType = FLOW.metaControl.get('cursorType');
        criteria = {};

	  if (ident) {
		  criteria.identifier = ident;
	  }

	  if (displayName) {
		  criteria.displayName = displayName;
	  }

	  if (sgId) {
		  criteria.surveyGroupId = sgId.get('keyId');
	  }

	  if (this.get('cursorStart')) {
		criteria.since = this.get('cursorStart');
	  }

	  FLOW.surveyedLocaleControl.set('content', FLOW.store.findQuery(FLOW.SurveyedLocale, criteria));
  },

  doNextPage: function () {
    FLOW.surveyedLocaleControl.get('sinceArray').pushObject(FLOW.metaControl.get('since'));
	this.set('cursorStart', FLOW.metaControl.get('since'));
    this.findSurveyedLocale();
    FLOW.surveyedLocaleControl.set('pageNumber', FLOW.surveyedLocaleControl.get('pageNumber') + 1);
  },

  doPrevPage: function () {
    FLOW.surveyedLocaleControl.get('sinceArray').popObject();
    FLOW.metaControl.set('since', FLOW.surveyedLocaleControl.get('sinceArray')[FLOW.surveyedLocaleControl.get('sinceArray').length - 1]);
	this.set('cursorStart', FLOW.metaControl.get('since'));
    this.findSurveyedLocale();
    FLOW.surveyedLocaleControl.set('pageNumber', FLOW.surveyedLocaleControl.get('pageNumber') - 1);
  },

  hasNextPage: function () {
    return FLOW.metaControl.get('numSLLoaded') == 20;
  }.property('FLOW.metaControl.numSLLoaded'),

  hasPrevPage: function () {
    return FLOW.surveyedLocaleControl.get('sinceArray').length != 0;
  }.property('FLOW.surveyedLocaleControl.sinceArray.length'),
});
<commit_msg>[#1299] Navigate next page based on cursor that was set while processing incoming response<commit_after>FLOW.MonitoringDataTableView = FLOW.View.extend({
  showingDetailsDialog: false,
  cursorStart: null,

  pageNumber: function(){
	return FLOW.surveyedLocaleControl.get('pageNumber');
  }.property('FLOW.surveyedLocaleControl.pageNumber'),

  showDetailsDialog: function (evt) {
	FLOW.surveyInstanceControl.set('content', FLOW.store.findQuery(FLOW.SurveyInstance, {
		surveyedLocaleId: evt.context.get('keyId')
	}));
    this.toggleProperty('showingDetailsDialog');
  },

  closeDetailsDialog: function () {
    this.toggleProperty('showingDetailsDialog');
  },

  showSurveyInstanceDetails: function (evt) {
    FLOW.questionAnswerControl.doQuestionAnswerQuery(evt.context.get('keyId'));
    $('.si_details').hide();
    $('tr[data-flow-id="si_details_' + evt.context.get('keyId') + '"]').show();
  },

  showSurveyedLocaleDeleteButton: function() {
    return FLOW.surveyedLocaleControl.get('userCanDelete');
  }.property(),

  findSurveyedLocale: function (evt) {
	  var ident = this.get('identifier'),
	      displayName = this.get('displayName'),
	      sgId = FLOW.selectedControl.get('selectedSurveyGroup'),
	      cursorType = FLOW.metaControl.get('cursorType');
        criteria = {};

	  if (ident) {
		  criteria.identifier = ident;
	  }

	  if (displayName) {
		  criteria.displayName = displayName;
	  }

	  if (sgId) {
		  criteria.surveyGroupId = sgId.get('keyId');
	  }

	  if (this.get('cursorStart')) {
		criteria.since = this.get('cursorStart');
	  }

	  FLOW.surveyedLocaleControl.set('content', FLOW.store.findQuery(FLOW.SurveyedLocale, criteria));
  },

  doNextPage: function () {
	var cursorArray = FLOW.surveyedLocaleControl.get('sinceArray');
	this.set('cursorStart', cursorArray[cursorArray.length - 1]);
    this.findSurveyedLocale();
    FLOW.surveyedLocaleControl.set('pageNumber', FLOW.surveyedLocaleControl.get('pageNumber') + 1);
  },

  doPrevPage: function () {
    FLOW.surveyedLocaleControl.get('sinceArray').popObject();
    FLOW.metaControl.set('since', FLOW.surveyedLocaleControl.get('sinceArray')[FLOW.surveyedLocaleControl.get('sinceArray').length - 1]);
	this.set('cursorStart', FLOW.metaControl.get('since'));
    this.findSurveyedLocale();
    FLOW.surveyedLocaleControl.set('pageNumber', FLOW.surveyedLocaleControl.get('pageNumber') - 1);
  },

  hasNextPage: function () {
    return FLOW.metaControl.get('numSLLoaded') == 20;
  }.property('FLOW.metaControl.numSLLoaded'),

  hasPrevPage: function () {
    return FLOW.surveyedLocaleControl.get('sinceArray').length != 0;
  }.property('FLOW.surveyedLocaleControl.sinceArray.length'),
});
<|endoftext|>


<commit_before>var compose = require('./compose')
var isArray = Array.isArray

function split(str) {
  return isArray(str) ? str : str.split(';')
}

module.exports = function (plugs) {

  plugs = plugs.map(function (e) {
    return isArray(e) ? compose(e) : e
  })

  return {
    name: plugs.map(function (e) { return e.name }).join(';'),
    client: function (addr, cb) {
      //if(/;/.test(addr))
      if(!split(addr).find(function (addr) {
        //connect with the first plug that understands this string.
        var plug = plugs.find(function (plug) { plug.parse(addr) })
        if(plug) plug.client(addr, cb)
        return plug
      }))
        cb(new Error('could not connect to one of:'+addr))
    },
    server: function (onConnect, onError) {
      //start all servers
      var closes = plugs.map(function (plug) {
        return plug.server(onConnect, onError)
      })

      return function () {
        closes.forEach(function (close) { close() })
      }
    },
    stringify: function () {
      return plugs.map(function (plug) {
        return plug.stringify()
      }).join(';')
    },
    //parse doesn't really make sense here...
    //like, what if you only have a partial match?
    //maybe just parse the ones you understand?
    parse: function (str) {
      return str.split(';').map(function (e, i) {
        return plugs[i].parse(e)
      })
    }
  }
}

<commit_msg>fix finding the right plugin to handle a protocol<commit_after>var compose = require('./compose')
var isArray = Array.isArray

function split(str) {
  return isArray(str) ? str : str.split(';')
}

module.exports = function (plugs) {

  plugs = plugs.map(function (e) {
    return isArray(e) ? compose(e) : e
  })
  console.log('PLUGS', plugs)

  return {
    name: plugs.map(function (e) { return e.name }).join(';'),
    client: function (addr, cb) {
      //if(/;/.test(addr))
      var plug
      split(addr).find(function (addr) {
        //connect with the first plug that understands this string.
        plug = plugs.find(function (plug) {
          return plug.parse(addr)
        })
      })
      if(plug) plug.client(addr, cb)
      else cb(new Error('could not connect to one of:'+addr))
    },
    server: function (onConnect, onError) {
      //start all servers
      var closes = plugs.map(function (plug) {
        return plug.server(onConnect, onError)
      })

      return function () {
        closes.forEach(function (close) { close() })
      }
    },
    stringify: function () {
      return plugs.map(function (plug) {
        return plug.stringify()
      }).join(';')
    },
    //parse doesn't really make sense here...
    //like, what if you only have a partial match?
    //maybe just parse the ones you understand?
    parse: function (str) {
      return str.split(';').map(function (e, i) {
        return plugs[i].parse(e)
      })
    }
  }
}

<|endoftext|>


<commit_before>// (logic of computation inspired by:
// https://stackoverflow.com/questions/32771458/distance-from-lat-lng-point-to-minor-arc-segment)

import bearing from '@turf/bearing';
import distance from '@turf/distance';
import rhumbBearing from '@turf/rhumb-bearing';
import rhumbDistance from '@turf/rhumb-distance';
import { featureOf } from '@turf/invariant';
import { segmentEach } from '@turf/meta';
import { point, feature, lineString, bearingToAngle, degrees2radians, convertDistance } from '@turf/helpers';

/**
 * Returns the minimum distance between a {@link Point} and a {@link LineString}, being the distance from a line the
 * minimum distance between the point and any segment of the `LineString`.
 *
 * @name pointToLineDistance
 * @param {Feature<Point>|Array<number>} pt Feature or Geometry
 * @param {Feature<LineString>|Array<Array<number>>} line GeoJSON Feature or Geometry
 * @param {string} [units=kilometers] can be degrees, radians, miles, or kilometers
 * @param {boolean} [mercator=false] if distance should be on Mercator or WGS84 projection
 * @returns {number} distance between point and line
 * @example
 * var pt = turf.point([0, 0]);
 * var line = turf.lineString([[1, 1],[-1, 1]]);
 *
 * var distance = turf.pointToLineDistance(pt, line, 'miles');
 * //=69.11854715938406
 */
export default function (pt, line, units, mercator) {
    // validation
    if (!pt) throw new Error('pt is required');
    if (Array.isArray(pt)) pt = point(pt);
    else if (pt.type === 'Point') pt = feature(pt);
    else featureOf(pt, 'Point', 'point');

    if (!line) throw new Error('line is required');
    if (Array.isArray(line)) line = lineString(line);
    else if (line.type === 'LineString') line = feature(line);
    else featureOf(line, 'LineString', 'line');

    var distance = Infinity;
    var p = pt.geometry.coordinates;
    segmentEach(line, function (segment) {
        var a = segment.geometry.coordinates[0];
        var b = segment.geometry.coordinates[1];
        var d = distanceToSegment(p, a, b, units, mercator);
        if (distance > d) distance = d;
    });
    return distance;
}

/**
 * Returns the distance between a point P on a segment AB.
 *
 * @private
 * @param {Array<number>} p external point
 * @param {Array<number>} a first segment point
 * @param {Array<number>} b second segment point
 * @param {string} [units=kilometers] can be degrees, radians, miles, or kilometers
 * @param {boolean} [mercator=false] if distance should be on Mercator or WGS84 projection
 * @returns {number} distance
 */
function distanceToSegment(p, a, b, units, mercator) {

    var distanceAP = (mercator !== true) ? distance(a, p, units) : euclideanDistance(a, p, units);
    var azimuthAP = bearingToAngle((mercator !== true) ? bearing(a, p) : rhumbBearing(a, p));
    var azimuthAB = bearingToAngle((mercator !== true) ? bearing(a, b) : rhumbBearing(a, b));
    var angleA = Math.abs(azimuthAP - azimuthAB);
    // if (angleA > 180) angleA = Math.abs(angleA - 360);
    // if the angle PAB is obtuse its projection on the line extending the segment falls outside the segment
    // thus return distance between P and the start point A
    /*
        P__
        |\ \____
        | \     \____
        |  \         \____
        |   \_____________\
        H    A             B
     */
    if (angleA > 90) return distanceAP;

    var azimuthBA = (azimuthAB + 180) % 360;
    var azimuthBP = bearingToAngle((mercator !== true) ? bearing(b, p) : rhumbBearing(b, p));
    var angleB = Math.abs(azimuthBP - azimuthBA);
    if (angleB > 180) angleB = Math.abs(angleB - 360);
    // also if the angle ABP is acute the projection of P falls outside the segment, on the other side
    // so return the distance between P and the end point B
    /*
                        ____P
                   ____/   /|
              ____/       / |
         ____/           /  |
        /______________/    |
       A               B    H
    */
    if (angleB > 90) return (mercator !== true) ? distance(p, b, units) : euclideanDistance(p, b, units);
    // finally if the projection falls inside the segment
    // return the distance between P and the segment
    /*
                     P
                  __/|\
               __/   | \
            __/      |  \
         __/         |   \
        /____________|____\
       A             H     B
    */
    if (mercator !== true) return distanceAP * Math.sin(degrees2radians(angleA));
    return mercatorPH(a, b, p, units);
}

/**
 * Returns the distance between a point P on a segment AB, on Mercator projection
 *
 * @private
 * @param {Array<number>} a first segment point
 * @param {Array<number>} b second segment point
 * @param {Array<number>} p external point
 * @param {string} [units=kilometers] can be degrees, radians, miles, or kilometers
 * @returns {number} distance
 */
function mercatorPH(a, b, p, units) {
    var delta = 0;
    // translate points if any is crossing the 180th meridian
    if (Math.abs(a[0]) >= 180 || Math.abs(b[0]) >= 180 || Math.abs(p[0]) >= 180) {
        delta = (a[0] > 0 || b[0] > 0 || p[0] > 0) ? -180 : 180;
    }

    var origin = point(p);
    var A = toMercator([a[0] + delta, a[1]]);
    var B = toMercator([b[0] + delta, b[1]]);
    var P = toMercator([p[0] + delta, p[1]]);
    var h = toWGS84(euclideanIntersection(A, B, P));

    if (delta !== 0) h[0] -= delta; // translate back to original position
    var distancePH = rhumbDistance(origin, h, units);
    return distancePH;
}

/**
 * Returns the point H projection of a point P on a segment AB, on the euclidean plain
 * from https://stackoverflow.com/questions/10301001/perpendicular-on-a-line-segment-from-a-given-point#answer-12499474
 *            P
 *           |
 *           |
 *  _________|____
 * A          H   B
 *
 * @private
 * @param {Array<number>} a first segment point
 * @param {Array<number>} b second segment point
 * @param {Array<number>} p external point
 * @returns {Array<number>} projected point
 */
function euclideanIntersection(a, b, p) {
    var x1 = a[0], y1 = a[1],
        x2 = b[0], y2 = b[1],
        x3 = p[0], y3 = p[1];
    var px = x2 - x1, py = y2 - y1;
    var dab = px * px + py * py;
    var u = ((x3 - x1) * px + (y3 - y1) * py) / dab;
    var x = x1 + u * px, y = y1 + u * py;
    return [x, y]; // H
}

/**
 * Returns euclidean distance between two points
 *
 * @private
 * @param {Object} from first point
 * @param {Object} to second point
 * @param {string} units can be degrees, radians, miles, or kilometers
 * @returns {number} squared distance
 */
function euclideanDistance(from, to, units) {
    // translate points if any is crossing the 180th meridian
    var delta = 0;
    if (Math.abs(from[0]) >= 180) {
        delta = (from[0] > 0) ? -180 : 180;
    }
    if (Math.abs(to[0]) >= 180) {
        delta = (to[0] > 0) ? -180 : 180;
    }
    var p1 = toMercator([from[0] + delta, from[1]]);
    var p2 = toMercator([to[0] + delta, to[1]]);

    var sqr = function (n) { return n * n; };
    var squareD = sqr(p1[0] - p2[0]) + sqr(p1[1] - p2[1]);
    var d = Math.sqrt(squareD);
    return convertDistance(d, 'meters', units);
}

/**
 * Convert lon/lat values to 900913 x/y.
 * from https://github.com/mapbox/sphericalmercator
 *
 * @private
 * @param {Array<number>} lonLat WGS84 point
 * @returns {Array<number>} Mercator [x, y] point
 */
function toMercator(lonLat) {
    var D2R = Math.PI / 180,
        // 900913 properties.
        A = 6378137.0,
        MAXEXTENT = 20037508.342789244;

    var xy = [
        A * lonLat[0] * D2R,
        A * Math.log(Math.tan((Math.PI * 0.25) + (0.5 * lonLat[1] * D2R)))
    ];
    // if xy value is beyond maxextent (e.g. poles), return maxextent.
    if (xy[0] > MAXEXTENT) xy[0] = MAXEXTENT;
    if (xy[0] < -MAXEXTENT) xy[0] = -MAXEXTENT;
    if (xy[1] > MAXEXTENT) xy[1] = MAXEXTENT;
    if (xy[1] < -MAXEXTENT) xy[1] = -MAXEXTENT;
    return xy;
}

/**
 * Convert 900913 x/y values to lon/lat.
 * from https://github.com/mapbox/sphericalmercator
 *
 * @private
 * @param {Array<number>} xy Mercator [x, y] point
 * @returns {Array<number>} WGS84 [lon, lat] point
 */
function toWGS84(xy) {
    // 900913 properties.
    var R2D = 180 / Math.PI,
        A = 6378137.0;

    return [
        (xy[0] * R2D / A),
        ((Math.PI * 0.5) - 2.0 * Math.atan(Math.exp(-xy[1] / A))) * R2D
    ];
}
<commit_msg>Update index.js<commit_after>// (logic of computation inspired by:
// https://stackoverflow.com/questions/32771458/distance-from-lat-lng-point-to-minor-arc-segment)

import bearing from '@turf/bearing';
import distance from '@turf/distance';
import rhumbBearing from '@turf/rhumb-bearing';
import rhumbDistance from '@turf/rhumb-distance';
import { featureOf } from '@turf/invariant';
import { segmentEach } from '@turf/meta';
import {
    point,
    feature,
    lineString,
    bearingToAngle,
    degrees2radians,
    convertDistance
} from '@turf/helpers';

/**
 * Returns the minimum distance between a {@link Point} and a {@link LineString}, being the distance from a line the
 * minimum distance between the point and any segment of the `LineString`.
 *
 * @name pointToLineDistance
 * @param {Feature<Point>|Array<number>} pt Feature or Geometry
 * @param {Feature<LineString>|Array<Array<number>>} line GeoJSON Feature or Geometry
 * @param {Object} [options] Optional parameters
 * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers
 * @param {boolean} [mercator=false] if distance should be on Mercator or WGS84 projection
 * @returns {number} distance between point and line
 * @example
 * var pt = turf.point([0, 0]);
 * var line = turf.lineString([[1, 1],[-1, 1]]);
 *
 * var distance = turf.pointToLineDistance(pt, line, 'miles');
 * //=69.11854715938406
 */
export default function (pt, line, options) {
    // Optional params
    options = options || {};
    // var units = options.units;
    // var mercator = options.mercator;

    // validation
    if (typeof options !== 'object') throw new Error('options must be an object');
    if (!pt) throw new Error('pt is required');
    if (Array.isArray(pt)) pt = point(pt);
    else if (pt.type === 'Point') pt = feature(pt);
    else featureOf(pt, 'Point', 'point');

    if (!line) throw new Error('line is required');
    if (Array.isArray(line)) line = lineString(line);
    else if (line.type === 'LineString') line = feature(line);
    else featureOf(line, 'LineString', 'line');

    var distance = Infinity;
    var p = pt.geometry.coordinates;
    segmentEach(line, function (segment) {
        var a = segment.geometry.coordinates[0];
        var b = segment.geometry.coordinates[1];
        var d = distanceToSegment(p, a, b, options);
        if (distance > d) distance = d;
    });
    return distance;
}

/**
 * Returns the distance between a point P on a segment AB.
 *
 * @private
 * @param {Array<number>} p external point
 * @param {Array<number>} a first segment point
 * @param {Array<number>} b second segment point
 * @param {Object} [options] Optional parameters
 * @param {string} [units=kilometers] can be degrees, radians, miles, or kilometers
 * @param {boolean} [mercator=false] if distance should be on Mercator or WGS84 projection
 * @returns {number} distance
 */
function distanceToSegment(p, a, b, options) {
    options = options || {};
    var units = options.units;
    var mercator = options.mercator;

    var distanceAP = (mercator !== true) ? distance(a, p, units) : euclideanDistance(a, p, units);
    var azimuthAP = bearingToAngle((mercator !== true) ? bearing(a, p) : rhumbBearing(a, p));
    var azimuthAB = bearingToAngle((mercator !== true) ? bearing(a, b) : rhumbBearing(a, b));
    var angleA = Math.abs(azimuthAP - azimuthAB);
    // if (angleA > 180) angleA = Math.abs(angleA - 360);
    // if the angle PAB is obtuse its projection on the line extending the segment falls outside the segment
    // thus return distance between P and the start point A
    /*
        P__
        |\ \____
        | \     \____
        |  \         \____
        |   \_____________\
        H    A             B
     */
    if (angleA > 90) return distanceAP;

    var azimuthBA = (azimuthAB + 180) % 360;
    var azimuthBP = bearingToAngle((mercator !== true) ? bearing(b, p) : rhumbBearing(b, p));
    var angleB = Math.abs(azimuthBP - azimuthBA);
    if (angleB > 180) angleB = Math.abs(angleB - 360);
    // also if the angle ABP is acute the projection of P falls outside the segment, on the other side
    // so return the distance between P and the end point B
    /*
                        ____P
                   ____/   /|
              ____/       / |
         ____/           /  |
        /______________/    |
       A               B    H
    */
    if (angleB > 90) return (mercator !== true) ? distance(p, b, units) : euclideanDistance(p, b, units);
    // finally if the projection falls inside the segment
    // return the distance between P and the segment
    /*
                     P
                  __/|\
               __/   | \
            __/      |  \
         __/         |   \
        /____________|____\
       A             H     B
    */
    if (mercator !== true) return distanceAP * Math.sin(degrees2radians(angleA));
    return mercatorPH(a, b, p, units);
}

/**
 * Returns the distance between a point P on a segment AB, on Mercator projection
 *
 * @private
 * @param {Array<number>} a first segment point
 * @param {Array<number>} b second segment point
 * @param {Array<number>} p external point
 * @param {string} [units=kilometers] can be degrees, radians, miles, or kilometers
 * @returns {number} distance
 */
function mercatorPH(a, b, p, units) {
    var delta = 0;
    // translate points if any is crossing the 180th meridian
    if (Math.abs(a[0]) >= 180 || Math.abs(b[0]) >= 180 || Math.abs(p[0]) >= 180) {
        delta = (a[0] > 0 || b[0] > 0 || p[0] > 0) ? -180 : 180;
    }

    var origin = point(p);
    var A = toMercator([a[0] + delta, a[1]]);
    var B = toMercator([b[0] + delta, b[1]]);
    var P = toMercator([p[0] + delta, p[1]]);
    var h = toWGS84(euclideanIntersection(A, B, P));

    if (delta !== 0) h[0] -= delta; // translate back to original position
    var distancePH = rhumbDistance(origin, h, units);
    return distancePH;
}

/**
 * Returns the point H projection of a point P on a segment AB, on the euclidean plain
 * from https://stackoverflow.com/questions/10301001/perpendicular-on-a-line-segment-from-a-given-point#answer-12499474
 *            P
 *           |
 *           |
 *  _________|____
 * A          H   B
 *
 * @private
 * @param {Array<number>} a first segment point
 * @param {Array<number>} b second segment point
 * @param {Array<number>} p external point
 * @returns {Array<number>} projected point
 */
function euclideanIntersection(a, b, p) {
    var x1 = a[0], y1 = a[1],
        x2 = b[0], y2 = b[1],
        x3 = p[0], y3 = p[1];
    var px = x2 - x1, py = y2 - y1;
    var dab = px * px + py * py;
    var u = ((x3 - x1) * px + (y3 - y1) * py) / dab;
    var x = x1 + u * px, y = y1 + u * py;
    return [x, y]; // H
}

/**
 * Returns euclidean distance between two points
 *
 * @private
 * @param {Object} from first point
 * @param {Object} to second point
 * @param {string} units can be degrees, radians, miles, or kilometers
 * @returns {number} squared distance
 */
function euclideanDistance(from, to, units) {
    // translate points if any is crossing the 180th meridian
    var delta = 0;
    if (Math.abs(from[0]) >= 180) {
        delta = (from[0] > 0) ? -180 : 180;
    }
    if (Math.abs(to[0]) >= 180) {
        delta = (to[0] > 0) ? -180 : 180;
    }
    var p1 = toMercator([from[0] + delta, from[1]]);
    var p2 = toMercator([to[0] + delta, to[1]]);

    var sqr = function (n) { return n * n; };
    var squareD = sqr(p1[0] - p2[0]) + sqr(p1[1] - p2[1]);
    var d = Math.sqrt(squareD);
    return convertDistance(d, 'meters', units);
}

/**
 * Convert lon/lat values to 900913 x/y.
 * from https://github.com/mapbox/sphericalmercator
 *
 * @private
 * @param {Array<number>} lonLat WGS84 point
 * @returns {Array<number>} Mercator [x, y] point
 */
function toMercator(lonLat) {
    var D2R = Math.PI / 180,
        // 900913 properties.
        A = 6378137.0,
        MAXEXTENT = 20037508.342789244;

    var xy = [
        A * lonLat[0] * D2R,
        A * Math.log(Math.tan((Math.PI * 0.25) + (0.5 * lonLat[1] * D2R)))
    ];
    // if xy value is beyond maxextent (e.g. poles), return maxextent.
    if (xy[0] > MAXEXTENT) xy[0] = MAXEXTENT;
    if (xy[0] < -MAXEXTENT) xy[0] = -MAXEXTENT;
    if (xy[1] > MAXEXTENT) xy[1] = MAXEXTENT;
    if (xy[1] < -MAXEXTENT) xy[1] = -MAXEXTENT;
    return xy;
}

/**
 * Convert 900913 x/y values to lon/lat.
 * from https://github.com/mapbox/sphericalmercator
 *
 * @private
 * @param {Array<number>} xy Mercator [x, y] point
 * @returns {Array<number>} WGS84 [lon, lat] point
 */
function toWGS84(xy) {
    // 900913 properties.
    var R2D = 180 / Math.PI,
        A = 6378137.0;

    return [
        (xy[0] * R2D / A),
        ((Math.PI * 0.5) - 2.0 * Math.atan(Math.exp(-xy[1] / A))) * R2D
    ];
}
<|endoftext|>


<commit_before>'use strict';

var React = require('react');
var ColorPicker = require('./color-picker');
var SearchStore = require('./search-store');
var _ = require('underscore');

var searchableTypes = [
  'name',
  'defaultValue',
  'value',
  'label'
];

var FormCollection = React.createClass({
  areDefined: function (value) {
    return typeof value !== 'undefined';
  },

  areInValue: function (value, term) {
    return value.toLowerCase().indexOf(term) >= 0;
  },

  containsSearchTerm: function (value, key) {
    var self = this;
    var searchTerm = this.props.searchTerm.toLowerCase().replace(/\s+?/gi, ' ');
    var searchTerms = searchTerm.split(' ');

    return searchableTypes.indexOf(key) >= 0 &&
      value &&
      (
        value.toLowerCase().indexOf(searchTerm) >= 0 ||
        _.every(searchTerms, self.areInValue.bind(self, value))
      );
  },

  addToSearch: function (val) {
    console.log(val);
    SearchStore.action('setSearchTerm', val);
  },

  create: {
    subHeader: function (child) {
      if (this.props.searchTerm) {
        return undefined;
      }
      return (

child.value

      );
    },

    variable: function (child, index) {
      var self = this;
      var colorPicker, label;

      if (this.props.searchTerm && !_.any(child, this.containsSearchTerm)) {
        return undefined;
      }

      if (child.type === 'color') {
        colorPicker = (
          <ColorPicker
            setValue={self.props.updateVariable.bind(null, self.props.index, index)}
            value={child.value}
            defaultValue={child.defaultValue} />
        );
      }

      if (child.label) {
        label = (

            {child.label}

        );
      }

      return (

          {label}

            {child.name}

            <input
              text='text'
              className='form-control'
              placeholder={child.defaultValue}
              value={child.value}
              onChange={self.props.updateVariable.bind(null, self.props.index, index)} />
            {colorPicker}

      );
    }
  },

  render: function () {
    var self = this;
    var description, hasSearchResults, children;

    var isNotActiveCollection = typeof this.props.activeIndex !== 'undefined' &&
      this.props.index !== this.props.activeIndex;
    var isActiveCollection = typeof this.props.activeIndex !== 'undefined' &&
      this.props.index === this.props.activeIndex;

    if (isNotActiveCollection && !this.props.searchTerm) {
      return false;
    }

    if (isActiveCollection || this.props.searchTerm) {
      children = this.props.group.children.map(function (child, index) {
        return self.create[child.element].call(self, child, index);
      });
    }

    if (isActiveCollection && this.props.group.description) {
      description = (

{this.props.group.description}

      );
    }

    if (this.props.searchTerm) {
      hasSearchResults = _.any(children, this.areDefined);

      if (!hasSearchResults) {
        return false;
      }
    }

    return (

{this.props.group.value}

            {description}
            {children}

    );
  }
});

module.exports = FormCollection;
<commit_msg>Remove log<commit_after>'use strict';

var React = require('react');
var ColorPicker = require('./color-picker');
var SearchStore = require('./search-store');
var _ = require('underscore');

var searchableTypes = [
  'name',
  'defaultValue',
  'value',
  'label'
];

var FormCollection = React.createClass({
  areDefined: function (value) {
    return typeof value !== 'undefined';
  },

  areInValue: function (value, term) {
    return value.toLowerCase().indexOf(term) >= 0;
  },

  containsSearchTerm: function (value, key) {
    var self = this;
    var searchTerm = this.props.searchTerm.toLowerCase().replace(/\s+?/gi, ' ');
    var searchTerms = searchTerm.split(' ');

    return searchableTypes.indexOf(key) >= 0 &&
      value &&
      (
        value.toLowerCase().indexOf(searchTerm) >= 0 ||
        _.every(searchTerms, self.areInValue.bind(self, value))
      );
  },

  addToSearch: function (val) {
    SearchStore.action('setSearchTerm', val);
  },

  create: {
    subHeader: function (child) {
      if (this.props.searchTerm) {
        return undefined;
      }
      return (

child.value

      );
    },

    variable: function (child, index) {
      var self = this;
      var colorPicker, label;

      if (this.props.searchTerm && !_.any(child, this.containsSearchTerm)) {
        return undefined;
      }

      if (child.type === 'color') {
        colorPicker = (
          <ColorPicker
            setValue={self.props.updateVariable.bind(null, self.props.index, index)}
            value={child.value}
            defaultValue={child.defaultValue} />
        );
      }

      if (child.label) {
        label = (

            {child.label}

        );
      }

      return (

          {label}

            {child.name}

            <input
              text='text'
              className='form-control'
              placeholder={child.defaultValue}
              value={child.value}
              onChange={self.props.updateVariable.bind(null, self.props.index, index)} />
            {colorPicker}

      );
    }
  },

  render: function () {
    var self = this;
    var description, hasSearchResults, children;

    var isNotActiveCollection = typeof this.props.activeIndex !== 'undefined' &&
      this.props.index !== this.props.activeIndex;
    var isActiveCollection = typeof this.props.activeIndex !== 'undefined' &&
      this.props.index === this.props.activeIndex;

    if (isNotActiveCollection && !this.props.searchTerm) {
      return false;
    }

    if (isActiveCollection || this.props.searchTerm) {
      children = this.props.group.children.map(function (child, index) {
        return self.create[child.element].call(self, child, index);
      });
    }

    if (isActiveCollection && this.props.group.description) {
      description = (

{this.props.group.description}

      );
    }

    if (this.props.searchTerm) {
      hasSearchResults = _.any(children, this.areDefined);

      if (!hasSearchResults) {
        return false;
      }
    }

    return (

{this.props.group.value}

            {description}
            {children}

    );
  }
});

module.exports = FormCollection;
<|endoftext|>


<commit_before>// Router Config
const ROUTER_MODEL = 'Nighthawk X6 R8000';
const ROUTER_IP = '192.168.1.1';
const ROUTER_USER = 'admin';
const ROUTER_PASS = 'password';
const MAX_UP = '10';
const MAX_DOWN = '1';

// Dependencies
const request = require('request');
const Xray = require('x-ray');
const x = Xray({
	filters: {
		split: function(value) {
			if (!value) {
				return value;
			}
			return value.split(SEPARATOR);
		}
	}
});

const SEPARATOR = '
';
const SEPARATOR_OUTPUT = ' - ';
const TITLE = ROUTER_MODEL + ' - Connected Devices';
// const DEVICE_TABLE_SEL = '#target > table > tr:nth-child(1) > td > div > ' +
// 'table > tr:nth-child(4) > td > table';
const DEVICE_TABLE_SEL = '#target > table > tr:nth-child(1) > td > div > ' +
	'table > tr:nth-child(4) > td > table > tr';
// const DEVICE_INFO_SEL = 'td:nth-child(5) @html | split';
const DEVICE_INFO_SEL = 'td:nth-child(5) > span > table > tr > ' +
	'td:nth-child(2) > span @html | split';
const DEVICE_CONNECTION_TYPE_SEL = 'td:nth-child(4)';
const DEVICE_UP_SEL = 'td:nth-child(7)';
const DEVICE_DOWN_SEL = 'td:nth-child(6)';
const SEP = '----------------------------------------------------------------------';

var BANDWIDTH_DOWN_USED = 0;
var BANDWIDTH_UP_USED = 0;
var MAX_IP_LEN = ROUTER_IP.length;

function calculateBandwithPercentag(results) {
	results.forEach(function(result) {
		MAX_IP_LEN = Math.max(result.info[1].length, MAX_IP_LEN);
		var down = result.down.substring(6, result.down.length - 5);
		var up = result.up.substring(6, result.up.length - 5);

		BANDWIDTH_DOWN_USED += parseFloat(down);
		BANDWIDTH_UP_USED += parseFloat(up);
	});
}

function printResults(results) {
	console.log(SEP);
	console.log(TITLE);
	console.log(SEP);
	results.forEach(function(result) {
		console.log((result.info[1] + "  ").substring(0, MAX_IP_LEN) + SEPARATOR_OUTPUT +
			result.down.substring(6, result.down.length - 2) + SEPARATOR_OUTPUT +
			result.up.substring(6, result.up.length - 2) + SEPARATOR_OUTPUT +
			result.connectionType + SEPARATOR_OUTPUT +
			result.info[0]);
	});
	console.log(SEP);
	console.log('TTL - Down: ' + BANDWIDTH_DOWN_USED.toFixed(1) + ' Mb ' +
		'(' + BANDWIDTH_DOWN_USED / MAX_DOWN + '%)' +
		' - Up: ' + BANDWIDTH_UP_USED.toFixed(1) + ' Mb ' +
		'(' + BANDWIDTH_DOWN_USED / MAX_DOWN + '%)');
	console.log(SEP);
}

function main() {
	request.get('http://' + ROUTER_IP + '/DEV_device_iQoS.htm', {
		'auth': {
			'user': ROUTER_USER,
			'pass': ROUTER_PASS,
			'sendImmediately': false
		}
	}, function(error, response, body) {
		if (error ||  response.statusCode !== 200 ||
			response.headers['content-type'] !==
			'text/html; charset=\"UTF-8\"' ||
			body.length == 0) {
			console.log('Error accessing router. \n' + response);
		}
		x(body, DEVICE_TABLE_SEL, [{
			info: DEVICE_INFO_SEL,
			connectionType: DEVICE_CONNECTION_TYPE_SEL,
			up: DEVICE_UP_SEL,
			down: DEVICE_DOWN_SEL
		}])(function(err, results) {
			if (err)  {
				console.log('Error parsing device table. \n ' + err);
				return;
			}
			results = results.slice(1, results.length);

			calculateBandwithPercentag(results);

			printResults(results);
		});
	})
}

main();<commit_msg>updated percentage<commit_after>// Router Config
const ROUTER_MODEL = 'Nighthawk X6 R8000';
const ROUTER_IP = '192.168.1.1';
const ROUTER_USER = 'admin';
const ROUTER_PASS = 'password';
const MAX_UP = 1;
const MAX_DOWN = 10;

// Dependencies
const request = require('request');
const Xray = require('x-ray');
const x = Xray({
	filters: {
		split: function(value) {
			if (!value) {
				return value;
			}
			return value.split(SEPARATOR);
		}
	}
});

const SEPARATOR = '
';
const SEPARATOR_OUTPUT = ' - ';
const TITLE = ROUTER_MODEL + ' - Connected Devices';
// const DEVICE_TABLE_SEL = '#target > table > tr:nth-child(1) > td > div > ' +
// 'table > tr:nth-child(4) > td > table';
const DEVICE_TABLE_SEL = '#target > table > tr:nth-child(1) > td > div > ' +
	'table > tr:nth-child(4) > td > table > tr';
// const DEVICE_INFO_SEL = 'td:nth-child(5) @html | split';
const DEVICE_INFO_SEL = 'td:nth-child(5) > span > table > tr > ' +
	'td:nth-child(2) > span @html | split';
const DEVICE_CONNECTION_TYPE_SEL = 'td:nth-child(4)';
const DEVICE_UP_SEL = 'td:nth-child(7) > p.device-bwBarLabelPadding > span';
const DEVICE_DOWN_SEL = 'td:nth-child(6) > p.device-bwBarLabelPadding > span';
const SEP = '----------------------------------------------------------------------';

var BANDWIDTH_DOWN_USED = 0;
var BANDWIDTH_UP_USED = 0;
var MAX_IP_LEN = ROUTER_IP.length;

function calculateBandwithPercentag(results) {
	results.forEach(function(result) {
		MAX_IP_LEN = Math.max(result.info[1].length, MAX_IP_LEN);
		var down = result.down.substring(0, result.down.length - 3);
		var up = result.up.substring(0, result.up.length - 3);

		BANDWIDTH_DOWN_USED += parseFloat(down);
		BANDWIDTH_UP_USED += parseFloat(up);
	});
}

function printResults(results) {
	console.log(SEP);
	console.log(TITLE);
	console.log(SEP);
	results.forEach(function(result) {
		var down = result.down.substring(0, result.down.length - 2);
		var up = result.up.substring(0, result.down.length - 2);
		console.log((result.info[1] + "  ").substring(0, MAX_IP_LEN) +
			SEPARATOR_OUTPUT +
			down + ' (' + ((parseFloat(down) / MAX_DOWN) * 100).toFixed(0) + '%)' +
			SEPARATOR_OUTPUT +
			up + ' (' + ((parseFloat(up	) / MAX_UP) * 100).toFixed(0) + '%)' +
			SEPARATOR_OUTPUT +
			result.connectionType +
			SEPARATOR_OUTPUT +
			result.info[0]);
	});
	console.log(SEP);
	console.log('TTL - Down: ' + BANDWIDTH_DOWN_USED.toFixed(1) + ' Mb ' +
		'(' + ((BANDWIDTH_DOWN_USED / MAX_DOWN) * 100).toFixed(0) + '%)' +
		' - Up: ' + BANDWIDTH_UP_USED.toFixed(1) + ' Mb ' +
		'(' + ((BANDWIDTH_UP_USED / MAX_UP) * 100).toFixed(0) + '%)');
	console.log(SEP);
}

function main() {
	request.get('http://' + ROUTER_IP + '/DEV_device_iQoS.htm', {
		'auth': {
			'user': ROUTER_USER,
			'pass': ROUTER_PASS,
			'sendImmediately': false
		}
	}, function(error, response, body) {
		if (error ||  response.statusCode !== 200 ||
			response.headers['content-type'] !==
			'text/html; charset=\"UTF-8\"' ||
			body.length == 0) {
			console.log('Error accessing router. \n' + response);
		}
		x(body, DEVICE_TABLE_SEL, [{
			info: DEVICE_INFO_SEL,
			connectionType: DEVICE_CONNECTION_TYPE_SEL,
			up: DEVICE_UP_SEL,
			down: DEVICE_DOWN_SEL
		}])(function(err, results) {
			if (err)  {
				console.log('Error parsing device table. \n ' + err);
				return;
			}
			results = results.slice(1, results.length);

			calculateBandwithPercentag(results);

			printResults(results);
		});
	})
}

main();<|endoftext|>


<commit_before>'use strict'

const express = require('express')
const Slapp = require('slapp')
const ConvoStore = require('slapp-convo-beepboop')
const Context = require('slapp-context-beepboop')

// use `PORT` env var on Beep Boop - default to 3000 locally
var port = process.env.PORT || 3000

var slapp = Slapp({
  // Beep Boop sets the SLACK_VERIFY_TOKEN env var
  verify_token: process.env.SLACK_VERIFY_TOKEN,
  convo_store: ConvoStore(),
  context: Context()
})

var HELP_TEXT = `
I will respond to the following messages:
\`help\` - to see this message.
\`hi\` - to demonstrate a conversation that tracks state.
\`thanks\` - to demonstrate a simple response.
\`<type-any-other-text>\` - to demonstrate a random emoticon response, some of the time :wink:.
\`attachment\` - to see a Slack attachment message.
`

//*********************************************
// Setup different handlers for messages
//*********************************************

// response to the user typing "help"
slapp.message('help', ['mention', 'direct_message'], (msg) => {
  msg.say(HELP_TEXT)
})

// "Conversation" flow that tracks state - kicks off when user says hi, hello or hey
slapp
  .message('^(hi|hello|hey)$', ['direct_mention', 'direct_message'], (msg, text) => {
    msg
      .say(`${text}, how are you?`)
      // sends next event from user to this route, passing along state
      .route('how-are-you', { greeting: text })
  })
  .route('how-are-you', (msg, state) => {
    var text = (msg.body.event && msg.body.event.text) || ''

    // user may not have typed text as their next action, ask again and re-route
    if (!text) {
      return msg
        .say("Whoops, I'm still waiting to hear how you're doing.")
        .say('How are you?')
        .route('how-are-you', state)
    }

    // add their response to state
    state.status = text

    msg
      .say(`Ok then. What's your favorite color?`)
      .route('color', state)
  })
  .route('color', (msg, state) => {
    var text = (msg.body.event && msg.body.event.text) || ''

    // user may not have typed text as their next action, ask again and re-route
    if (!text) {
      return msg
        .say("I'm eagerly awaiting to hear your favorite color.")
        .route('color', state)
    }

    // add their response to state
    state.color = text

    msg
      .say('Thanks for sharing.')
      .say(`Here's what you've told me so far: \`\`\`${JSON.stringify(state)}\`\`\``)
    // At this point, since we don't route anywhere, the "conversation" is over
  })

// Can use a regex as well
slapp.message(/^(thanks|thank you)/i, ['mention', 'direct_message'], (msg) => {
  // You can provide a list of responses, and a random one will be chosen
  // You can also include slack emoji in your responses
  msg.say([
    "You're welcome :smile:",
    'You bet',
    ':+1: Of course',
    'Anytime :sun_with_face: :full_moon_with_face:'
  ])
})

// demonstrate returning an attachment...
slapp.message('attachment', ['mention', 'direct_message'], (msg) => {
  msg.say({
    text: 'Check out this amazing attachment! :confetti_ball: ',
    attachments: [{
      text: 'Slapp is a robust open source library that sits on top of the Slack APIs',
      title: 'Slapp Library - Open Source',
      image_url: 'https://storage.googleapis.com/beepboophq/_assets/bot-1.22f6fb.png',
      title_link: 'https://beepboophq.com/',
      color: '#7CD197'
    }]
  })
})

// Catch-all for any other responses not handled above
slapp.message('.*', ['direct_mention', 'direct_message'], (msg) => {
  // respond only 40% of the time
  if (Math.random() < 0.4) {
    msg.say([':wave:', ':pray:', ':raised_hands:'])
  }
})

// attach Slapp to express server
var server = slapp.attachToExpress(express())

slapp.message('SYNC ISSUE RESOLVED', (msg) => {
msg.say('Thank you!')})

slapp.message('SYNC TABLE ALERT', (msg) => {
  msg.say({
	text: '',
    attachments: [
        {
            text: 'I have detected an out of sync issue from Slackbot, who is working on it?',
            fallback: 'You are unable to choose a game',
            callback_id: 'sync_ack',
            color: '#3AA3E3',
            attachment_type: 'default',
            actions: [
                {
                    'name': 'acknowledge',
                    'text': 'Acknowledge',
                    'type': 'button',
                    'value': 'acknowledge'
                }
            ]
        }
    ]
} )
})
slapp.action('sync_ack', 'acknowledge', (msg, user) => {
  msg.respond(msg.body.response_url, `*Someone has acknowledged they are looking into the sync alert!*`)
})
// start http server
server.listen(port, (err) => {
  if (err) {
    return console.error(err)
  }

  console.log(`Listening on port ${port}`)
})
<commit_msg>did further testing<commit_after>'use strict'

const express = require('express')
const Slapp = require('slapp')
const ConvoStore = require('slapp-convo-beepboop')
const Context = require('slapp-context-beepboop')

// use `PORT` env var on Beep Boop - default to 3000 locally
var port = process.env.PORT || 3000

var slapp = Slapp({
  // Beep Boop sets the SLACK_VERIFY_TOKEN env var
  verify_token: process.env.SLACK_VERIFY_TOKEN,
  convo_store: ConvoStore(),
  context: Context()
})

var HELP_TEXT = `
I will respond to the following messages:
\`help\` - to see this message.
\`hi\` - to demonstrate a conversation that tracks state.
\`thanks\` - to demonstrate a simple response.
\`<type-any-other-text>\` - to demonstrate a random emoticon response, some of the time :wink:.
\`attachment\` - to see a Slack attachment message.
`

//*********************************************
// Setup different handlers for messages
//*********************************************

// response to the user typing "help"
slapp.message('help', ['mention', 'direct_message'], (msg) => {
  msg.say(HELP_TEXT)
})

// "Conversation" flow that tracks state - kicks off when user says hi, hello or hey
slapp
  .message('^(hi|hello|hey)$', ['direct_mention', 'direct_message'], (msg, text) => {
    msg
      .say(`${text}, how are you?`)
      // sends next event from user to this route, passing along state
      .route('how-are-you', { greeting: text })
  })
  .route('how-are-you', (msg, state) => {
    var text = (msg.body.event && msg.body.event.text) || ''

    // user may not have typed text as their next action, ask again and re-route
    if (!text) {
      return msg
        .say("Whoops, I'm still waiting to hear how you're doing.")
        .say('How are you?')
        .route('how-are-you', state)
    }

    // add their response to state
    state.status = text

    msg
      .say(`Ok then. What's your favorite color?`)
      .route('color', state)
  })
  .route('color', (msg, state) => {
    var text = (msg.body.event && msg.body.event.text) || ''

    // user may not have typed text as their next action, ask again and re-route
    if (!text) {
      return msg
        .say("I'm eagerly awaiting to hear your favorite color.")
        .route('color', state)
    }

    // add their response to state
    state.color = text

    msg
      .say('Thanks for sharing.')
      .say(`Here's what you've told me so far: \`\`\`${JSON.stringify(state)}\`\`\``)
    // At this point, since we don't route anywhere, the "conversation" is over
  })

// Can use a regex as well
slapp.message(/^(thanks|thank you)/i, ['mention', 'direct_message'], (msg) => {
  // You can provide a list of responses, and a random one will be chosen
  // You can also include slack emoji in your responses
  msg.say([
    "You're welcome :smile:",
    'You bet',
    ':+1: Of course',
    'Anytime :sun_with_face: :full_moon_with_face:'
  ])
})

// demonstrate returning an attachment...
slapp.message('attachment', ['mention', 'direct_message'], (msg) => {
  msg.say({
    text: 'Check out this amazing attachment! :confetti_ball: ',
    attachments: [{
      text: 'Slapp is a robust open source library that sits on top of the Slack APIs',
      title: 'Slapp Library - Open Source',
      image_url: 'https://storage.googleapis.com/beepboophq/_assets/bot-1.22f6fb.png',
      title_link: 'https://beepboophq.com/',
      color: '#7CD197'
    }]
  })
})

// Catch-all for any other responses not handled above
slapp.message('.*', ['direct_mention', 'direct_message'], (msg) => {
  // respond only 40% of the time
  if (Math.random() < 0.4) {
    msg.say([':wave:', ':pray:', ':raised_hands:'])
  }
})

// attach Slapp to express server
var server = slapp.attachToExpress(express())

slapp.message('SYNC ISSUE RESOLVED', (msg) => {
msg.say('Thank you!')})

slapp.message('SYNC TABLE ALERT', (msg) => {
  msg.say({
	text: '',
    attachments: [
        {
            text: 'I have detected an out of sync issue from Slackbot, who is working on it?',
            fallback: 'You are unable to choose a game',
            callback_id: 'sync_ack',
            color: '#3AA3E3',
            attachment_type: 'default',
            actions: [
                {
                    'name': 'acknowledge',
                    'text': 'Acknowledge',
                    'type': 'button',
                    'value': 'acknowledge'
                }
            ]
        }
    ]
} )
}, slaap.meta.bot_id = null)
slapp.action('sync_ack', 'acknowledge', (msg, user) => {
  msg.respond(msg.body.response_url, `*Someone has acknowledged they are looking into the sync alert!*`)
})
// start http server
server.listen(port, (err) => {
  if (err) {
    return console.error(err)
  }

  console.log(`Listening on port ${port}`)
})
<|endoftext|>


<commit_before>'use strict';

//require
let Ajv = require('ajv');
let ajv = Ajv({
    verbose: true,
    allErrors: true
    //v5: true  //enable v5 proposal of JSON-schema standard
}); // options can be passed, e.g. {allErrors: true}

//build schema
const objectid = {
    type: 'string',
    maxLength: 24,
    minLength: 1
};

//build schema
const contentItem = {
    type: 'object',
    properties: {
        order: {
            //type: 'string'
            type: 'number',
            minimum: 1
        },
        kind: {
            type: 'string',
            enum: ['deck', 'slide']
        },
        ref: {
            type: 'object',
            properties: {
                id: objectid,
                revision: {
                    type: 'number',
                    minimum: 1
                } //if not given use the last revision
            },
            required: ['id']
        }
    },
    required: ['kind', 'ref']
};
const deckRevision = {
    type: 'object',
    properties: {
        id: { //increment with every new revision
            type: 'number',
            minimum: 1
        },
        title: {
            type: 'string'
        },
        timestamp: {
            type: 'string'
        },
        user: objectid,
        parent: {
            type: 'object'
        },
        popularity: {
            type: 'number',
            minimum: 0
        },
        theme: {
            type: 'object',
            properties: {
                default: objectid
            }
        },
        transition: {
            type: 'object',
            properties: {
                default: objectid
            }
        },
        comment: {
            type: 'string'
        },
        abstract: {
            type: 'string'
        },
        footer: {
            type: 'object',
            properties: {
                text: {
                    type: 'string'
                }
            }
        },
        license: {
            type: 'string',
            enum: ['CC0', 'CC BY', 'CC BY-SA']
        },
        isFeatured: {
            type: 'number'
        },
        priority: {
            type: 'number'
        },
        visibility: {
            type: 'boolean'
        },
        language: {
            type: 'string'
        },
        translation: {
            type: 'object',
            properties: {
                status: {
                    type: 'string',
                    enum: ['original', 'google', 'revised']
                },
                source: {
                    type: 'object'
                }
            }
        },
        tags: {
            type: 'array',
            items: {
                type: 'string'
            }
        },
        preferences: {
            type: 'array',
            items: {
                type: 'object'
            }
        },
        contentItems: {
            type: 'array',
            items: contentItem
        },
        dataSources: {
            type: 'array',
            items: objectid
        },
        usage: {
            type: 'array',
            items: objectid
        }
    },
    required: ['id', 'timestamp', 'user', 'license']
};
const deck = {
    type: 'object',
    properties: {
        timestamp: {
            type: 'string'
        },
        user: objectid,
        kind: {
            type: 'string'
        },
        description: {
            type: 'string'
        },
        language: {
            type: 'string'
        },
        translation: {
            type: 'object'
        },
        lastUpdate: {
            type: 'string'
        },
        revisions: {
            type: 'array',
            items: deckRevision
        },
        tags: {
            type: 'array',
            items: {
                type: 'string'
            }
        },
        active: {
          type: 'number'
        }
    },
    required: ['timestamp', 'user']
};

//export
module.exports = ajv.compile(deck);
<commit_msg>Fixed indentation for deck.js<commit_after>'use strict';

//require
let Ajv = require('ajv');
let ajv = Ajv({
    verbose: true,
    allErrors: true
    //v5: true  //enable v5 proposal of JSON-schema standard
}); // options can be passed, e.g. {allErrors: true}

//build schema
const objectid = {
    type: 'string',
    maxLength: 24,
    minLength: 1
};

//build schema
const contentItem = {
    type: 'object',
    properties: {
        order: {
            //type: 'string'
            type: 'number',
            minimum: 1
        },
        kind: {
            type: 'string',
            enum: ['deck', 'slide']
        },
        ref: {
            type: 'object',
            properties: {
                id: objectid,
                revision: {
                    type: 'number',
                    minimum: 1
                } //if not given use the last revision
            },
            required: ['id']
        }
    },
    required: ['kind', 'ref']
};
const deckRevision = {
    type: 'object',
    properties: {
        id: { //increment with every new revision
            type: 'number',
            minimum: 1
        },
        title: {
            type: 'string'
        },
        timestamp: {
            type: 'string'
        },
        user: objectid,
        parent: {
            type: 'object'
        },
        popularity: {
            type: 'number',
            minimum: 0
        },
        theme: {
            type: 'object',
            properties: {
                default: objectid
            }
        },
        transition: {
            type: 'object',
            properties: {
                default: objectid
            }
        },
        comment: {
            type: 'string'
        },
        abstract: {
            type: 'string'
        },
        footer: {
            type: 'object',
            properties: {
                text: {
                    type: 'string'
                }
            }
        },
        license: {
            type: 'string',
            enum: ['CC0', 'CC BY', 'CC BY-SA']
        },
        isFeatured: {
            type: 'number'
        },
        priority: {
            type: 'number'
        },
        visibility: {
            type: 'boolean'
        },
        language: {
            type: 'string'
        },
        translation: {
            type: 'object',
            properties: {
                status: {
                    type: 'string',
                    enum: ['original', 'google', 'revised']
                },
                source: {
                    type: 'object'
                }
            }
        },
        tags: {
            type: 'array',
            items: {
                type: 'string'
            }
        },
        preferences: {
            type: 'array',
            items: {
                type: 'object'
            }
        },
        contentItems: {
            type: 'array',
            items: contentItem
        },
        dataSources: {
            type: 'array',
            items: objectid
        },
        usage: {
            type: 'array',
            items: objectid
        }
    },
    required: ['id', 'timestamp', 'user', 'license']
};
const deck = {
    type: 'object',
    properties: {
        timestamp: {
            type: 'string'
        },
        user: objectid,
        kind: {
            type: 'string'
        },
        description: {
            type: 'string'
        },
        language: {
            type: 'string'
        },
        translation: {
            type: 'object'
        },
        lastUpdate: {
            type: 'string'
        },
        revisions: {
            type: 'array',
            items: deckRevision
        },
        tags: {
            type: 'array',
            items: {
                type: 'string'
            }
        },
        active: {
            type: 'number'
        }
    },
    required: ['timestamp', 'user']
};

//export
module.exports = ajv.compile(deck);
<|endoftext|>


<commit_before>module.exports = {
  "rules": {
	  "at-rule-empty-line-before": [ "always", {
      except: ["first-nested"],
      ignore: ["after-comment"],
      ignoreAtRules: ["import"]
    } ],
    "at-rule-no-vendor-prefix": true,
    "block-closing-brace-newline-after": "always",
    "block-closing-brace-newline-before": "always-multi-line",
    "block-closing-brace-space-before": "always-single-line",
    "block-no-empty": true,
    "block-opening-brace-newline-after": "always-multi-line",
    "block-opening-brace-space-after": "always-single-line",
    "block-opening-brace-space-before": "always",
    "color-hex-case": "lower",
    "color-hex-length": "short",
    "color-no-invalid-hex": true,
    "comment-empty-line-before": [ "always", {
        except: ["first-nested"],
        ignore: ["stylelint-commands"]
    } ],
    "comment-whitespace-inside": null,
    "declaration-bang-space-after": "never",
    "declaration-bang-space-before": "always",
    "declaration-block-semicolon-newline-after": "always-multi-line",
    "declaration-block-semicolon-space-after": "always-single-line",
    "declaration-block-semicolon-space-before": "never",
    "declaration-block-single-line-max-declarations": 1,
    "declaration-block-no-shorthand-property-overrides": true,
    "declaration-block-properties-order": "alphabetical",
    "declaration-block-trailing-semicolon": "always",
    "declaration-colon-newline-after": "always-multi-line",
    "declaration-colon-space-after": null,
    "declaration-colon-space-before": "never",
    "function-calc-no-unspaced-operator": true,
    "function-comma-newline-after": "always-multi-line",
    "function-comma-space-after": "always-single-line",
    "function-comma-space-before": "never",
    "function-linear-gradient-no-nonstandard-direction": true,
    "function-parentheses-newline-inside": "always-multi-line",
    "function-parentheses-space-inside": "never-single-line",
    "function-whitespace-after": "always",
    "function-url-quotes": "always",
    "indentation": null,
    "length-zero-no-unit": "true",
    "max-empty-lines": 5,
    "max-line-length": 80,
    "media-feature-parentheses-space-inside": "never",
    "media-feature-colon-space-after": "always",
    "media-feature-colon-space-before": "never",
    "media-feature-name-no-vendor-prefix": true,
    "media-feature-range-operator-space-after": "always",
    "media-feature-range-operator-space-before": "always",
    "media-query-list-comma-newline-after": "always-multi-line",
    "media-query-list-comma-space-after": "always-single-line",
    "media-query-list-comma-space-before": "never",
    "no-eol-whitespace": true,
    "no-missing-end-of-source-newline": true,
    "number-leading-zero": "never",
    "number-no-trailing-zeros": true,
    "property-no-vendor-prefix": true,
    "root-no-standard-properties": null,
    "rule-nested-empty-line-before": null,
    "rule-non-nested-empty-line-before": "always-multi-line",
    "selector-combinator-space-after": "always",
    "selector-combinator-space-before": "always",
    "selector-list-comma-newline-after": "always-multi-line",
    "selector-list-comma-space-before": "never",
    "selector-no-vendor-prefix": true,
    "selector-pseudo-element-colon-notation": "double",
    "selector-root-no-composition": true,
    "string-quotes": "double",
    "value-list-comma-newline-after": "always-multi-line",
    "value-list-comma-space-after": "always-single-line",
    "value-list-comma-space-before": "never",
    "value-no-vendor-prefix": true,
  },
}
<commit_msg>Added apply to ignored atrules<commit_after>module.exports = {
  "rules": {
	  "at-rule-empty-line-before": [ "always", {
      except: ["first-nested"],
      ignore: ["after-comment"],
      ignoreAtRules: ["import", "apply"]
    } ],
    "at-rule-no-vendor-prefix": true,
    "block-closing-brace-newline-after": "always",
    "block-closing-brace-newline-before": "always-multi-line",
    "block-closing-brace-space-before": "always-single-line",
    "block-no-empty": true,
    "block-opening-brace-newline-after": "always-multi-line",
    "block-opening-brace-space-after": "always-single-line",
    "block-opening-brace-space-before": "always",
    "color-hex-case": "lower",
    "color-hex-length": "short",
    "color-no-invalid-hex": true,
    "comment-empty-line-before": [ "always", {
        except: ["first-nested"],
        ignore: ["stylelint-commands"]
    } ],
    "comment-whitespace-inside": null,
    "declaration-bang-space-after": "never",
    "declaration-bang-space-before": "always",
    "declaration-block-semicolon-newline-after": "always-multi-line",
    "declaration-block-semicolon-space-after": "always-single-line",
    "declaration-block-semicolon-space-before": "never",
    "declaration-block-single-line-max-declarations": 1,
    "declaration-block-no-shorthand-property-overrides": true,
    "declaration-block-properties-order": "alphabetical",
    "declaration-block-trailing-semicolon": "always",
    "declaration-colon-newline-after": "always-multi-line",
    "declaration-colon-space-after": null,
    "declaration-colon-space-before": "never",
    "function-calc-no-unspaced-operator": true,
    "function-comma-newline-after": "always-multi-line",
    "function-comma-space-after": "always-single-line",
    "function-comma-space-before": "never",
    "function-linear-gradient-no-nonstandard-direction": true,
    "function-parentheses-newline-inside": "always-multi-line",
    "function-parentheses-space-inside": "never-single-line",
    "function-whitespace-after": "always",
    "function-url-quotes": "always",
    "indentation": null,
    "length-zero-no-unit": "true",
    "max-empty-lines": 5,
    "max-line-length": 80,
    "media-feature-parentheses-space-inside": "never",
    "media-feature-colon-space-after": "always",
    "media-feature-colon-space-before": "never",
    "media-feature-name-no-vendor-prefix": true,
    "media-feature-range-operator-space-after": "always",
    "media-feature-range-operator-space-before": "always",
    "media-query-list-comma-newline-after": "always-multi-line",
    "media-query-list-comma-space-after": "always-single-line",
    "media-query-list-comma-space-before": "never",
    "no-eol-whitespace": true,
    "no-missing-end-of-source-newline": true,
    "number-leading-zero": "never",
    "number-no-trailing-zeros": true,
    "property-no-vendor-prefix": true,
    "root-no-standard-properties": null,
    "rule-nested-empty-line-before": null,
    "rule-non-nested-empty-line-before": "always-multi-line",
    "selector-combinator-space-after": "always",
    "selector-combinator-space-before": "always",
    "selector-list-comma-newline-after": "always-multi-line",
    "selector-list-comma-space-before": "never",
    "selector-no-vendor-prefix": true,
    "selector-pseudo-element-colon-notation": "double",
    "selector-root-no-composition": true,
    "string-quotes": "double",
    "value-list-comma-newline-after": "always-multi-line",
    "value-list-comma-space-after": "always-single-line",
    "value-list-comma-space-before": "never",
    "value-no-vendor-prefix": true,
  },
}
<|endoftext|>


<commit_before>"use strict";

class Zebra extends Individual {
    constructor(config) {
        super(config);
        this.isScaping = false;
        this.eatRadius = Utils.gaussianRandom(config.meanEatRadius, config.stdEatRadius);
        this.clip = undefined;
    }

    action(zebraBoids, tigerBoids, foodNodes) {
        if ( Math.random() > 0.5 ) {
            this.flock( zebraBoids );
        }

        //Always escape from the tigers
        this.escape(tigerBoids);
        if(!this.isScaping) {
            let value = this.tryEat(foodNodes);
            if(value) {
                this.allowMove = false;
            }
        }
    }

    build3DObject() {
        // Morphs
        this.material = new THREE.MeshPhongMaterial( {
            map: this.turing.getTexture(),//THREE.ImageUtils.loadTexture('lib/three.js-master/examples/textures/zebra_skin.jpg'),
            morphTargets: true,
        });
        this.scale = 0.2;

        this.sceneList = {
            objectScale: new THREE.Vector3(this.scale, this.scale, this.scale),
            objectRotation: new THREE.Euler(Math.PI/2,  Math.PI/2, 0)
        };

        function createMorph(individual) {
            function addMorph( geometry, speed, duration, individual) {

                let mesh = new THREE.Mesh(geometry, individual.material);

                //Animatining the mesh with the default animation ****
                mesh.speed = speed;

                let clip = geometry.animations[ 0 ];
                individual.clip = clip;
                // set duration to shift the playback out of face
                individual.mixer.clipAction( clip, mesh ).setDuration(duration )
                    .startAt( - duration * Math.random() ).play();

                //Location and Orientation of the meshes
                mesh.position.set( individual.position.x, individual.position.y, individual.position.z );

                mesh.scale.copy(individual.sceneList.objectScale);

                mesh.rotation.copy(individual.sceneList.objectRotation);

                mesh.castShadow = true;
                mesh.receiveShadow = true;

                individual.scene.add( mesh );

                individual.element3D = mesh;
            }

            let loader = new THREE.JSONLoader();
            loader.load( "models/horse.js", function( geometry ) {
                addMorph( geometry, 400, 1, individual);
            });
        }

        createMorph(this);
    }

    //escaping from tigers
    escape( boids_t ) {

        let boid_t, distance;
        let steer = new THREE.Vector3();
        this.isScaping = false;
        for (let i = 0, il = boids_t.length; i < il; i++ ) {
            boid_t = boids_t[ i ];
            distance = boid_t.position.distanceTo( this.position );

            if ( distance > 0 && distance <= this.neighborhoodRadius ) {
                steer = boid_t.position;
                this.repulse( steer );
                this.isScaping = true;
            }
        }
    }

    move3DObject() {
        this.element3D.position.copy(this.position);
        let direction = new THREE.Vector3();
        this.element3D.getWorldDirection(direction);

        //
        let indAngle = Math.atan2( direction.z , direction.x );
        let velAngle = Math.atan2( this.velocity.y , this.velocity.x );
        let velOldAngle = Math.atan2( this.oldVelocity.y , this.oldVelocity.x );
        let angleDifference = velAngle + velOldAngle;

        this.element3D.rotation.y = (angleDifference / 2) + (Math.PI / 2);
        this.oldVelocity = this.velocity;
    }
}<commit_msg>zebras movement fixed<commit_after>"use strict";

class Zebra extends Individual {
    constructor(config) {
        super(config);
        this.isScaping = false;
        this.eatRadius = Utils.gaussianRandom(config.meanEatRadius, config.stdEatRadius);
        this.clip = undefined;
        this.moving = true;
    }

    action(zebraBoids, tigerBoids, foodNodes) {
        if ( Math.random() > 0.5 ) {
            this.flock( zebraBoids );
        }

        //Always escape from the tigers
        this.escape(tigerBoids);
        if(!this.isScaping) {
            let value = this.tryEat(foodNodes);
            if(value) {
                this.allowMove = false;
                if(this.moving) {
                    this.mixer.clipAction( this.clip, this.element3D ).stop();
                    this.moving = false;
                }
            }
        } else if(!this.moving){
            this.mixer.clipAction(this.clip, this.element3D).setDuration(1)
                .startAt(-1 * Math.random()).play();
            this.moving = true;
        }
    }

    setDeath() {
        super.setDeath();
        this.mixer.clipAction( this.clip, this.element3D ).stop();
    }

    build3DObject() {
        // Morphs
        this.material = new THREE.MeshPhongMaterial( {
            map: this.turing.getTexture(),//THREE.ImageUtils.loadTexture('lib/three.js-master/examples/textures/zebra_skin.jpg'),
            morphTargets: true,
        });
        this.scale = 0.2;

        this.sceneList = {
            objectScale: new THREE.Vector3(this.scale, this.scale, this.scale),
            objectRotation: new THREE.Euler(Math.PI/2,  Math.PI/2, 0)
        };

        function createMorph(individual) {
            function addMorph( geometry, speed, duration, individual) {

                let mesh = new THREE.Mesh(geometry, individual.material);

                //Animatining the mesh with the default animation ****
                mesh.speed = speed;

                let clip = geometry.animations[ 0 ];
                individual.clip = clip;
                // set duration to shift the playback out of face
                individual.mixer.clipAction( clip, mesh ).setDuration(duration )
                    .startAt( - duration * Math.random() ).play();

                //Location and Orientation of the meshes
                mesh.position.set( individual.position.x, individual.position.y, individual.position.z );

                mesh.scale.copy(individual.sceneList.objectScale);

                mesh.rotation.copy(individual.sceneList.objectRotation);

                mesh.castShadow = true;
                mesh.receiveShadow = true;

                individual.scene.add( mesh );

                individual.element3D = mesh;
            }

            let loader = new THREE.JSONLoader();
            loader.load( "models/horse.js", function( geometry ) {
                addMorph( geometry, 400, 1, individual);
            });
        }

        createMorph(this);
    }

    //escaping from tigers
    escape( boids_t ) {

        let boid_t, distance;
        let steer = new THREE.Vector3();
        this.isScaping = false;
        for (let i = 0, il = boids_t.length; i < il; i++ ) {
            boid_t = boids_t[ i ];
            distance = boid_t.position.distanceTo( this.position );

            if ( distance > 0 && distance <= this.neighborhoodRadius ) {
                steer = boid_t.position;
                this.repulse( steer );
                this.isScaping = true;
            }
        }
    }

    move3DObject() {
        this.element3D.position.copy(this.position);
        let direction = new THREE.Vector3();
        this.element3D.getWorldDirection(direction);

        //
        let indAngle = Math.atan2( direction.z , direction.x );
        let velAngle = Math.atan2( this.velocity.y , this.velocity.x );
        let velOldAngle = Math.atan2( this.oldVelocity.y , this.oldVelocity.x );
        let angleDifference = velAngle + velOldAngle;

        this.element3D.rotation.y = (angleDifference / 2) + (Math.PI / 2);
        this.oldVelocity = this.velocity;
    }
}<|endoftext|>


<commit_before>const path = require('path')
const webpack = require('webpack')

const {
  runByHBuilderX,
  isInHBuilderX,
  parseJson,
  parsePagesJson,
  parseManifestJson
} = require('@dcloudio/uni-cli-shared')

const uniI18n = require('@dcloudio/uni-cli-i18n')

const defaults = {
  clean: true,
  target: 'app',
  'unsafe-inline': true
}

const modifyConfig = (config, fn) => {
  if (Array.isArray(config)) {
    config.forEach(c => fn(c))
  } else {
    fn(config)
  }
}

module.exports = (api, options) => {
  api.registerCommand('uni-build', {
    description: 'build for production',
    usage: 'vue-cli-service uni-build [options]',
    options: {
      '--watch': 'watch for changes',
      '--minimize': 'Tell webpack to minimize the bundle using the TerserPlugin.',
      '--auto-host': 'specify automator host',
      '--auto-port': 'specify automator port',
      '--subpackage': 'specify subpackage',
      '--plugin': 'specify mp plugin',
      '--manifest': 'build manifest.json',
      '--sourcemap': 'generate sourcemap'
    }
  }, async (args) => {
    for (const key in defaults) {
      if (args[key] == null) {
        args[key] = defaults[key]
      }
    }

    if (args.manifest && process.env.UNI_PLATFORM === 'app-plus') {
      return buildManifestJson()
    }

    const platforms = ['mp-weixin', 'mp-qq', 'mp-jd', 'mp-baidu', 'mp-alipay', 'mp-toutiao', 'mp-lark']
    if (args.subpackage && platforms.includes(process.env.UNI_PLATFORM)) {
      process.env.UNI_SUBPACKGE = args.subpackage
    }

    const mpPluginPlatforms = ['mp-weixin', 'mp-alipay']
    if (args.plugin) {
      if (mpPluginPlatforms.includes(process.env.UNI_PLATFORM)) {
        process.env.UNI_MP_PLUGIN = args.plugin
        analysisPluginDir()
      } else {
        console.log()
        console.error(uniI18n.__('pluginUni.compileToMpPluginOnlySupportPlatform'))
        console.log()
        process.exit(0)
      }
    }

    require('./util').initAutomator(args)

    args.entry = args.entry || args._[0]

    process.env.VUE_CLI_BUILD_TARGET = args.target

    if (args.sourcemap) process.env.SOURCEMAP = args.sourcemap

    await build(args, api, options)

    delete process.env.VUE_CLI_BUILD_TARGET
  })
}

function getWebpackConfig (api, args, options) {
  const validateWebpackConfig = require('@vue/cli-service/lib/util/validateWebpackConfig')
  // resolve raw webpack config
  const webpackConfig = require('@vue/cli-service/lib/commands/build/resolveAppConfig')(api, args, options)

  // check for common config errors
  validateWebpackConfig(webpackConfig, api, options, args.target)

  if (args.watch) {
    modifyConfig(webpackConfig, config => {
      config.watch = true
    })
  }

  if (args.minimize && process.env.NODE_ENV !== 'production') {
    modifyConfig(webpackConfig, config => {
      config.optimization.minimize = true
      if (webpack.version[0] <= 4) {
        config.optimization.namedModules = false
      }
    })
  } else {
    modifyConfig(webpackConfig, config => {
      if (!config.optimization) {
        config.optimization = {}
      }
      if (webpack.version[0] <= 4) {
        config.optimization.namedModules = false
      }
    })
  }
  return webpackConfig
}

function getWebpackConfigs (api, args, options) {
  if (!process.env.UNI_USING_V3) {
    return [getWebpackConfig(api, args, options)]
  }
  const pluginOptions = (options.pluginOptions || (options.pluginOptions = {}))
  pluginOptions['uni-app-plus'] = {
    service: true
  }
  options.publicPath = '/'
  const serviceWebpackConfig = getWebpackConfig(api, args, options)
  delete pluginOptions['uni-app-plus'].service
  pluginOptions['uni-app-plus'].view = true
  options.publicPath = './'
  const viewWebpackConfig = getWebpackConfig(api, args, options)
  return [serviceWebpackConfig, viewWebpackConfig]
}

async function build (args, api, options) {
  const fs = require('fs-extra')
  const chalk = require('chalk')

  const {
    log,
    done,
    logWithSpinner,
    stopSpinner
  } = require('@vue/cli-shared-utils')

  const runByAliIde = process.env.BUILD_ENV === 'ali-ide'

  log()

  if (!runByHBuilderX && !runByAliIde) {
    logWithSpinner(uniI18n.__('pluginUni.startCompileProjectToPlatform', {
      0: process.env.UNI_SUB_PLATFORM || process.env.UNI_PLATFORM,
      1: process.env.UNI_MP_PLUGIN ? uniI18n.__('plugin') : uniI18n.__('platform')
    }))
  }

  const targetDir = api.resolve(options.outputDir)

  const webpackConfigs = getWebpackConfigs(api, args, options)

  if (process.env.NODE_ENV === 'production') {
    try {
      fs.emptyDir(path.resolve(process.env.UNI_CLI_CONTEXT, 'node_modules/.cache'))
    } catch (e) {}
  }

  if (args.clean || process.env.UNI_PLATFORM === 'app-plus') {
    await fs.emptyDir(targetDir)
  }

  if (process.env.UNI_USING_NATIVE || process.env.UNI_USING_V3_NATIVE) {
    webpackConfigs.length = 0
  }

  if (
    process.env.UNI_USING_NATIVE ||
    process.env.UNI_USING_V3_NATIVE ||
    (process.UNI_NVUE_ENTRY && Object.keys(process.UNI_NVUE_ENTRY).length)
  ) {
    webpackConfigs.push(require('@dcloudio/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js')(process
      .UNI_NVUE_ENTRY))
  }

  return new Promise((resolve, reject) => {
    webpack(webpackConfigs, (err, stats) => {
      if (!runByHBuilderX && !runByAliIde) {
        stopSpinner(false)
      }
      if (err) {
        return reject(err)
      }

      if (stats.hasErrors()) {
        /* eslint-disable prefer-promise-reject-errors */
        return reject('Build failed with errors.')
      }

      if (!args.silent && (process.env.UNI_PLATFORM !== 'app-plus' || process.env
        .UNI_AUTOMATOR_WS_ENDPOINT)) {
        const targetDirShort = path.relative(
          api.service.context,
          process.env.UNI_OUTPUT_DIR
        )

        if (!args.watch) {
          const dirMsg = runByHBuilderX ? ''
            : `The ${chalk.cyan(targetDirShort)} directory is ready to be deployed.`
          done(`Build complete. ${dirMsg}`)

          if (process.env.UNI_PLATFORM === 'h5' && !isInHBuilderX) {
            console.log()
            console.log('欢迎将H5站部署到uniCloud前端网页托管平台，高速、免费、安全、省心，详见：https://uniapp.dcloud.io/uniCloud/hosting')
          }
        } else {
          const dirMsg = runByHBuilderX ? ''
            : `The ${chalk.cyan(targetDirShort)} directory is ready. `
          done(`Build complete. ${dirMsg}Watching for changes...`)
        }
      }

      resolve()
    })
  })
}

module.exports.defaultModes = {
  'uni-build': process.env.NODE_ENV
}

/**
 * 编译到微信小程序插件 文件校验
 */
function analysisPluginDir () {
  const fs = require('fs-extra')

  // plugin.json 是否存在
  const pluginJsonName = 'plugin.json'
  const pluginJsonPath = path.resolve(process.env.UNI_INPUT_DIR, pluginJsonName)

  if (!fs.pathExistsSync(pluginJsonPath)) {
    console.log()
    console.error(uniI18n.__('pluginUni.fileNoExistsCheckAfterRetry', {
      0: pluginJsonName
    }))
    console.log()
    process.exit(0)
  }

  const pluginJson = parseJson(fs.readFileSync(pluginJsonPath, 'utf-8'), true)

  // main 入口文件是否存在
  if (pluginJson.main) {
    process.env.UNI_MP_PLUGIN_MAIN = pluginJson.main
    const UNI_MP_PLUGIN_MAIN = process.env.UNI_MP_PLUGIN_MAIN
    const mainFilePath = path.resolve(process.env.UNI_INPUT_DIR, UNI_MP_PLUGIN_MAIN)

    if (UNI_MP_PLUGIN_MAIN && !fs.pathExistsSync(mainFilePath)) {
      console.log()
      console.error(uniI18n.__('pluginUni.entryDileNoExistsCheckAfterRetry', {
        0: UNI_MP_PLUGIN_MAIN
      }))
      console.log()
      process.exit(0)
    }
  }
}

function buildManifestJson () {
  const fs = require('fs-extra')
  const inputDir = process.env.UNI_INPUT_DIR
  const outputDir = process.env.UNI_OUTPUT_DIR
  const pagesJsonPath = path.resolve(inputDir, 'pages.json')
  const manifestJsonPath = path.resolve(inputDir, 'manifest.json')

  const pagesJson = parsePagesJson(fs.readFileSync(pagesJsonPath, 'utf8'))
  const manifestJson = parseManifestJson(fs.readFileSync(manifestJsonPath, 'utf8'))

  const res = require('@dcloudio/webpack-uni-pages-loader/lib/platforms/app-plus/index.js')(pagesJson,
    manifestJson,
    false)
  if (res && res[0]) {
    fs.outputFileSync(
      path.resolve(outputDir, 'manifest.json'),
      res[0].content
    )
  }
  const {
    done
  } = require('@vue/cli-shared-utils')
  done('Build complete.')
}
<commit_msg>chore: update log<commit_after>const path = require('path')
const webpack = require('webpack')

const {
  runByHBuilderX,
  isInHBuilderX,
  parseJson,
  parsePagesJson,
  parseManifestJson
} = require('@dcloudio/uni-cli-shared')

const uniI18n = require('@dcloudio/uni-cli-i18n')

const defaults = {
  clean: true,
  target: 'app',
  'unsafe-inline': true
}

const modifyConfig = (config, fn) => {
  if (Array.isArray(config)) {
    config.forEach(c => fn(c))
  } else {
    fn(config)
  }
}

module.exports = (api, options) => {
  api.registerCommand('uni-build', {
    description: 'build for production',
    usage: 'vue-cli-service uni-build [options]',
    options: {
      '--watch': 'watch for changes',
      '--minimize': 'Tell webpack to minimize the bundle using the TerserPlugin.',
      '--auto-host': 'specify automator host',
      '--auto-port': 'specify automator port',
      '--subpackage': 'specify subpackage',
      '--plugin': 'specify mp plugin',
      '--manifest': 'build manifest.json',
      '--sourcemap': 'generate sourcemap'
    }
  }, async (args) => {
    for (const key in defaults) {
      if (args[key] == null) {
        args[key] = defaults[key]
      }
    }

    if (args.manifest && process.env.UNI_PLATFORM === 'app-plus') {
      return buildManifestJson()
    }

    const platforms = ['mp-weixin', 'mp-qq', 'mp-jd', 'mp-baidu', 'mp-alipay', 'mp-toutiao', 'mp-lark']
    if (args.subpackage && platforms.includes(process.env.UNI_PLATFORM)) {
      process.env.UNI_SUBPACKGE = args.subpackage
    }

    const mpPluginPlatforms = ['mp-weixin', 'mp-alipay']
    if (args.plugin) {
      if (mpPluginPlatforms.includes(process.env.UNI_PLATFORM)) {
        process.env.UNI_MP_PLUGIN = args.plugin
        analysisPluginDir()
      } else {
        console.log()
        console.error(uniI18n.__('pluginUni.compileToMpPluginOnlySupportPlatform'))
        console.log()
        process.exit(0)
      }
    }

    require('./util').initAutomator(args)

    args.entry = args.entry || args._[0]

    process.env.VUE_CLI_BUILD_TARGET = args.target

    if (args.sourcemap) process.env.SOURCEMAP = args.sourcemap

    await build(args, api, options)

    delete process.env.VUE_CLI_BUILD_TARGET
  })
}

function getWebpackConfig (api, args, options) {
  const validateWebpackConfig = require('@vue/cli-service/lib/util/validateWebpackConfig')
  // resolve raw webpack config
  const webpackConfig = require('@vue/cli-service/lib/commands/build/resolveAppConfig')(api, args, options)

  // check for common config errors
  validateWebpackConfig(webpackConfig, api, options, args.target)

  if (args.watch) {
    modifyConfig(webpackConfig, config => {
      config.watch = true
    })
  }

  if (args.minimize && process.env.NODE_ENV !== 'production') {
    modifyConfig(webpackConfig, config => {
      config.optimization.minimize = true
      if (webpack.version[0] <= 4) {
        config.optimization.namedModules = false
      }
    })
  } else {
    modifyConfig(webpackConfig, config => {
      if (!config.optimization) {
        config.optimization = {}
      }
      if (webpack.version[0] <= 4) {
        config.optimization.namedModules = false
      }
    })
  }
  return webpackConfig
}

function getWebpackConfigs (api, args, options) {
  if (!process.env.UNI_USING_V3) {
    return [getWebpackConfig(api, args, options)]
  }
  const pluginOptions = (options.pluginOptions || (options.pluginOptions = {}))
  pluginOptions['uni-app-plus'] = {
    service: true
  }
  options.publicPath = '/'
  const serviceWebpackConfig = getWebpackConfig(api, args, options)
  delete pluginOptions['uni-app-plus'].service
  pluginOptions['uni-app-plus'].view = true
  options.publicPath = './'
  const viewWebpackConfig = getWebpackConfig(api, args, options)
  return [serviceWebpackConfig, viewWebpackConfig]
}

async function build (args, api, options) {
  const fs = require('fs-extra')
  const chalk = require('chalk')

  const {
    log,
    done,
    logWithSpinner,
    stopSpinner
  } = require('@vue/cli-shared-utils')

  const runByAliIde = process.env.BUILD_ENV === 'ali-ide'

  log()

  if (!runByHBuilderX && !runByAliIde) {
    logWithSpinner(uniI18n.__('pluginUni.startCompileProjectToPlatform', {
      0: process.env.UNI_SUB_PLATFORM || process.env.UNI_PLATFORM,
      1: process.env.UNI_MP_PLUGIN ? uniI18n.__('plugin') : uniI18n.__('platform')
    }))
  }

  const targetDir = api.resolve(options.outputDir)

  const webpackConfigs = getWebpackConfigs(api, args, options)

  if (process.env.NODE_ENV === 'production') {
    try {
      fs.emptyDir(path.resolve(process.env.UNI_CLI_CONTEXT, 'node_modules/.cache'))
    } catch (e) {}
  }

  if (args.clean || process.env.UNI_PLATFORM === 'app-plus') {
    await fs.emptyDir(targetDir)
  }

  if (process.env.UNI_USING_NATIVE || process.env.UNI_USING_V3_NATIVE) {
    webpackConfigs.length = 0
  }

  if (
    process.env.UNI_USING_NATIVE ||
    process.env.UNI_USING_V3_NATIVE ||
    (process.UNI_NVUE_ENTRY && Object.keys(process.UNI_NVUE_ENTRY).length)
  ) {
    webpackConfigs.push(require('@dcloudio/vue-cli-plugin-hbuilderx/build/webpack.nvue.conf.js')(process
      .UNI_NVUE_ENTRY))
  }

  return new Promise((resolve, reject) => {
    webpack(webpackConfigs, (err, stats) => {
      if (!runByHBuilderX && !runByAliIde) {
        stopSpinner(false)
      }
      if (err) {
        return reject(err)
      }

      if (stats.hasErrors()) {
        /* eslint-disable prefer-promise-reject-errors */
        return reject('Build failed with errors.')
      }

      if (!args.silent && (process.env.UNI_PLATFORM !== 'app-plus' || process.env
        .UNI_AUTOMATOR_WS_ENDPOINT)) {
        const targetDirShort = path.relative(
          api.service.context,
          process.env.UNI_OUTPUT_DIR
        )

        if (!args.watch) {
          const dirMsg = runByHBuilderX ? ''
            : `The ${chalk.cyan(targetDirShort)} directory is ready to be deployed.`
          done(`Build complete. ${dirMsg}`)

          if (process.env.UNI_PLATFORM === 'h5' && !isInHBuilderX) {
            console.log()
            console.log('欢迎将web站点部署到uniCloud前端网页托管平台，高速、免费、安全、省心，详见：https://uniapp.dcloud.io/uniCloud/hosting')
          }
        } else {
          const dirMsg = runByHBuilderX ? ''
            : `The ${chalk.cyan(targetDirShort)} directory is ready. `
          done(`Build complete. ${dirMsg}Watching for changes...`)
        }
      }

      resolve()
    })
  })
}

module.exports.defaultModes = {
  'uni-build': process.env.NODE_ENV
}

/**
 * 编译到微信小程序插件 文件校验
 */
function analysisPluginDir () {
  const fs = require('fs-extra')

  // plugin.json 是否存在
  const pluginJsonName = 'plugin.json'
  const pluginJsonPath = path.resolve(process.env.UNI_INPUT_DIR, pluginJsonName)

  if (!fs.pathExistsSync(pluginJsonPath)) {
    console.log()
    console.error(uniI18n.__('pluginUni.fileNoExistsCheckAfterRetry', {
      0: pluginJsonName
    }))
    console.log()
    process.exit(0)
  }

  const pluginJson = parseJson(fs.readFileSync(pluginJsonPath, 'utf-8'), true)

  // main 入口文件是否存在
  if (pluginJson.main) {
    process.env.UNI_MP_PLUGIN_MAIN = pluginJson.main
    const UNI_MP_PLUGIN_MAIN = process.env.UNI_MP_PLUGIN_MAIN
    const mainFilePath = path.resolve(process.env.UNI_INPUT_DIR, UNI_MP_PLUGIN_MAIN)

    if (UNI_MP_PLUGIN_MAIN && !fs.pathExistsSync(mainFilePath)) {
      console.log()
      console.error(uniI18n.__('pluginUni.entryDileNoExistsCheckAfterRetry', {
        0: UNI_MP_PLUGIN_MAIN
      }))
      console.log()
      process.exit(0)
    }
  }
}

function buildManifestJson () {
  const fs = require('fs-extra')
  const inputDir = process.env.UNI_INPUT_DIR
  const outputDir = process.env.UNI_OUTPUT_DIR
  const pagesJsonPath = path.resolve(inputDir, 'pages.json')
  const manifestJsonPath = path.resolve(inputDir, 'manifest.json')

  const pagesJson = parsePagesJson(fs.readFileSync(pagesJsonPath, 'utf8'))
  const manifestJson = parseManifestJson(fs.readFileSync(manifestJsonPath, 'utf8'))

  const res = require('@dcloudio/webpack-uni-pages-loader/lib/platforms/app-plus/index.js')(pagesJson,
    manifestJson,
    false)
  if (res && res[0]) {
    fs.outputFileSync(
      path.resolve(outputDir, 'manifest.json'),
      res[0].content
    )
  }
  const {
    done
  } = require('@vue/cli-shared-utils')
  done('Build complete.')
}
<|endoftext|>