<commit_before>// transform
// Functions for transformation matrices, and to be exact,
// affine non-reflective similarity transformation matrices.
//

// Default epsilon to use when coping with floating point arithmetics.
// JavaScript floating point numbers have 52 bits in mantissa (IEEE-754).
// That is about 16 base10 numbers. Therefore the epsilon should be
// much larger than 1 * 10^-16. Let say 1 * 10^-10 is a good one.
exports.EPSILON = 0.0000000001

exports.create = function (a, b, x, y) {
  // Create a transform object. Check that parameters valid.
  //
  if (typeof a !== 'number') {
    throw new Error('Invalid transform property a: ' + a)
  }
  if (typeof b !== 'number') {
    throw new Error('Invalid transform property b: ' + b)
  }
  if (typeof x !== 'number') {
    throw new Error('Invalid transform property x: ' + x)
  }
  if (typeof y !== 'number') {
    throw new Error('Invalid transform property y: ' + y)
  }

  return {
    a: a,
    b: b,
    x: x,
    y: y
  }
}

exports.createFromPolar = function (scale, rotation, tx, ty) {
  // Create a nudged.transform object by using scale magnitude,
  // rotation angle, and translation.
  //
  // Parameters:
  //   scale
  //     number, the scaling factor
  //   rotation
  //     number, rotation in radians from positive x axis towards pos. y axis.
  //   tx
  //     translation toward pos. x
  //   ty
  //     translation toward pos. y
  //
  // Return
  //   a transform object
  //
  return {
    a: scale * Math.cos(rotation),
    b: scale * Math.sin(rotation),
    x: tx,
    y: ty
  }
}

exports.createFromArray = function (abxy) {
  return {
    a: abxy[0],
    b: abxy[1],
    x: abxy[2],
    y: abxy[3]
  }
}

exports.almostEqual =
exports.almostEquals = function (tr, ts, epsilon) {
  // Are two transforms almost equal? Return true if a matrix norm
  // of the difference is smaller than epsilon. We use modified L1 norm
  // that values a, B, x, and y as equally important.
  //
  // Parameters:
  //   tr
  //     a transform
  //   ts
  //     a transform
  //   epsilon
  //     optional number, default to transform.EPSILON.
  //     Set to 0 for strict comparison.
  //
  // Note:
  //   We first thought to use Frobenius norm to compare
  //   against epsilon but it felt wrong
  //   because it exaggerates a and b. Proof:
  //     We know Frobenius norm for real square matrices:
  //       Norm(A) = sqrt(sum_i(sum_j(a_ij * a_ij)))
  //     For a transform it looks like:
  //       Norm(T) = sqrt(a*a + b*b + x*x + b*b + a*a + y*y + 1)
  //     Thus a and b have twice the impact.
  //
  if (typeof epsilon !== 'number') {
    epsilon = exports.EPSILON
  }

  const da = Math.abs(tr.a - ts.a)
  const db = Math.abs(tr.b - ts.b)
  const dx = Math.abs(tr.x - ts.x)
  const dy = Math.abs(tr.y - ts.y)

  // smaller-or-equal instead of smaller-than to make epsilon=0 work.
  return da + db + dx + dy <= epsilon
}

exports.equal =
exports.equals = function (tr, ts) {
  // Are transforms equal?
  //
  // Parameters:
  //   tr
  //     a transform
  //   ts
  //     a transform
  //
  return (tr.a === ts.a && tr.b === ts.b &&
    tr.x === ts.x && tr.y === ts.y)
}

exports.getMatrix = function (tr) {
  // Get the similarity transformation matrix
  // in the format common to other APIs, including:
  // - kld-affine
  // - MDN documentation in some parts
  //
  // Return
  //   object o, having properties a, b, c, d, e, f:
  //   [ a  -b   x ]   [ o.a  o.c  o.e ]
  //   [ b   a   y ] = [ o.b  o.d  o.f ]
  //   [ 0   0   1 ]   [  -    -    -  ]
  return {
    a: tr.a,
    b: tr.b,
    c: -tr.b,
    d: tr.a,
    e: tr.x,
    f: tr.y
  }
}

exports.getRotation = function (tr) {
  // in rads
  return Math.atan2(tr.b, tr.a)
}

exports.getScale = function (tr) {
  // scale multiplier
  return Math.sqrt(tr.b * tr.b + tr.a * tr.a)
}

exports.getTranslation = function (tr) {
  // Current translation as a point.
  return {
    x: tr.x,
    y: tr.y
  }
}

exports.toArray = function (tr) {
  // Return an array representation of the transformation.
  //
  // Compatible with nudged.createFromArray(...)
  return [tr.a, tr.b, tr.x, tr.y]
}

exports.toString = function (tr) {
  // Return a string of CSS transform-function data type.
  //
  // Together with nudged.createFromString(...), this method allows
  // serialization to and from strings.
  //
  // NOTE When JavaScript converts numbers to strings, the string might
  // end up using the scientific notation (e.g. 1e-12). Not all browsers
  // support scientific notation in CSS. We have experienced problems
  // with Safari and Opera. Therefore toString must prevent the scientific
  // notation here and convert to fixed number of decimal places.
  //
  // See also: https://stackoverflow.com/q/1685680/638546
  //
  const a = tr.a.toFixed(8)
  const b = tr.b.toFixed(8)
  const c = (-tr.b).toFixed(8) // Unnecessary? Maybe '-' + b? No, e.g. '--1.2'
  const x = tr.x.toFixed(8)
  const y = tr.y.toFixed(8)
  return 'matrix(' + a + ',' + b + ',' + c + ',' + a + ',' + x + ',' + y + ')'
}

exports.point = function (tr, p) {
  // Transform a point
  //
  // Parameters
  //   tr
  //     a transfrom
  //   p
  //     a xy point
  //
  // Return
  //   the tronsformed xy point
  //
  return {
    x: tr.a * p.x - tr.b * p.y + tr.x,
    y: tr.b * p.x + tr.a * p.y + tr.y
  }
}

exports.points = function (tr, ps) {
  // Transform an array of points
  //
  // Parameters
  //   tr
  //     a transform
  //   ps
  //     an array of points
  const c = []
  for (let i = 0; i < ps.length; i += 1) {
    c.push(exports.point(tr, ps[i]))
  }
}

exports.inverse = function (tr) {
  // Return inversed transform
  // See note 2015-10-26-16-30
  const det = tr.a * tr.a + tr.b * tr.b
  // Test if singular transformation. These might occur when all the range
  // points are the same, forcing the scale to drop to zero.
  if (Math.abs(det) < Transform.EPSILON) {
    throw new Error('Singular transformations cannot be inversed.')
  }
  const ahat = tr.a / det
  const bhat = -tr.b / det
  const xhat = (-tr.a * tr.x - tr.b * tr.y) / det
  const yhat = (tr.b * tr.x - tr.a * tr.y) / det

  return {
    a: ahat,
    b: bhat,
    x: xhat,
    y: yhat
  }
}

// exports.addVector = ?
// exports.translateBy =
exports.translate = function (tr, vec) {
  // Modify transformation so that its image
  // is translated by the given vector.
  // In other words it transforms points
  // further by the given vector.
  //
  // Parameters
  //   tr
  //     a transform
  //   vec
  //     a 2d vector { dx, dy }
  //
  // Return
  //   a transform
  //
  return {
    a: tr.a,
    b: tr.b,
    x: tr.x + vec.dx,
    y: tr.y + vec.dy
  }
}

// exports.translateTo = function (tr, p) {
//   // Modify transformation so that it translates (0, 0)
//   // to the given point.
//   //
//   // Parameters
//   //   tr
//   //     a transform
//   //   p
//   //     a 2d point { x, y }
//   //
//   //
//
// }

exports.scale = function (tr, center, multiplier) {
  // Scale image of the transform so that the given
  // center point stays fixed.
  //
  // Parameter
  //   tr
  //     a transform
  //   center
  //     a point
  //   multiplier
  //     a number
  //
  // Return
  //   a transform
  //
  const m = multiplier // alias
  const cx = center.x
  const cy = center.y
  return {
    a: m * tr.a,
    b: m * tr.b,
    x: m * tr.x + (1 - m) * cx,
    y: m * tr.y + (1 - m) * cy
  }
}

exports.rotate = function (tr, center, radians) {
  // Rotate image of the transform so that the given
  // center point stays fixed.
  //
  // Parameter
  //   tr
  //     a transform
  //   center
  //     a point
  //   radians
  //     a number, angle
  //
  // Return
  //   a transform
  //
  const co = Math.cos(radians)
  const si = Math.sin(radians)

  const cx = pivot[0]
  const cy = pivot[1]

  const ahat = tr.a * co - tr.b * si
  const bhat = tr.a * si + tr.b * co
  const xhat = (tr.x - cx) * co - (tr.y - cy) * si + cx
  const yhat = (tr.x - cx) * si + (tr.y - cy) * co + cy

  return {
    a: ahat,
    b: bhat,
    x: xhat,
    y: yhat
  }
}

exports.compose =
exports.multiply = function (tr, ts) {
  // Multiply transformation matrix tr from
  // the right with the given transformation matrix ts.
  // In other words, transform the image of ts by tr.
  //
  // For reading aid:
  //   a -b  x    a -b  x
  //   b  a  y *  b  a  y
  //   0  0  1    0  0  1
  //
  return {
    a: tr.a * ts.a - tr.b * ts.b,
    b: tr.a * ts.b + tr.b * ts.a,
    x: tr.a * ts.x - tr.b * ts.y + tr.x,
    y: tr.b * ts.x + tr.a * ts.y + tr.y
  }
}

exports.IDENTITY = {
  a: 1,
  b: 0,
  x: 0,
  y: 0
}

exports.ROT90 = { a: 0, b: 1, x: 0, y: 0 }
exports.ROT180 = { a: -1, b: 0, x: 0, y: 0 }
exports.ROT270 = { a: 0, b: -1, x: 0, y: 0 }
exports.X2 = { a: 2, b: 0, x: 0, y: 0 }
<commit_msg>Remove type checks from transform.create<commit_after>// transform
// Functions for transformation matrices, and to be exact,
// affine non-reflective similarity transformation matrices.
//

// Default epsilon to use when coping with floating point arithmetics.
// JavaScript floating point numbers have 52 bits in mantissa (IEEE-754).
// That is about 16 base10 numbers. Therefore the epsilon should be
// much larger than 1 * 10^-16. Let say 1 * 10^-10 is a good one.
exports.EPSILON = 0.0000000001

exports.create = function (a, b, x, y) {
  // Create a transform object.
  //
  // Parameters
  //   a
  //     number. The diagonal of linear transformation.
  //   b
  //     number. The upper and lower triangle of lin. transf.
  //   x
  //     number. The translation towards x
  //   y
  //     number. The translation towards y
  //
  // Return
  //   a transform object
  //
  return {
    a: a,
    b: b,
    x: x,
    y: y
  }
}

exports.createFromPolar = function (scale, rotation, tx, ty) {
  // Create a nudged.transform object by using scale magnitude,
  // rotation angle, and translation.
  //
  // Parameters:
  //   scale
  //     number, the scaling factor
  //   rotation
  //     number, rotation in radians from positive x axis towards pos. y axis.
  //   tx
  //     translation toward pos. x
  //   ty
  //     translation toward pos. y
  //
  // Return
  //   a transform object
  //
  return {
    a: scale * Math.cos(rotation),
    b: scale * Math.sin(rotation),
    x: tx,
    y: ty
  }
}

exports.createFromArray = function (abxy) {
  return {
    a: abxy[0],
    b: abxy[1],
    x: abxy[2],
    y: abxy[3]
  }
}

exports.almostEqual =
exports.almostEquals = function (tr, ts, epsilon) {
  // Are two transforms almost equal? Return true if a matrix norm
  // of the difference is smaller than epsilon. We use modified L1 norm
  // that values a, B, x, and y as equally important.
  //
  // Parameters:
  //   tr
  //     a transform
  //   ts
  //     a transform
  //   epsilon
  //     optional number, default to transform.EPSILON.
  //     Set to 0 for strict comparison.
  //
  // Note:
  //   We first thought to use Frobenius norm to compare
  //   against epsilon but it felt wrong
  //   because it exaggerates a and b. Proof:
  //     We know Frobenius norm for real square matrices:
  //       Norm(A) = sqrt(sum_i(sum_j(a_ij * a_ij)))
  //     For a transform it looks like:
  //       Norm(T) = sqrt(a*a + b*b + x*x + b*b + a*a + y*y + 1)
  //     Thus a and b have twice the impact.
  //
  if (typeof epsilon !== 'number') {
    epsilon = exports.EPSILON
  }

  const da = Math.abs(tr.a - ts.a)
  const db = Math.abs(tr.b - ts.b)
  const dx = Math.abs(tr.x - ts.x)
  const dy = Math.abs(tr.y - ts.y)

  // smaller-or-equal instead of smaller-than to make epsilon=0 work.
  return da + db + dx + dy <= epsilon
}

exports.equal =
exports.equals = function (tr, ts) {
  // Are transforms equal?
  //
  // Parameters:
  //   tr
  //     a transform
  //   ts
  //     a transform
  //
  return (tr.a === ts.a && tr.b === ts.b &&
    tr.x === ts.x && tr.y === ts.y)
}

exports.getMatrix = function (tr) {
  // Get the similarity transformation matrix
  // in the format common to other APIs, including:
  // - kld-affine
  // - MDN documentation in some parts
  //
  // Return
  //   object o, having properties a, b, c, d, e, f:
  //   [ a  -b   x ]   [ o.a  o.c  o.e ]
  //   [ b   a   y ] = [ o.b  o.d  o.f ]
  //   [ 0   0   1 ]   [  -    -    -  ]
  return {
    a: tr.a,
    b: tr.b,
    c: -tr.b,
    d: tr.a,
    e: tr.x,
    f: tr.y
  }
}

exports.getRotation = function (tr) {
  // in rads
  return Math.atan2(tr.b, tr.a)
}

exports.getScale = function (tr) {
  // scale multiplier
  return Math.sqrt(tr.b * tr.b + tr.a * tr.a)
}

exports.getTranslation = function (tr) {
  // Current translation as a point.
  return {
    x: tr.x,
    y: tr.y
  }
}

exports.toArray = function (tr) {
  // Return an array representation of the transformation.
  //
  // Compatible with nudged.createFromArray(...)
  return [tr.a, tr.b, tr.x, tr.y]
}

exports.toString = function (tr) {
  // Return a string of CSS transform-function data type.
  //
  // Together with nudged.createFromString(...), this method allows
  // serialization to and from strings.
  //
  // NOTE When JavaScript converts numbers to strings, the string might
  // end up using the scientific notation (e.g. 1e-12). Not all browsers
  // support scientific notation in CSS. We have experienced problems
  // with Safari and Opera. Therefore toString must prevent the scientific
  // notation here and convert to fixed number of decimal places.
  //
  // See also: https://stackoverflow.com/q/1685680/638546
  //
  const a = tr.a.toFixed(8)
  const b = tr.b.toFixed(8)
  const c = (-tr.b).toFixed(8) // Unnecessary? Maybe '-' + b? No, e.g. '--1.2'
  const x = tr.x.toFixed(8)
  const y = tr.y.toFixed(8)
  return 'matrix(' + a + ',' + b + ',' + c + ',' + a + ',' + x + ',' + y + ')'
}

exports.point = function (tr, p) {
  // Transform a point
  //
  // Parameters
  //   tr
  //     a transfrom
  //   p
  //     a xy point
  //
  // Return
  //   the tronsformed xy point
  //
  return {
    x: tr.a * p.x - tr.b * p.y + tr.x,
    y: tr.b * p.x + tr.a * p.y + tr.y
  }
}

exports.points = function (tr, ps) {
  // Transform an array of points
  //
  // Parameters
  //   tr
  //     a transform
  //   ps
  //     an array of points
  const c = []
  for (let i = 0; i < ps.length; i += 1) {
    c.push(exports.point(tr, ps[i]))
  }
}

exports.inverse = function (tr) {
  // Return inversed transform
  // See note 2015-10-26-16-30
  const det = tr.a * tr.a + tr.b * tr.b
  // Test if singular transformation. These might occur when all the range
  // points are the same, forcing the scale to drop to zero.
  if (Math.abs(det) < Transform.EPSILON) {
    throw new Error('Singular transformations cannot be inversed.')
  }
  const ahat = tr.a / det
  const bhat = -tr.b / det
  const xhat = (-tr.a * tr.x - tr.b * tr.y) / det
  const yhat = (tr.b * tr.x - tr.a * tr.y) / det

  return {
    a: ahat,
    b: bhat,
    x: xhat,
    y: yhat
  }
}

// exports.addVector = ?
// exports.translateBy =
exports.translate = function (tr, vec) {
  // Modify transformation so that its image
  // is translated by the given vector.
  // In other words it transforms points
  // further by the given vector.
  //
  // Parameters
  //   tr
  //     a transform
  //   vec
  //     a 2d vector { dx, dy }
  //
  // Return
  //   a transform
  //
  return {
    a: tr.a,
    b: tr.b,
    x: tr.x + vec.dx,
    y: tr.y + vec.dy
  }
}

// exports.translateTo = function (tr, p) {
//   // Modify transformation so that it translates (0, 0)
//   // to the given point.
//   //
//   // Parameters
//   //   tr
//   //     a transform
//   //   p
//   //     a 2d point { x, y }
//   //
//   //
//
// }

exports.scale = function (tr, center, multiplier) {
  // Scale image of the transform so that the given
  // center point stays fixed.
  //
  // Parameter
  //   tr
  //     a transform
  //   center
  //     a point
  //   multiplier
  //     a number
  //
  // Return
  //   a transform
  //
  const m = multiplier // alias
  const cx = center.x
  const cy = center.y
  return {
    a: m * tr.a,
    b: m * tr.b,
    x: m * tr.x + (1 - m) * cx,
    y: m * tr.y + (1 - m) * cy
  }
}

exports.rotate = function (tr, center, radians) {
  // Rotate image of the transform so that the given
  // center point stays fixed.
  //
  // Parameter
  //   tr
  //     a transform
  //   center
  //     a point
  //   radians
  //     a number, angle
  //
  // Return
  //   a transform
  //
  const co = Math.cos(radians)
  const si = Math.sin(radians)

  const cx = pivot[0]
  const cy = pivot[1]

  const ahat = tr.a * co - tr.b * si
  const bhat = tr.a * si + tr.b * co
  const xhat = (tr.x - cx) * co - (tr.y - cy) * si + cx
  const yhat = (tr.x - cx) * si + (tr.y - cy) * co + cy

  return {
    a: ahat,
    b: bhat,
    x: xhat,
    y: yhat
  }
}

exports.compose =
exports.multiply = function (tr, ts) {
  // Multiply transformation matrix tr from
  // the right with the given transformation matrix ts.
  // In other words, transform the image of ts by tr.
  //
  // For reading aid:
  //   a -b  x    a -b  x
  //   b  a  y *  b  a  y
  //   0  0  1    0  0  1
  //
  return {
    a: tr.a * ts.a - tr.b * ts.b,
    b: tr.a * ts.b + tr.b * ts.a,
    x: tr.a * ts.x - tr.b * ts.y + tr.x,
    y: tr.b * ts.x + tr.a * ts.y + tr.y
  }
}

exports.IDENTITY = {
  a: 1,
  b: 0,
  x: 0,
  y: 0
}

exports.ROT90 = { a: 0, b: 1, x: 0, y: 0 }
exports.ROT180 = { a: -1, b: 0, x: 0, y: 0 }
exports.ROT270 = { a: 0, b: -1, x: 0, y: 0 }
exports.X2 = { a: 2, b: 0, x: 0, y: 0 }
<|endoftext|>


<commit_before>'use strict';

function PlaneAPI(w, h) {
    this.__init__(w, h);
}

PlaneAPI.prototype = {
    width    : null,
    height   : null,

    mesh     : null,
    geometry : null,
    material : null,

    scene: null,

    __init__: function(w, h) {
        this.width    = w;
        this.height   = h;

        // PlaneGeometry takes in a width, height, optionalWidthSegments (default 1), optionalHeightSegments (default 1)
        this.geometry = new THREE.PlaneGeometry(this.width, this.height);

        //this.object3d.add(this.geometry.mesh)

        this.create();
    },

    create: function() {
        this.material = new THREE.MeshBasicMaterial({
            color: 0x060606,
            //transparent: true,
            //opacity: 0.85,
            side: THREE.FrontSide
        });
        this.mesh = new THREE.Mesh(this.geometry, this.material);

        var geo = new THREE.EdgesGeometry(this.mesh.geometry); // or WireframeGeometry
        var mat = new THREE.LineBasicMaterial({color: 0xFFC0CB, linewidth: 3});
        var wireframe = new THREE.LineSegments(geo, mat);
        this.mesh.add(wireframe);
    },

    update_position_and_look_at: function(position_vector, look_at_position) {
        this.object3D.position.x = position_vector.x;
        this.object3D.position.y = position_vector.y;
        this.object3D.position.z = position_vector.z;
        this.object3D.lookAt(look_at_position);
    }
};<commit_msg>general updating 44<commit_after>'use strict';

function PlaneAPI(w, h) {
    this.__init__(w, h);
}

PlaneAPI.prototype = {
    width    : null,
    height   : null,

    mesh     : null,
    geometry : null,
    material : null,

    scene: null,

    __init__: function(w, h) {
        this.width    = w;
        this.height   = h;

        // PlaneGeometry takes in a width, height, optionalWidthSegments (default 1), optionalHeightSegments (default 1)
        this.geometry = new THREE.PlaneGeometry(this.width, this.height);

        //this.object3d.add(this.geometry.mesh)

        this.create();
    },

    create: function() {
        this.material = new THREE.MeshBasicMaterial({
            color: 0x060606,
            //transparent: true,
            //opacity: 0.85,
            side: THREE.FrontSide
        });
        this.mesh = new THREE.Mesh(this.geometry, this.material);

        var geo = new THREE.EdgesGeometry(this.mesh.geometry); // or WireframeGeometry
        var mat = new THREE.LineBasicMaterial({color: 0xFFC0CB, linewidth: 3});
        var wireframe = new THREE.LineSegments(geo, mat);
        //this.mesh.add(wireframe);
    },

    update_position_and_look_at: function(position_vector, look_at_position) {
        this.object3D.position.x = position_vector.x;
        this.object3D.position.y = position_vector.y;
        this.object3D.position.z = position_vector.z;
        this.object3D.lookAt(look_at_position);
    }
};<|endoftext|>


<commit_before>/*!
 * transform
 * Version: 0.0.1
 * Date: 2016/8/1
 * https://github.com/Nuintun/fengine
 *
 * This is licensed under the MIT License (MIT).
 * For details, see: https://github.com/Nuintun/fengine/blob/master/LICENSE
 */

'use strict';

var fs = require('fs');
var path = require('path');
var util = require('./util');
var Events = require('./events');

var DIRECTIVE = {
  SLOT: 'slot',
  LAYOUT: 'layout',
  INCLUDE: 'include',
  NONLAYOUT: '!layout'
};
var EVENTS = {
  END: 'end',
  DATA: 'data',
  SLOT: '__SLOT__'
};
var CWD = process.cwd();

/**
 *
 * @type {{
 *   delimiter: assert.delimiter,
 *   data: assert.data
 *   layout: assert.layout
 * }}
 */
var assert = {
  /**
   * delimiter
   * @param options
   * @param defaults
   */
  delimiter: function (options, defaults){
    Object.keys(options.delimiter).forEach(function (key){
      var def = defaults.delimiter[key];
      var delimiter = options.delimiter[key];

      if (!util.array(delimiter)) {
        options.delimiter[key] = def.map(function (delimiter){
          return util.str4regex(delimiter);
        });
      } else {
        if (!util.string(delimiter[0])) {
          delimiter[0] = util.str4regex(def[0]);
        }

        if (!util.string(delimiter[1])) {
          delimiter[1] = util.str4regex(def[1]);
        }
      }
    });
  },
  /**
   * data
   * @param options
   * @param defaults
   * @param context
   */
  data: function (options, defaults, context){
    Object.keys(options.data).forEach(function (key){
      var def = defaults.data[key];
      var data = options.data[key];

      if (util.fn(data)) {
        data = data.call(context, context.src);
      }

      if (!util.string(data)) {
        options.data[key] = def;
      } else {
        options.data[key] = data;
      }
    });
  },
  /**
   * layout
   * @param options
   * @param defaults
   * @param context
   */
  layout: function (options, defaults, context){
    context.layout = util.fn(options.layout)
      ? options.layout.call(context, context.src)
      : options.layout;

    context.layout = util.string(context.layout)
      ? path.join(context.root, context.layout)
      : defaults.layout;
  }
};

/**
 * Transform
 * @param src
 * @param source
 * @param options
 * @constructor
 */
function Transform(src, source, options){
  // buffer
  if (source instanceof Buffer) {
    source = source.toString();
  }

  // src must be a string
  if (!util.string(src)) {
    throw new TypeError('options.src must be a file path.');
  }

  // source must be a string
  if (!util.string(source)) {
    throw new TypeError('source must be a string.');
  }

  var context = this;
  var defaults = {
    root: CWD,
    layout: null,
    delimiter: {
      data: ['{{', '}}'],
      directive: ['<!--', '-->']
    },
    data: {
      dirname: function (){
        var dirname = util.normalize(path.relative(this.root, this.dirname));

        return dirname ? dirname + '/' : dirname;
      },
      filename: function (){
        return this.filename;
      }
    }
  };

  context.index = 0;
  context.slot = null;
  context.entry = null;
  context.layout = null;
  context.source = source;
  context.isLayout = false;
  context.defaults = defaults;
  context.options = options = util.extend(true, {}, defaults, options);

  context.src = path.resolve(CWD, src);
  context.dirname = path.dirname(context.src);
  context.extname = path.extname(context.src);
  context.filename = path.basename(context.src, context.extname);
  context.root = path.resolve(CWD, util.string(options.root) ? options.root : CWD);

  context.transform();
}

/**
 * extend
 * @type {Events}
 */
Transform.prototype = Object.create(Events.prototype, {
  constructor: { value: Transform }
});

/**
 * splitter
 */
Transform.prototype.splitter = function (){
  var context = this;
  var options = context.options;
  var defaults = context.defaults;

  if (!context.entry) {
    assert.delimiter(options, defaults);
    assert.data(options, defaults, context);
  }

  var dataDelimiter = options.delimiter.data;
  var directiveDelimiter = options.delimiter.directive;
  var dataDirective = Object.keys(options.data).map(function (data){
    return util.str4regex(data);
  }).join('|');

  context.regexp = {
    transform: new RegExp(
      directiveDelimiter[0]
      + '\\s*('
      + util.str4regex(DIRECTIVE.INCLUDE)
      + '\\s*\\(\\s*(.+?)\\s*\\)|'
      + util.str4regex(DIRECTIVE.SLOT)
      + ')\\s*'
      + directiveDelimiter[1]
      + '|'
      + dataDelimiter[0]
      + '\\s*('
      + dataDirective
      + ')\\s*'
      + dataDelimiter[1],
      'img'
    ),
    layout: new RegExp(
      directiveDelimiter[0]
      + '\\s*'
      + util.str4regex(DIRECTIVE.LAYOUT)
      + '\\s*\\(\\s*(.+?)\\s*\\)\\s*'
      + directiveDelimiter[1]
    ),
    nonlayout: new RegExp(
      directiveDelimiter[0]
      + '\\s*'
      + util.str4regex(DIRECTIVE.NONLAYOUT)
      + '\\s*'
      + directiveDelimiter[1]
    )
  };
};

/**
 * set layout
 * @param src
 */
Transform.prototype.setLayout = function (src){
  var context = this;

  fs.readFile(src, function (error, source){
    if (error) {
      return context.next();
    }

    var slot = '';
    var layout = context.thread(src, source);

    layout.isLayout = true;

    context.on(EVENTS.DATA, function (data, type){
      if (type !== 'layout') {
        slot += data;
      }
    });

    context.on(EVENTS.SLOT, function (){
      layout.slot = slot;

      layout.next();
    });

    layout.on(EVENTS.DATA, function (data){
      context.write(data, 'layout');
    });

    layout.once(EVENTS.END, function (){
      context.end();
    });
  });
};

/**
 * skip layout
 */
Transform.prototype.skipLayout = function (){
  var context = this;

  context.layout = null;

  context.next();
};

/**
 * transform
 */
Transform.prototype.transform = function (){
  var context = this;

  process.nextTick(function (){
    context.splitter();

    if (!context.entry) {
      assert.layout(context.options, context.defaults, context);
    }

    var src;
    var layout = context.regexp.layout.exec(context.source);
    var nonlayout = context.regexp.nonlayout.exec(context.source);

    if (nonlayout && (layout ? nonlayout.index < layout.index : true)) {
      context.skipLayout();
    } else {
      src = layout ? context.resolve(layout[1]) : context.layout;

      if (src && src !== context.src) {
        context.setLayout(src);
      } else {
        context.skipLayout();
      }
    }
  });
};

/**
 * exec
 * @returns {boolean}
 */
Transform.prototype.exec = function (){
  var context = this;
  var match = context.regexp.transform.exec(context.source);

  if (!match) return false;

  var index = match.index;
  var type = match[1] ? 'directive' : 'data';
  var command = type === 'directive' ? match[1] : match[3];
  var data = type === 'directive' ? match[2] : match[3];

  match = match[0];

  context.write(context.source.substring(context.index, index));

  context.index = index + match.length;

  if (type === 'directive') {
    command = command.toLowerCase();

    switch (command) {
      case DIRECTIVE.SLOT:
        if (context.isLayout && context.entry) {
          if (context.slot) {
            context.write(context.slot);
          } else {
            context.entry.next();
          }
        } else {
          context.write(match);
          context.next();
        }
        break;
      default:
        if (command.indexOf(DIRECTIVE.INCLUDE) === 0) {
          var src = context.resolve(data);

          if (src === context.src) {
            context.write(match);
            context.next();

            return true;
          }

          var entry = context.entry;

          while (entry) {
            if (src === entry.src) {
              context.write(match);
              context.next();

              return true;
            }

            entry = entry.entry;
          }

          fs.readFile(src, function (error, source){
            if (error) {
              context.write(match);

              return context.next();
            }

            var child = context.thread(src, source);

            child.on(EVENTS.DATA, function (data){
              context.write(data, 'include');
            });

            child.once(EVENTS.END, function (){
              context.next();
            });
          });
        } else {
          context.write(match);
          context.next();
        }
        break;
    }
  } else {
    data = context.options.data.hasOwnProperty(data)
      ? context.options.data[data]
      : match;

    context.write(data);
    context.next();
  }

  return true;
};

/**
 * resolve
 * @param url
 * @returns {*}
 */
Transform.prototype.resolve = function (url){
  var context = this;

  if (/^[\\/]/.test(url)) {
    return path.join(context.root, url);
  } else {
    return path.join(context.dirname, url);
  }
};

/**
 * write
 * @param data
 * @param type
 * @returns {*}
 */
Transform.prototype.write = function (data, type){
  type = type || 'context';

  this.emit(EVENTS.DATA, data, type);

  return data;
};

/**
 * end
 * @param data
 * @param type
 * @returns {*}
 */
Transform.prototype.end = function (data, type){
  var context = this;

  data && context.write(data, type);

  context.emit(EVENTS.END);

  context.entry = null;

  return data;
};

/**
 * next
 */
Transform.prototype.next = function (){
  var context = this;

  if (!context.exec()) {
    context.write(context.source.substring(context.index));

    if (context.isLayout || !context.layout) {
      context.end();
    } else {
      context.emit(EVENTS.SLOT);
    }
  }
};

/**
 * thread
 * @param src
 * @param source
 * @returns {Transform}
 */
Transform.prototype.thread = function (src, source){
  var context = this;
  var options = util.extend(true, {}, context.options);

  options.layout = null;

  var thread = new Transform(src, source.toString(), options);

  thread.entry = context;

  return thread;
};

// exports
module.exports = Transform;
<commit_msg>fixed dirname<commit_after>/*!
 * transform
 * Version: 0.0.1
 * Date: 2016/8/1
 * https://github.com/Nuintun/fengine
 *
 * This is licensed under the MIT License (MIT).
 * For details, see: https://github.com/Nuintun/fengine/blob/master/LICENSE
 */

'use strict';

var fs = require('fs');
var path = require('path');
var util = require('./util');
var Events = require('./events');

var DIRECTIVE = {
  SLOT: 'slot',
  LAYOUT: 'layout',
  INCLUDE: 'include',
  NONLAYOUT: '!layout'
};
var EVENTS = {
  END: 'end',
  DATA: 'data',
  SLOT: '__SLOT__'
};
var CWD = process.cwd();

/**
 *
 * @type {{
 *   delimiter: assert.delimiter,
 *   data: assert.data
 *   layout: assert.layout
 * }}
 */
var assert = {
  /**
   * delimiter
   * @param options
   * @param defaults
   */
  delimiter: function (options, defaults){
    Object.keys(options.delimiter).forEach(function (key){
      var def = defaults.delimiter[key];
      var delimiter = options.delimiter[key];

      if (!util.array(delimiter)) {
        options.delimiter[key] = def.map(function (delimiter){
          return util.str4regex(delimiter);
        });
      } else {
        if (!util.string(delimiter[0])) {
          delimiter[0] = util.str4regex(def[0]);
        }

        if (!util.string(delimiter[1])) {
          delimiter[1] = util.str4regex(def[1]);
        }
      }
    });
  },
  /**
   * data
   * @param options
   * @param defaults
   * @param context
   */
  data: function (options, defaults, context){
    Object.keys(options.data).forEach(function (key){
      var def = defaults.data[key];
      var data = options.data[key];

      if (util.fn(data)) {
        data = data.call(context, context.src);
      }

      if (!util.string(data)) {
        options.data[key] = def;
      } else {
        options.data[key] = data;
      }
    });
  },
  /**
   * layout
   * @param options
   * @param defaults
   * @param context
   */
  layout: function (options, defaults, context){
    context.layout = util.fn(options.layout)
      ? options.layout.call(context, context.src)
      : options.layout;

    context.layout = util.string(context.layout)
      ? path.join(context.root, context.layout)
      : defaults.layout;
  }
};

/**
 * Transform
 * @param src
 * @param source
 * @param options
 * @constructor
 */
function Transform(src, source, options){
  // buffer
  if (source instanceof Buffer) {
    source = source.toString();
  }

  // src must be a string
  if (!util.string(src)) {
    throw new TypeError('options.src must be a file path.');
  }

  // source must be a string
  if (!util.string(source)) {
    throw new TypeError('source must be a string.');
  }

  var context = this;
  var defaults = {
    root: CWD,
    layout: null,
    delimiter: {
      data: ['{{', '}}'],
      directive: ['<!--', '-->']
    },
    data: {
      dirname: function (){
        var dirname = util.normalize(path.relative(this.root, this.dirname));

        return dirname ? dirname + '/' : dirname;
      },
      filename: function (){
        return this.filename;
      }
    }
  };

  context.index = 0;
  context.slot = null;
  context.entry = null;
  context.layout = null;
  context.source = source;
  context.isLayout = false;
  context.defaults = defaults;
  context.options = options = util.extend(true, {}, defaults, options);

  context.src = path.resolve(CWD, src);
  context.dirname = path.dirname(context.src);
  context.extname = path.extname(context.src);
  context.filename = path.basename(context.src, context.extname);
  context.root = path.resolve(CWD, util.string(options.root) ? options.root : CWD);

  context.transform();
}

/**
 * extend
 * @type {Events}
 */
Transform.prototype = Object.create(Events.prototype, {
  constructor: { value: Transform }
});

/**
 * splitter
 */
Transform.prototype.splitter = function (){
  var context = this;
  var options = context.options;
  var defaults = context.defaults;

  if (!context.entry) {
    assert.delimiter(options, defaults);
    assert.data(options, defaults, context);
  }

  var dataDelimiter = options.delimiter.data;
  var directiveDelimiter = options.delimiter.directive;
  var dataDirective = Object.keys(options.data).map(function (data){
    return util.str4regex(data);
  }).join('|');

  context.regexp = {
    transform: new RegExp(
      directiveDelimiter[0]
      + '\\s*('
      + util.str4regex(DIRECTIVE.INCLUDE)
      + '\\s*\\(\\s*(.+?)\\s*\\)|'
      + util.str4regex(DIRECTIVE.SLOT)
      + ')\\s*'
      + directiveDelimiter[1]
      + '|'
      + dataDelimiter[0]
      + '\\s*('
      + dataDirective
      + ')\\s*'
      + dataDelimiter[1],
      'img'
    ),
    layout: new RegExp(
      directiveDelimiter[0]
      + '\\s*'
      + util.str4regex(DIRECTIVE.LAYOUT)
      + '\\s*\\(\\s*(.+?)\\s*\\)\\s*'
      + directiveDelimiter[1]
    ),
    nonlayout: new RegExp(
      directiveDelimiter[0]
      + '\\s*'
      + util.str4regex(DIRECTIVE.NONLAYOUT)
      + '\\s*'
      + directiveDelimiter[1]
    )
  };
};

/**
 * set layout
 * @param src
 */
Transform.prototype.setLayout = function (src){
  var context = this;

  fs.readFile(src, function (error, source){
    if (error) {
      return context.setLayout();
    }

    var slot = '';
    var layout = context.thread(src, source);

    layout.isLayout = true;

    context.on(EVENTS.DATA, function (data, type){
      if (type !== 'layout') {
        slot += data;
      }
    });

    context.on(EVENTS.SLOT, function (){
      layout.slot = slot;

      layout.next();
    });

    layout.on(EVENTS.DATA, function (data){
      context.write(data, 'layout');
    });

    layout.once(EVENTS.END, function (){
      context.end();
    });
  });
};

/**
 * skip layout
 */
Transform.prototype.skipLayout = function (){
  var context = this;

  context.layout = null;

  context.next();
};

/**
 * transform
 */
Transform.prototype.transform = function (){
  var context = this;

  process.nextTick(function (){
    context.splitter();

    if (!context.entry) {
      assert.layout(context.options, context.defaults, context);
    }

    var src;
    var layout = context.regexp.layout.exec(context.source);
    var nonlayout = context.regexp.nonlayout.exec(context.source);

    if (nonlayout && (layout ? nonlayout.index < layout.index : true)) {
      context.skipLayout();
    } else {
      src = layout ? context.resolve(layout[1]) : context.layout;

      if (src && src !== context.src) {
        context.setLayout(src);
      } else {
        context.skipLayout();
      }
    }
  });
};

/**
 * exec
 * @returns {boolean}
 */
Transform.prototype.exec = function (){
  var context = this;
  var match = context.regexp.transform.exec(context.source);

  if (!match) return false;

  var index = match.index;
  var type = match[1] ? 'directive' : 'data';
  var command = type === 'directive' ? match[1] : match[3];
  var data = type === 'directive' ? match[2] : match[3];

  match = match[0];

  context.write(context.source.substring(context.index, index));

  context.index = index + match.length;

  if (type === 'directive') {
    command = command.toLowerCase();

    switch (command) {
      case DIRECTIVE.SLOT:
        if (context.isLayout && context.entry) {
          if (context.slot) {
            context.write(context.slot);
          } else {
            context.entry.next();
          }
        } else {
          context.write(match);
          context.next();
        }
        break;
      default:
        if (command.indexOf(DIRECTIVE.INCLUDE) === 0) {
          var src = context.resolve(data);

          if (src === context.src) {
            context.write(match);
            context.next();

            return true;
          }

          var entry = context.entry;

          while (entry) {
            if (src === entry.src) {
              context.write(match);
              context.next();

              return true;
            }

            entry = entry.entry;
          }

          fs.readFile(src, function (error, source){
            if (error) {
              context.write(match);

              return context.next();
            }

            var child = context.thread(src, source);

            child.on(EVENTS.DATA, function (data){
              context.write(data, 'include');
            });

            child.once(EVENTS.END, function (){
              context.next();
            });
          });
        } else {
          context.write(match);
          context.next();
        }
        break;
    }
  } else {
    data = context.options.data.hasOwnProperty(data)
      ? context.options.data[data]
      : match;

    context.write(data);
    context.next();
  }

  return true;
};

/**
 * resolve
 * @param url
 * @returns {*}
 */
Transform.prototype.resolve = function (url){
  var context = this;

  if (/^[\\/]/.test(url)) {
    return path.join(context.root, url);
  } else {
    return path.join(context.dirname, url);
  }
};

/**
 * write
 * @param data
 * @param type
 * @returns {*}
 */
Transform.prototype.write = function (data, type){
  type = type || 'context';

  this.emit(EVENTS.DATA, data, type);

  return data;
};

/**
 * end
 * @param data
 * @param type
 * @returns {*}
 */
Transform.prototype.end = function (data, type){
  var context = this;

  data && context.write(data, type);

  context.emit(EVENTS.END);

  context.entry = null;

  return data;
};

/**
 * next
 */
Transform.prototype.next = function (){
  var context = this;

  if (!context.exec()) {
    context.write(context.source.substring(context.index));

    if (context.isLayout || !context.layout) {
      context.end();
    } else {
      context.emit(EVENTS.SLOT);
    }
  }
};

/**
 * thread
 * @param src
 * @param source
 * @returns {Transform}
 */
Transform.prototype.thread = function (src, source){
  var context = this;
  var options = util.extend(true, {}, context.options);

  options.layout = null;

  var thread = new Transform(src, source.toString(), options);

  thread.entry = context;

  return thread;
};

// exports
module.exports = Transform;
<|endoftext|>


<commit_before>var babelify = require('babelify')
var envify = require('envify/custom')
var fs = require('fs')
var markdown = require('browserify-markdown')
var mimeType = require('mime')
var path = require('path')
var postcss = require('postcss')
var through = require('through2')
var YAML = require('yamljs')

module.exports = function transform ({
  config,
  debug,
  env,
  outfile
}) {
  var babelifyConfig = {
    presets: [
      require('babel-preset-es2015'),
      require('babel-preset-react'),
      require('babel-preset-stage-0')
    ],
    plugins: [
      require('babel-plugin-add-module-exports'),
      require('babel-plugin-transform-runtime')
    ]
  }

  var defaultEnvify = Object.assign(process.env, {
    _: 'purge',
    CONFIG_PATH: config.path,
    MESSAGES: JSON.stringify(config.messages), // TODO: Make all envify replacements strings
    NODE_ENV: env,
    SETTINGS: JSON.stringify(config.settings),
    STORE: JSON.stringify(config.store)
  }, config.env)

  var cssTransforms = [
    require('postcss-import')({
      plugins: [
        base64ify(process.cwd()) // inline all url files
      ]
    }),
    require('postcss-cssnext')(), // TODO: Creating CSS.yml variable settings to use in postcss-cssnext
    require('postcss-safe-parser'),
    require('postcss-reporter')()
  ]

  return [
    cssTransform({
      configPath: config.path,
      debug,
      injectCSS: config.injectCSS,
      outfile,
      processor: postcss(cssTransforms)
    }),
    htmlTransform,
    markdown(),
    yamlTransform,
    babelify.configure(babelifyConfig),
    envify(defaultEnvify) // Envify needs to happen last...
  ]
}

function cssTransform ({
  configPath,
  debug,
  injectCss,
  outfile,
  processor
}) {
  return function (filename) {
    if (!/\.css$/i.test(filename)) {
      return through()
    }

    return through(function (buf, enc, next) {
      var self = this
      var css = buf.toString('utf8')

      processor
        .process(css.replace(/CONFIG_PATH/g, configPath), {
          map: debug,
          to: path.basename(outfile)
        })
        .then(function (results) {
          const csspath = outfile.replace('.js', '.css')
          fs.writeFile(csspath, results.css, function (err) {
            if (err) {
              console.error(err)
            }
          })
          if (results.map) {
            fs.writeFile(`${csspath}.map`, results.map, function (err) {
              if (err) {
                console.error(err)
              }
            })
          }
          self.push('// css was here')
          next()
        })
        .catch(function (err) {
          console.error(err.stack)
          process.exit(1)
        })
    })
  }
}

function htmlTransform (filename) {
  if (!/\.html$/i.test(filename)) {
    return through()
  }

  return through(function (buf, enc, next) {
    var html = buf.toString('utf8')
    this.push('module.exports=' + JSON.stringify(html))
    next()
  })
}

function yamlTransform (filename) {
  if (!/\.yml|\.yaml$/i.test(filename)) {
    return through()
  }

  return through(function (buf, enc, next) {
    this.push('module.exports=' + JSON.stringify(YAML.parse(buf.toString('utf8'))) + ';')
    next()
  })
}

function getUrl (value) {
  var reg = /url\((\s*)(['"]?)(.+?)\2(\s*)\)/g
  var match = reg.exec(value)
  var url = match[3]
  return url
}

var base64ify = postcss.plugin('postcss-base64ify', function () {
  return function (css, result) {
    var source = css.source.input.file
    var dir = path.dirname(source)
    css.replaceValues(/url\((\s*)(['"]?)(.+?)\2(\s*)\)/g, function (string) {
      var filename = getUrl(string)
        .split('?')[0]
        .split('#')[0]
      var file
      if (filename.indexOf('data') === 0 || filename.length === 0) {
        return string
      } else if (filename[0] === '/') {
        file = path.join(process.cwd(), filename)
      } else {
        file = path.resolve(dir, filename)
      }
      if (!fs.existsSync(file)) {
        throw new Error('File', file, 'does not exist')
      }
      var buffer = fs.readFileSync(file)
      return 'url("data:' + mimeType.lookup(filename) + ';base64,' + buffer.toString('base64') + '")'
    })
  }
})
<commit_msg>Map the css.map to the correct file<commit_after>var babelify = require('babelify')
var envify = require('envify/custom')
var fs = require('fs')
var markdown = require('browserify-markdown')
var mimeType = require('mime')
var path = require('path')
var postcss = require('postcss')
var through = require('through2')
var YAML = require('yamljs')

module.exports = function transform ({
  config,
  debug,
  env,
  outfile
}) {
  var babelifyConfig = {
    presets: [
      require('babel-preset-es2015'),
      require('babel-preset-react'),
      require('babel-preset-stage-0')
    ],
    plugins: [
      require('babel-plugin-add-module-exports'),
      require('babel-plugin-transform-runtime')
    ]
  }

  var defaultEnvify = Object.assign(process.env, {
    _: 'purge',
    CONFIG_PATH: config.path,
    MESSAGES: JSON.stringify(config.messages), // TODO: Make all envify replacements strings
    NODE_ENV: env,
    SETTINGS: JSON.stringify(config.settings),
    STORE: JSON.stringify(config.store)
  }, config.env)

  var cssTransforms = [
    require('postcss-import')({
      plugins: [
        base64ify(process.cwd()) // inline all url files
      ]
    }),
    require('postcss-cssnext')(), // TODO: Creating CSS.yml variable settings to use in postcss-cssnext
    require('postcss-safe-parser'),
    require('postcss-reporter')()
  ]

  return [
    cssTransform({
      configPath: config.path,
      debug,
      injectCSS: config.injectCSS,
      outfile,
      processor: postcss(cssTransforms)
    }),
    htmlTransform,
    markdown(),
    yamlTransform,
    babelify.configure(babelifyConfig),
    envify(defaultEnvify) // Envify needs to happen last...
  ]
}

function cssTransform ({
  configPath,
  debug,
  injectCss,
  outfile,
  processor
}) {
  return function (filename) {
    if (!/\.css$/i.test(filename)) {
      return through()
    }

    return through(function (buf, enc, next) {
      const self = this
      const css = buf.toString('utf8')
      processor
        .process(css.replace(/CONFIG_PATH/g, configPath), {
          map: debug,
          to: `${path.basename(outfile, '.js')}.css`
        })
        .then(function (results) {
          const csspath = outfile.replace('.js', '.css')
          fs.writeFile(csspath, results.css, function (err) {
            if (err) {
              console.error(err)
            }
          })
          if (results.map) {
            fs.writeFile(`${csspath}.map`, results.map, function (err) {
              if (err) {
                console.error(err)
              }
            })
          }
          self.push('// css was here')
          next()
        })
        .catch(function (err) {
          console.error(err.stack)
          process.exit(1)
        })
    })
  }
}

function htmlTransform (filename) {
  if (!/\.html$/i.test(filename)) {
    return through()
  }

  return through(function (buf, enc, next) {
    var html = buf.toString('utf8')
    this.push('module.exports=' + JSON.stringify(html))
    next()
  })
}

function yamlTransform (filename) {
  if (!/\.yml|\.yaml$/i.test(filename)) {
    return through()
  }

  return through(function (buf, enc, next) {
    this.push('module.exports=' + JSON.stringify(YAML.parse(buf.toString('utf8'))) + ';')
    next()
  })
}

function getUrl (value) {
  var reg = /url\((\s*)(['"]?)(.+?)\2(\s*)\)/g
  var match = reg.exec(value)
  var url = match[3]
  return url
}

var base64ify = postcss.plugin('postcss-base64ify', function () {
  return function (css, result) {
    var source = css.source.input.file
    var dir = path.dirname(source)
    css.replaceValues(/url\((\s*)(['"]?)(.+?)\2(\s*)\)/g, function (string) {
      var filename = getUrl(string)
        .split('?')[0]
        .split('#')[0]
      var file
      if (filename.indexOf('data') === 0 || filename.length === 0) {
        return string
      } else if (filename[0] === '/') {
        file = path.join(process.cwd(), filename)
      } else {
        file = path.resolve(dir, filename)
      }
      if (!fs.existsSync(file)) {
        throw new Error('File', file, 'does not exist')
      }
      var buffer = fs.readFileSync(file)
      return 'url("data:' + mimeType.lookup(filename) + ';base64,' + buffer.toString('base64') + '")'
    })
  }
})
<|endoftext|>


<commit_before>import styles from './handlehighlight.css'

let currentValue

export default function handlehighlight(state) {
  let previousValue = currentValue
  let highlightTextsAdd = {}
  let highlightTextsDelete = {}

  if (state.highlight.toolbarOn === 1) {
    currentValue = state.highlight.highlightMap
    if (previousValue !== currentValue) {
      if (previousValue === undefined) {
        highlightTextsAdd = currentValue
      } else {
        localStorage.setItem('highlightMap', JSON.stringify(currentValue))
        let keysPre = Object.keys(previousValue)
        let keysCur = Object.keys(currentValue)

        keysPre.filter((item) => {
          if (!(keysCur.indexOf(item) > -1)) {
            highlightTextsDelete[item] = previousValue[item]
          }
        })
        keysCur.filter((item) => {
          if (!(keysPre.indexOf(item) > -1)) {
            highlightTextsAdd[item] = currentValue[item]
          }
        })
      }
      // 渲染新增加的highlightText

      if (Object.keys(highlightTextsAdd).length !== 0) {
        const highlightTextsArray = Object.values(highlightTextsAdd)
        highlightTextsArray.forEach(function(highlight) {
          let id = highlight.id

          highlight.texts.forEach(function(highlightText) {
            // 找到高亮的数据所在的highlightText的父节点
            let selectorArray = highlight.cacSelector.concat(highlightText.subSelector)

            let highlightTextSelector = ''
            for(var i = 0; i < selectorArray.length; i++) {
              highlightTextSelector = highlightTextSelector + selectorArray[i].nodeName
              if(selectorArray[i].id) {
                highlightTextSelector = highlightTextSelector  + "#" +  selectorArray[i].id
              }
              if(selectorArray[i].classes) {
                selectorArray[i].classes.forEach((className) =>      highlightTextSelector = highlightTextSelector  + "." + className)
              }
              highlightTextSelector = highlightTextSelector + '>'
              // highlightTextSelector = highlightTextSelector + ':nth-of-type(' + selectorArray[i].nthOfType + ')>'
            }

            let nodes = document.querySelectorAll(highlightTextSelector.slice(0,highlightTextSelector.length - 1))
            let text = highlightText.text
            let startOffset = highlightText.startOffset
            let endOffset = highlightText.endOffset
            let commonAncestorNode

            for(var i = 0; i < nodes.length; i++ ) {
              if (nodes[i].innerText.indexOf(text) > -1) {
                commonAncestorNode = nodes[i]
              }
            }

            if (commonAncestorNode.nodeType === Node.ELEMENT_NODE) {
              commonAncestorNode.innerHTML = commonAncestorNode.innerHTML.replace(text, '' + text + '')
            }
          })
        })
      }

      // 删除高亮数据
      if (Object.keys(highlightTextsDelete).length !== 0) {
        const highlightTextsArray = Object.values(highlightTextsDelete)
        highlightTextsArray.forEach(function(highlight) {

          highlight.texts.forEach(function(highlightText){
          let deleteNode = document.body.querySelector(".node_" + highlight.id)
          let commonAncestorNode = deleteNode.parentNode

          let text = highlightText.text
          let startOffset = highlightText.startOffset
          if (commonAncestorNode.nodeType === Node.ELEMENT_NODE) {
            // commonAncestorNode.removeChild(deleteNode)
            commonAncestorNode.innerHTML = commonAncestorNode.innerHTML.replace(deleteNode.outerHTML, text)
            // commonAncestorNode.innerHTML = commonAncestorNode.innerHTML.slice(0, startOffset) + content + commonAncestorNode.innerHTML.slice(startOffset)
          }
          })
        })
      }
    }
  }
}
<commit_msg>use fragment to handle highlight<commit_after>import styles from './handlehighlight.css'

let currentValue

export default function handlehighlight(state) {
  let previousValue = currentValue
  let highlightTextsAdd = {}
  let highlightTextsDelete = {}

  if (state.highlight.toolbarOn === 1) {
    currentValue = state.highlight.highlightMap
    if (previousValue !== currentValue) {
      if (previousValue === undefined) {
        highlightTextsAdd = currentValue
      } else {
        localStorage.setItem('highlightMap', JSON.stringify(currentValue))
        let keysPre = Object.keys(previousValue)
        let keysCur = Object.keys(currentValue)

        keysPre.filter((item) => {
          if (!(keysCur.indexOf(item) > -1)) {
            highlightTextsDelete[item] = previousValue[item]
          }
        })
        keysCur.filter((item) => {
          if (!(keysPre.indexOf(item) > -1)) {
            highlightTextsAdd[item] = currentValue[item]
          }
        })
      }
      // 渲染新增加的highlightText

      if (Object.keys(highlightTextsAdd).length !== 0) {
        const highlightTextsArray = Object.values(highlightTextsAdd)
        highlightTextsArray.forEach(function(highlight) {
          let id = highlight.id

          highlight.texts.forEach(function(highlightText) {
            // 找到高亮的数据所在的highlightText的父节点
            let selectorArray = highlight.cacSelector.concat(highlightText.subSelector)

            let highlightTextSelector = ''
            for(var i = 0; i < selectorArray.length; i++) {
              highlightTextSelector = highlightTextSelector + selectorArray[i].nodeName
              if(selectorArray[i].id) {
                highlightTextSelector = highlightTextSelector  + "#" +  selectorArray[i].id
              }
              if(selectorArray[i].classes) {
                selectorArray[i].classes.forEach((className) =>      highlightTextSelector = highlightTextSelector  + "." + className)
              }
              highlightTextSelector = highlightTextSelector + '>'
              // highlightTextSelector = highlightTextSelector + ':nth-of-type(' + selectorArray[i].nthOfType + ')>'
            }

            let nodes = document.querySelectorAll(highlightTextSelector.slice(0,highlightTextSelector.length - 1))
            let text = highlightText.text
            let startOffset = highlightText.startOffset
            let endOffset = highlightText.endOffset
            let hightlightTextNode

            for (var i = 0; i < nodes.length; i++ ) {
              let node = nodes[i]
              for (var j = 0; j < node.childNodes.length; j++) {
                if (node.childNodes[j].nodeType === Node.TEXT_NODE) {
                  if (node.childNodes[j].nodeValue.slice(startOffset,endOffset) === text) {
                    hightlightTextNode = node.childNodes[j]
                  }
                }
              }
            }
            let selectBF = document.createTextNode(hightlightTextNode.nodeValue.slice(0, startOffset))

            let selectAF = document.createTextNode(hightlightTextNode.nodeValue.slice(endOffset))
            let span = document.createElement('span')
            span.innerHTML = text
            span.classList.add(styles.highlightNote)
            span.classList.add('node_' + id)

            let fragment = document.createDocumentFragment()
            fragment.appendChild(selectBF)
            fragment.appendChild(span)
            fragment.appendChild(selectAF)
            hightlightTextNode.parentNode.replaceChild(fragment, hightlightTextNode)
            // if (hightlightNode.nodeType === Node.ELEMENT_NODE) {
              // hightlightNode.innerHTML = hightlightNode.innerHTML.replace(text, '' + text + '')
            // }
          })
        })
      }

      // 删除高亮数据
      if (Object.keys(highlightTextsDelete).length !== 0) {
        const highlightTextsArray = Object.values(highlightTextsDelete)
        highlightTextsArray.forEach(function(highlight) {

          highlight.texts.forEach(function(highlightText){
          let deleteNode = document.body.querySelector(".node_" + highlight.id)
          let commonAncestorNode = deleteNode.parentNode

          let text = highlightText.text
          let startOffset = highlightText.startOffset
          if (commonAncestorNode.nodeType === Node.ELEMENT_NODE) {
            // commonAncestorNode.removeChild(deleteNode)
            commonAncestorNode.innerHTML = commonAncestorNode.innerHTML.replace(deleteNode.outerHTML, text)
            // commonAncestorNode.innerHTML = commonAncestorNode.innerHTML.slice(0, startOffset) + content + commonAncestorNode.innerHTML.slice(startOffset)
          }
          })
        })
      }
    }
  }
}
<|endoftext|>


<commit_before>// Generated by CoffeeScript 1.8.0
(function() {
  var GenericReceiver, MAP, ResponseReceiver, Session, SockJSConnection, Transport, closeFrame, register, stream, utils, uuid,
    __hasProp = {}.hasOwnProperty,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

  stream = require('stream');

  uuid = require('node-uuid');

  utils = require('./utils');

  Transport = (function() {
    function Transport() {}

    return Transport;

  })();

  Transport.CONNECTING = 0;

  Transport.OPEN = 1;

  Transport.CLOSING = 2;

  Transport.CLOSED = 3;

  closeFrame = function(status, reason) {
    return 'c' + JSON.stringify([status, reason]);
  };

  SockJSConnection = (function(_super) {
    __extends(SockJSConnection, _super);

    function SockJSConnection(_session) {
      this._session = _session;
      this.id = uuid.v4();
      this.headers = {};
      this.prefix = this._session.prefix;
    }

    SockJSConnection.prototype.toString = function() {
      return '<SockJSConnection ' + this.id + '>';
    };

    SockJSConnection.prototype.write = function(string) {
      return this._session.send('' + string);
    };

    SockJSConnection.prototype.end = function(string) {
      if (string) {
        this.write(string);
      }
      this.close();
      return null;
    };

    SockJSConnection.prototype.close = function(code, reason) {
      return this._session.close(code, reason);
    };

    SockJSConnection.prototype.destroy = function() {
      this.end();
      return this.removeAllListeners();
    };

    SockJSConnection.prototype.destroySoon = function() {
      return this.destroy();
    };

    return SockJSConnection;

  })(stream.Stream);

  SockJSConnection.prototype.__defineGetter__('readable', function() {
    return this._session.readyState === Transport.OPEN;
  });

  SockJSConnection.prototype.__defineGetter__('writable', function() {
    return this._session.readyState === Transport.OPEN;
  });

  SockJSConnection.prototype.__defineGetter__('readyState', function() {
    return this._session.readyState;
  });

  MAP = {};

  Session = (function() {
    function Session(session_id, server) {
      this.session_id = session_id;
      this.heartbeat_delay = server.options.heartbeat_delay;
      this.disconnect_delay = server.options.disconnect_delay;
      this.prefix = server.options.prefix;
      this.send_buffer = [];
      this.is_closing = false;
      this.readyState = Transport.CONNECTING;
      if (this.session_id) {
        MAP[this.session_id] = this;
      }
      this.timeout_cb = (function(_this) {
        return function() {
          return _this.didTimeout();
        };
      })(this);
      this.to_tref = setTimeout(this.timeout_cb, this.disconnect_delay);
      this.connection = new SockJSConnection(this);
      this.emit_open = (function(_this) {
        return function() {
          _this.emit_open = null;
          return server.emit('connection', _this.connection);
        };
      })(this);
    }

    Session.prototype.register = function(req, recv) {
      if (this.recv) {
        recv.doSendFrame(closeFrame(2010, "Another connection still open"));
        recv.didClose();
        return;
      }
      if (this.to_tref) {
        clearTimeout(this.to_tref);
        this.to_tref = null;
      }
      if (this.readyState === Transport.CLOSING) {
        this.flushToRecv(recv);
        recv.doSendFrame(this.close_frame);
        recv.didClose();
        this.to_tref = setTimeout(this.timeout_cb, this.disconnect_delay);
        return;
      }
      this.recv = recv;
      this.recv.session = this;
      this.decorateConnection(req);
      if (this.readyState === Transport.CONNECTING) {
        this.recv.doSendFrame('o');
        this.readyState = Transport.OPEN;
        process.nextTick(this.emit_open);
      }
      if (!this.recv) {
        return;
      }
      this.tryFlush();
    };

    Session.prototype.decorateConnection = function(req) {
      var address, headers, key, remoteAddress, remotePort, socket, x, _i, _len, _ref;
      if (!(socket = this.recv.connection)) {
        socket = this.recv.response.connection;
      }
      try {
        remoteAddress = socket.remoteAddress;
        remotePort = socket.remotePort;
        address = socket.address();
      } catch (_error) {
        x = _error;
      }
      if (remoteAddress) {
        this.connection.remoteAddress = remoteAddress;
        this.connection.remotePort = remotePort;
        this.connection.address = address;
      }
      this.connection.url = req.url;
      this.connection.pathname = req.pathname;
      this.connection.protocol = this.recv.protocol;
      headers = {};
      _ref = ['referer', 'x-client-ip', 'x-forwarded-for', 'x-cluster-client-ip', 'via', 'x-real-ip', 'host', 'user-agent', 'accept-language'];
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        key = _ref[_i];
        if (req.headers[key]) {
          headers[key] = req.headers[key];
        }
      }
      if (headers) {
        return this.connection.headers = headers;
      }
    };

    Session.prototype.unregister = function() {
      var delay;
      delay = this.recv.delay_disconnect;
      this.recv.session = null;
      this.recv = null;
      if (this.to_tref) {
        clearTimeout(this.to_tref);
      }
      if (delay) {
        return this.to_tref = setTimeout(this.timeout_cb, this.disconnect_delay);
      } else {
        return this.timeout_cb();
      }
    };

    Session.prototype.flushToRecv = function(recv) {
      var sb, _ref;
      if (this.send_buffer.length > 0) {
        _ref = [this.send_buffer, []], sb = _ref[0], this.send_buffer = _ref[1];
        recv.doSendBulk(sb);
        return true;
      }
      return false;
    };

    Session.prototype.tryFlush = function() {
      var x;
      if (!this.flushToRecv(this.recv) || !this.to_tref) {
        if (this.to_tref) {
          clearTimeout(this.to_tref);
        }
        x = (function(_this) {
          return function() {
            if (_this.recv) {
              _this.to_tref = setTimeout(x, _this.heartbeat_delay);
              return _this.recv.doSendFrame("h");
            }
          };
        })(this);
        this.to_tref = setTimeout(x, this.heartbeat_delay);
      }
    };

    Session.prototype.didTimeout = function() {
      if (this.to_tref) {
        clearTimeout(this.to_tref);
        this.to_tref = null;
      }
      if (this.readyState !== Transport.CONNECTING && this.readyState !== Transport.OPEN && this.readyState !== Transport.CLOSING) {
        throw Error('INVALID_STATE_ERR');
      }
      if (this.recv) {
        throw Error('RECV_STILL_THERE');
      }
      this.readyState = Transport.CLOSED;
      this.connection.emit('end');
      this.connection.emit('close');
      this.connection = null;
      if (this.session_id) {
        delete MAP[this.session_id];
        return this.session_id = null;
      }
    };

    Session.prototype.didMessage = function(payload) {
      if (this.readyState === Transport.OPEN) {
        this.connection.emit('data', payload);
      }
    };

    Session.prototype.send = function(payload) {
      if (this.readyState !== Transport.OPEN) {
        return false;
      }
      this.send_buffer.push('' + payload);
      if (this.recv) {
        this.tryFlush();
      }
      return true;
    };

    Session.prototype.close = function(status, reason) {
      if (status == null) {
        status = 1000;
      }
      if (reason == null) {
        reason = "Normal closure";
      }
      if (this.readyState !== Transport.OPEN) {
        return false;
      }
      this.readyState = Transport.CLOSING;
      this.close_frame = closeFrame(status, reason);
      if (this.recv) {
        this.recv.doSendFrame(this.close_frame);
        if (this.recv) {
          this.recv.didClose();
        }
        if (this.recv) {
          this.unregister();
        }
      }
      return true;
    };

    return Session;

  })();

  Session.bySessionId = function(session_id) {
    if (!session_id) {
      return null;
    }
    return MAP[session_id] || null;
  };

  register = function(req, server, session_id, receiver) {
    var session;
    session = Session.bySessionId(session_id);
    if (!session) {
      session = new Session(session_id, server);
    }
    session.register(req, receiver);
    return session;
  };

  exports.register = function(req, server, receiver) {
    return register(req, server, req.session, receiver);
  };

  exports.registerNoSession = function(req, server, receiver) {
    return register(req, server, void 0, receiver);
  };

  GenericReceiver = (function() {
    function GenericReceiver(thingy) {
      this.thingy = thingy;
      this.setUp(this.thingy);
    }

    GenericReceiver.prototype.setUp = function() {
      this.thingy_end_cb = (function(_this) {
        return function() {
          return _this.didAbort();
        };
      })(this);
      this.thingy.addListener('close', this.thingy_end_cb);
      return this.thingy.addListener('end', this.thingy_end_cb);
    };

    GenericReceiver.prototype.tearDown = function() {
      this.thingy.removeListener('close', this.thingy_end_cb);
      this.thingy.removeListener('end', this.thingy_end_cb);
      return this.thingy_end_cb = null;
    };

    GenericReceiver.prototype.didAbort = function() {
      return this.didClose();
    };

    GenericReceiver.prototype.didClose = function() {
      if (this.thingy) {
        this.tearDown(this.thingy);
        this.thingy = null;
      }
      if (this.session) {
        return this.session.unregister();
      }
    };

    GenericReceiver.prototype.doSendBulk = function(messages) {
      var m, q_msgs;
      q_msgs = (function() {
        var _i, _len, _results;
        _results = [];
        for (_i = 0, _len = messages.length; _i < _len; _i++) {
          m = messages[_i];
          _results.push(utils.quote(m));
        }
        return _results;
      })();
      return this.doSendFrame('a' + '[' + q_msgs.join(',') + ']');
    };

    return GenericReceiver;

  })();

  ResponseReceiver = (function(_super) {
    __extends(ResponseReceiver, _super);

    ResponseReceiver.prototype.max_response_size = void 0;

    ResponseReceiver.prototype.delay_disconnect = true;

    function ResponseReceiver(request, response, options) {
      var x;
      this.request = request;
      this.response = response;
      this.options = options;
      this.curr_response_size = 0;
      try {
        this.request.connection.setKeepAlive(true, 5000);
      } catch (_error) {
        x = _error;
      }
      ResponseReceiver.__super__.constructor.call(this, this.request.connection);
      if (this.max_response_size === void 0) {
        this.max_response_size = this.options.response_limit;
      }
    }

    ResponseReceiver.prototype.doSendFrame = function(payload) {
      var r, x;
      this.curr_response_size += payload.length;
      r = false;
      try {
        this.response.write(payload);
        r = true;
      } catch (_error) {
        x = _error;
      }
      if (this.max_response_size && this.curr_response_size >= this.max_response_size) {
        this.didClose();
      }
      return r;
    };

    ResponseReceiver.prototype.didClose = function() {
      var x;
      ResponseReceiver.__super__.didClose.apply(this, arguments);
      try {
        this.response.end();
      } catch (_error) {
        x = _error;
      }
      return this.response = null;
    };

    return ResponseReceiver;

  })(GenericReceiver);

  exports.GenericReceiver = GenericReceiver;

  exports.Transport = Transport;

  exports.Session = Session;

  exports.ResponseReceiver = ResponseReceiver;

  exports.SockJSConnection = SockJSConnection;

}).call(this);
<commit_msg>Interject newlines every 100th record to force flush on client side<commit_after>// Generated by CoffeeScript 1.8.0
(function() {
  var GenericReceiver, MAP, ResponseReceiver, Session, SockJSConnection, Transport, closeFrame, register, stream, utils, uuid,
    __hasProp = {}.hasOwnProperty,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

  stream = require('stream');

  uuid = require('node-uuid');

  utils = require('./utils');

  Transport = (function() {
    function Transport() {}

    return Transport;

  })();

  Transport.CONNECTING = 0;

  Transport.OPEN = 1;

  Transport.CLOSING = 2;

  Transport.CLOSED = 3;

  closeFrame = function(status, reason) {
    return 'c' + JSON.stringify([status, reason]);
  };

  SockJSConnection = (function(_super) {
    __extends(SockJSConnection, _super);

    function SockJSConnection(_session) {
      this._session = _session;
      this.id = uuid.v4();
      this.headers = {};
      this.prefix = this._session.prefix;
    }

    SockJSConnection.prototype.toString = function() {
      return '<SockJSConnection ' + this.id + '>';
    };

    SockJSConnection.prototype.write = function(string) {
      return this._session.send('' + string);
    };

    SockJSConnection.prototype.end = function(string) {
      if (string) {
        this.write(string);
      }
      this.close();
      return null;
    };

    SockJSConnection.prototype.close = function(code, reason) {
      return this._session.close(code, reason);
    };

    SockJSConnection.prototype.destroy = function() {
      this.end();
      return this.removeAllListeners();
    };

    SockJSConnection.prototype.destroySoon = function() {
      return this.destroy();
    };

    return SockJSConnection;

  })(stream.Stream);

  SockJSConnection.prototype.__defineGetter__('readable', function() {
    return this._session.readyState === Transport.OPEN;
  });

  SockJSConnection.prototype.__defineGetter__('writable', function() {
    return this._session.readyState === Transport.OPEN;
  });

  SockJSConnection.prototype.__defineGetter__('readyState', function() {
    return this._session.readyState;
  });

  MAP = {};

  Session = (function() {
    function Session(session_id, server) {
      this.session_id = session_id;
      this.heartbeat_delay = server.options.heartbeat_delay;
      this.disconnect_delay = server.options.disconnect_delay;
      this.prefix = server.options.prefix;
      this.send_buffer = [];
      this.is_closing = false;
      this.readyState = Transport.CONNECTING;
      if (this.session_id) {
        MAP[this.session_id] = this;
      }
      this.timeout_cb = (function(_this) {
        return function() {
          return _this.didTimeout();
        };
      })(this);
      this.to_tref = setTimeout(this.timeout_cb, this.disconnect_delay);
      this.connection = new SockJSConnection(this);
      this.emit_open = (function(_this) {
        return function() {
          _this.emit_open = null;
          return server.emit('connection', _this.connection);
        };
      })(this);
    }

    Session.prototype.register = function(req, recv) {
      if (this.recv) {
        recv.doSendFrame(closeFrame(2010, "Another connection still open"));
        recv.didClose();
        return;
      }
      if (this.to_tref) {
        clearTimeout(this.to_tref);
        this.to_tref = null;
      }
      if (this.readyState === Transport.CLOSING) {
        this.flushToRecv(recv);
        recv.doSendFrame(this.close_frame);
        recv.didClose();
        this.to_tref = setTimeout(this.timeout_cb, this.disconnect_delay);
        return;
      }
      this.recv = recv;
      this.recv.session = this;
      this.decorateConnection(req);
      if (this.readyState === Transport.CONNECTING) {
        this.recv.doSendFrame('o');
        this.readyState = Transport.OPEN;
        process.nextTick(this.emit_open);
      }
      if (!this.recv) {
        return;
      }
      this.tryFlush();
    };

    Session.prototype.decorateConnection = function(req) {
      var address, headers, key, remoteAddress, remotePort, socket, x, _i, _len, _ref;
      if (!(socket = this.recv.connection)) {
        socket = this.recv.response.connection;
      }
      try {
        remoteAddress = socket.remoteAddress;
        remotePort = socket.remotePort;
        address = socket.address();
      } catch (_error) {
        x = _error;
      }
      if (remoteAddress) {
        this.connection.remoteAddress = remoteAddress;
        this.connection.remotePort = remotePort;
        this.connection.address = address;
      }
      this.connection.url = req.url;
      this.connection.pathname = req.pathname;
      this.connection.protocol = this.recv.protocol;
      headers = {};
      _ref = ['referer', 'x-client-ip', 'x-forwarded-for', 'x-cluster-client-ip', 'via', 'x-real-ip', 'host', 'user-agent', 'accept-language'];
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        key = _ref[_i];
        if (req.headers[key]) {
          headers[key] = req.headers[key];
        }
      }
      if (headers) {
        return this.connection.headers = headers;
      }
    };

    Session.prototype.unregister = function() {
      var delay;
      delay = this.recv.delay_disconnect;
      this.recv.session = null;
      this.recv = null;
      if (this.to_tref) {
        clearTimeout(this.to_tref);
      }
      if (delay) {
        return this.to_tref = setTimeout(this.timeout_cb, this.disconnect_delay);
      } else {
        return this.timeout_cb();
      }
    };

    Session.prototype.flushToRecv = function(recv) {
      var sb, _ref;
      if (this.send_buffer.length > 0) {
        _ref = [this.send_buffer, []], sb = _ref[0], this.send_buffer = _ref[1];
        recv.doSendBulk(sb);
        return true;
      }
      return false;
    };

    Session.prototype.tryFlush = function() {
      var x;
      if (!this.flushToRecv(this.recv) || !this.to_tref) {
        if (this.to_tref) {
          clearTimeout(this.to_tref);
        }
        x = (function(_this) {
          return function() {
            if (_this.recv) {
              _this.to_tref = setTimeout(x, _this.heartbeat_delay);
              return _this.recv.doSendFrame("h");
            }
          };
        })(this);
        this.to_tref = setTimeout(x, this.heartbeat_delay);
      }
    };

    Session.prototype.didTimeout = function() {
      if (this.to_tref) {
        clearTimeout(this.to_tref);
        this.to_tref = null;
      }
      if (this.readyState !== Transport.CONNECTING && this.readyState !== Transport.OPEN && this.readyState !== Transport.CLOSING) {
        throw Error('INVALID_STATE_ERR');
      }
      if (this.recv) {
        throw Error('RECV_STILL_THERE');
      }
      this.readyState = Transport.CLOSED;
      this.connection.emit('end');
      this.connection.emit('close');
      this.connection = null;
      if (this.session_id) {
        delete MAP[this.session_id];
        return this.session_id = null;
      }
    };

    Session.prototype.didMessage = function(payload) {
      if (this.readyState === Transport.OPEN) {
        this.connection.emit('data', payload);
      }
    };

    Session.prototype.send = function(payload) {
      if (this.readyState !== Transport.OPEN) {
        return false;
      }
      this.send_buffer.push('' + payload);
      if (this.recv) {
        this.tryFlush();
      }
      return true;
    };

    Session.prototype.close = function(status, reason) {
      if (status == null) {
        status = 1000;
      }
      if (reason == null) {
        reason = "Normal closure";
      }
      if (this.readyState !== Transport.OPEN) {
        return false;
      }
      this.readyState = Transport.CLOSING;
      this.close_frame = closeFrame(status, reason);
      if (this.recv) {
        this.recv.doSendFrame(this.close_frame);
        if (this.recv) {
          this.recv.didClose();
        }
        if (this.recv) {
          this.unregister();
        }
      }
      return true;
    };

    return Session;

  })();

  Session.bySessionId = function(session_id) {
    if (!session_id) {
      return null;
    }
    return MAP[session_id] || null;
  };

  register = function(req, server, session_id, receiver) {
    var session;
    session = Session.bySessionId(session_id);
    if (!session) {
      session = new Session(session_id, server);
    }
    session.register(req, receiver);
    return session;
  };

  exports.register = function(req, server, receiver) {
    return register(req, server, req.session, receiver);
  };

  exports.registerNoSession = function(req, server, receiver) {
    return register(req, server, void 0, receiver);
  };

  GenericReceiver = (function() {
    function GenericReceiver(thingy) {
      this.thingy = thingy;
      this.setUp(this.thingy);
    }

    GenericReceiver.prototype.setUp = function() {
      this.thingy_end_cb = (function(_this) {
        return function() {
          return _this.didAbort();
        };
      })(this);
      this.thingy.addListener('close', this.thingy_end_cb);
      return this.thingy.addListener('end', this.thingy_end_cb);
    };

    GenericReceiver.prototype.tearDown = function() {
      this.thingy.removeListener('close', this.thingy_end_cb);
      this.thingy.removeListener('end', this.thingy_end_cb);
      return this.thingy_end_cb = null;
    };

    GenericReceiver.prototype.didAbort = function() {
      return this.didClose();
    };

    GenericReceiver.prototype.didClose = function() {
      if (this.thingy) {
        this.tearDown(this.thingy);
        this.thingy = null;
      }
      if (this.session) {
        return this.session.unregister();
      }
    };

    GenericReceiver.prototype.doSendBulk = function(messages) {
      var m, q_msgs;
      q_msgs = (function() {
        var _i, _len, _results;
        _results = [];
        for (_i = 0, _len = messages.length; _i < _len; _i++) {
          m = messages[_i];
          _results.push(utils.quote(m));
        }
        return _results;
      })();
      var blob="";

      while (q_msgs.length > 0) {

        blob += 'a' + '[' + q_msgs.splice(0,100).join(',') + ']';

        if (q_msgs.length > 0)
          blob += "\n";

      }

      return this.doSendFrame(blob);
    };

    return GenericReceiver;

  })();

  ResponseReceiver = (function(_super) {
    __extends(ResponseReceiver, _super);

    ResponseReceiver.prototype.max_response_size = void 0;

    ResponseReceiver.prototype.delay_disconnect = true;

    function ResponseReceiver(request, response, options) {
      var x;
      this.request = request;
      this.response = response;
      this.options = options;
      this.curr_response_size = 0;
      try {
        this.request.connection.setKeepAlive(true, 5000);
      } catch (_error) {
        x = _error;
      }
      ResponseReceiver.__super__.constructor.call(this, this.request.connection);
      if (this.max_response_size === void 0) {
        this.max_response_size = this.options.response_limit;
      }
    }

    ResponseReceiver.prototype.doSendFrame = function(payload) {
      var r, x;
      this.curr_response_size += payload.length;
      r = false;
      try {
        this.response.write(payload);
        r = true;
      } catch (_error) {
        x = _error;
      }
      if (this.max_response_size && this.curr_response_size >= this.max_response_size) {
        this.didClose();
      }
      return r;
    };

    ResponseReceiver.prototype.didClose = function() {
      var x;
      ResponseReceiver.__super__.didClose.apply(this, arguments);
      try {
        this.response.end();
      } catch (_error) {
        x = _error;
      }
      return this.response = null;
    };

    return ResponseReceiver;

  })(GenericReceiver);

  exports.GenericReceiver = GenericReceiver;

  exports.Transport = Transport;

  exports.Session = Session;

  exports.ResponseReceiver = ResponseReceiver;

  exports.SockJSConnection = SockJSConnection;

}).call(this);
<|endoftext|>


<commit_before>/**
 * Get system info
 *
 * @param {string} sysInfo System info
 * @returns {string} System info
 */
function getSysInfo(sysInfo) {
	if (sysInfo) {
		return sysInfo;
	}

	const os = require('os');
	/* istanbul ignore next */
	switch (os.platform()) {
		case 'darwin':
			return 'Macintosh; Intel Mac OS X ' + require('get-osx-version');

		case 'windows':
			switch (os.arch()) {
				case 'x64':
					return 'Windows; Win64; x64';
				case 'x86':
					return 'Windows; Win32; x86';
				case 'arm':
					return 'Windows; ARM';
				default:
					return 'Windows';
			}

		case 'linux':
			switch (os.arch()) {
				case 'x64':
					return 'Linux; x86_64';
				case 'i686':
					return 'Linux; i686';
				case 'arm':
					return 'Linux; ARM';
				default:
					return 'Linux';
			}

		default:
			return '';
	}
}

module.exports.getSysInfo = getSysInfo;
<commit_msg>refactor sysInfo<commit_after>/**
 * @param {string} arch The operating system CPU architecture
 * @returns {string} Linux system informations
 */
function linux(arch) {
	switch (arch) {
		case 'x64':
			return 'Linux; x86_64';
		case 'i686':
			return 'Linux; i686';
		case 'arm':
			return 'Linux; ARM';
		default:
			return 'Linux';
	}
}

/**
 *	@returns {string} macOS system informations
 */
function mac() {
	return 'Macintosh; Intel Mac OS X ' + require('get-osx-version');
}

/**
 * @param {string} arch The operating system CPU architecture
 * @returns {string} Windows system informations
 */
function windows(arch) {
	switch (arch) {
		case 'x64':
			return 'Windows; Win64; x64';
		case 'x86':
			return 'Windows; Win32; x86';
		case 'arm':
			return 'Windows; ARM';
		default:
			return 'Windows';
	}
}

/**
 * Get system info
 *
 * @param {string} sysInfo System info
 * @returns {string} System info
 */
function getSysInfo(sysInfo) {
	if (sysInfo) {
		return sysInfo;
	}

	const os = require('os');
	/* istanbul ignore next */
	switch (os.platform()) {
		case 'darwin':
			return mac();

		case 'linux':
			return linux(os.arch());

		case 'windows':
			return windows(os.arch());

		default:
			return '';
	}
}

module.exports.getSysInfo = getSysInfo;
<|endoftext|>


<commit_before>/**
 * Created by nuintun on 2015/4/27.
 */

'use strict';

var hash = require('./hash');
var cache = require('./cache');
var extname = require('path').extname;
var plugins = require('./plugins/');
var util = require('./util');
var debug = util.debug;

function transport(vinyl, options){
  if (options.cache) {
    // set hash
    vinyl.hash = hash(vinyl.stat);
    // get cache
    var cached = cache.get(vinyl);

    // if not cached, parse vinyl
    if (cached === null) {
      vinyl = parse(vinyl, options);

      // cache vinyl
      cache.set(vinyl);
    } else {
      // debug
      debug('read file from cache: %s', colors.magenta(pathFromCwd(vinyl.path)));

      vinyl = cached;
    }
  } else {
    vinyl = parse(vinyl, options);
  }

  return vinyl;
}

function parse(vinyl, options){
  var ext = extname(vinyl.path);
  var plugin = plugins[ext.substring(1)] || plugins.other;

  // parse vinyl
  return plugin(vinyl, options);
}

/**
 * exports module.
 */
module.exports = transport;
<commit_msg>add read file from cache debug log<commit_after>/**
 * Created by nuintun on 2015/4/27.
 */

'use strict';

var hash = require('./hash');
var cache = require('./cache');
var extname = require('path').extname;
var plugins = require('./plugins/');
var util = require('./util');
var debug = util.debug;

function transport(vinyl, options){
  if (options.cache) {
    // set hash
    vinyl.hash = hash(vinyl.stat);
    // get cache
    var cached = cache.get(vinyl);

    // if not cached, parse vinyl
    if (cached === null) {
      vinyl = parse(vinyl, options);

      // cache vinyl
      cache.set(vinyl);
    } else {
      // debug
      debug('read file from cache: %s', colors.magenta(util.pathFromCwd(vinyl.path)));

      vinyl = cached;
    }
  } else {
    vinyl = parse(vinyl, options);
  }

  return vinyl;
}

function parse(vinyl, options){
  var ext = extname(vinyl.path);
  var plugin = plugins[ext.substring(1)] || plugins.other;

  // parse vinyl
  return plugin(vinyl, options);
}

/**
 * exports module.
 */
module.exports = transport;
<|endoftext|>


<commit_before>module.exports = {
  queryString: [
    ''
  ],
  queryStringSubQuery: [
    'android',
    'topcashback',
    'Top_CashBack'
  ],
  blockedStrings: [
    'porn',
    'sex'
  ],
  resultType: [
    'mixed',
    'recent',
    'popular'
  ],
  responseString: [
    'Hi @screenName thanks for the follow!',
    '@screenName thanks for following!',
    'Hey @screenName thanks for the follow!',
    'Thanks for following @screenName!',
    'Hey @screenName, thanks for following!',
    'Awesome @screenName, thanks for following!',
    'Thanks for the follow @screenName!',
    'Thanks for following @screenName! Have a nice day!'
  ]
}
<commit_msg>query string modified<commit_after>module.exports = {
  queryString: [
    ''
  ],
  queryStringSubQuery: [
    'android',
    'topcashback',
    'Top_CashBack',
    'firozansar'
  ],
  blockedStrings: [
    'porn',
    'sex',
    'bet'
  ],
  resultType: [
    'mixed',
    'recent',
    'popular'
  ],
  responseString: [
    'Hi @screenName thanks for the follow!',
    '@screenName thanks for following!',
    'Hey @screenName thanks for the follow!',
    'Thanks for following @screenName!',
    'Hey @screenName, thanks for following!',
    'Awesome @screenName, thanks for following!',
    'Thanks for the follow @screenName!',
    'Thanks for following @screenName! Have a nice day!'
  ]
}
<|endoftext|>