<commit_before>var crypto = require('crypto');
var Buffer = require('buffer').Buffer;

function hex_hmac_sha1(data, key) {
  var hmac = crypto.createHmac('sha1', key);
  hmac.update(data);
  return hmac.digest('hex');
}

var base64 = {
    encode: function(str) {
        return (new Buffer(str)).toString('base64');
    },
    decode: function(str) {
        return (new Buffer(str, 'base64')).toString('utf8');
    }
};

var processCookie = exports.processCookie = function(name, value) {
  var len, parts, expires, remoteSig, localSig;

  parts = value.replace(/\*/g, '=').split("|");

  if ( parts.length !== 4 ) {
    return null;
  }

  len = parts[0];
  value = base64.decode( parts[1] ).substr(0, len);
  expires = new Date( +parts[2] );
  remoteSig = parts[3];

  if ( expires < Date.now() ) {
    return null;
  }

  localSig = hex_hmac_sha1( parts.slice( 0, 3 ).join("|"), cookieSecret() );

  if ( localSig !== remoteSig ) {
    throw new Error("invalid cookie signature: " + name);
  }

  return value;
};

var mutateHttp = function(http){
  http.IncomingMessage.prototype._parseCookies = function() {
    var header = this.headers["cookie"] || "",
        ret = {};

    header.split(";").forEach( function( cookie ) {
      var parts = cookie.split("="),
          name =  (parts[0] ? parts[0].trim() : ''),
          value = (parts[1] ? parts[1].trim() : '');

      ret[ name ] = value;
    });
    return this.cookies = ret;
  };

  http.IncomingMessage.prototype.getCookie = function( name ) {
    var cookies = this.cookies || this._parseCookies();
    return cookies[ name ] || null;
  };

  http.IncomingMessage.prototype.getSecureCookie = function( name ) {
    var value = this.getCookie( name );

    if ( !value ) {
      return null;
    }

    return processCookie(name, value);
  };

  // this probably isn't kosher, but it's the best way to keep the interface sane.
  var _writeHead = http.ServerResponse.prototype.writeHead;
  var COOKIE_KEY = 'Set-Cookie', slice = Array.prototype.slice;
  http.ServerResponse.prototype.writeHead = function () {
    // Honor the passed args and method signature (see http.writeHead docs)
    var args = slice.call(arguments), headers = args[args.length-1];
    if (!headers || typeof(headers) != 'object') {
      // No header arg - create and append to args list
      args.push(headers = []);
    }

    // Merge cookie values
    var prev = headers[COOKIE_KEY], cookies = this.cookies || [];
    if (prev) cookies.push(prev);
    if (cookies.length > 0) headers[COOKIE_KEY] = cookies.join(", ");

    // Invoke original writeHead()
    _writeHead.apply(this, args);
  };

  http.ServerResponse.prototype.setCookie = function( name, value, options ) {
    var cookies = this.cookies || ( this.cookies = [] ),
        cookie = [ name, "=", value, ";" ];

    options = options || {};

    if ( options.expires )
      cookie.push( " expires=", (new Date(options.expires)).toUTCString(), ";" );

    if ( options.path )
      cookie.push( " path=", options.path, ";" );

    if ( options.domain )
      cookie.push( " domain=", options.domain, ";" );

    if ( options.secure )
      cookie.push( " secure", ";" );

    if ( options.httpOnly )
      cookie.push( " httponly" );

    cookies.push( cookie.join("") );
  };

  http.ServerResponse.prototype.generateCookieValue = function( value, options ) {
    options = options || {};
    value = [ (value + '').length, base64.encode( value ), +options.expires ];
    var signature = hex_hmac_sha1( value.join("|"), cookieSecret() );

    value.push( signature );
    value = value.join("|").replace(/=/g, '*');

    return value;
  };

  http.ServerResponse.prototype.setSecureCookie = function( name, value, options ) {
    options = options || {};
    if (value !== null && typeof value !== 'undefined') value = value.toString();
    else value = '';
    value = this.generateCookieValue(value, options);
    this.setCookie( name, value, options );
  };

  http.ServerResponse.prototype.clearCookie = function( name, options ) {
    options = options || {};
    options.expires = new Date( Date.now() - 30 * 24 * 60 * 60 * 1000 );
    this.setCookie( name, "", options );
  };
};

mutateHttp(require('http'));

function cookieSecret() {
  if ( exports.secret )
    return exports.secret;

  return exports.secret = hex_hmac_sha1( Math.random(), Math.random() );
}
<commit_msg>Fix the multiple-cookies bug.<commit_after>var crypto = require('crypto');
var Buffer = require('buffer').Buffer;

function hex_hmac_sha1(data, key) {
  var hmac = crypto.createHmac('sha1', key);
  hmac.update(data);
  return hmac.digest('hex');
}

var base64 = {
    encode: function(str) {
        return (new Buffer(str)).toString('base64');
    },
    decode: function(str) {
        return (new Buffer(str, 'base64')).toString('utf8');
    }
};

var processCookie = exports.processCookie = function(name, value) {
  var len, parts, expires, remoteSig, localSig;

  parts = value.replace(/\*/g, '=').split("|");

  if ( parts.length !== 4 ) {
    return null;
  }

  len = parts[0];
  value = base64.decode( parts[1] ).substr(0, len);
  expires = new Date( +parts[2] );
  remoteSig = parts[3];

  if ( expires < Date.now() ) {
    return null;
  }

  localSig = hex_hmac_sha1( parts.slice( 0, 3 ).join("|"), cookieSecret() );

  if ( localSig !== remoteSig ) {
    throw new Error("invalid cookie signature: " + name);
  }

  return value;
};

var mutateHttp = function(http){
  http.IncomingMessage.prototype._parseCookies = function() {
    var header = this.headers["cookie"] || "",
        ret = {};

    header.split(";").forEach( function( cookie ) {
      var parts = cookie.split("="),
          name =  (parts[0] ? parts[0].trim() : ''),
          value = (parts[1] ? parts[1].trim() : '');

      ret[ name ] = value;
    });
    return this.cookies = ret;
  };

  http.IncomingMessage.prototype.getCookie = function( name ) {
    var cookies = this.cookies || this._parseCookies();
    return cookies[ name ] || null;
  };

  http.IncomingMessage.prototype.getSecureCookie = function( name ) {
    var value = this.getCookie( name );

    if ( !value ) {
      return null;
    }

    return processCookie(name, value);
  };

  // this probably isn't kosher, but it's the best way to keep the interface sane.
  var _writeHead = http.ServerResponse.prototype.writeHead;
  var COOKIE_KEY = 'Set-Cookie', slice = Array.prototype.slice;
  http.ServerResponse.prototype.writeHead = function () {
    // Honor the passed args and method signature (see http.writeHead docs)
    var args = slice.call(arguments), headers = args[args.length-1];
    if (!headers || typeof(headers) != 'object') {
      // No header arg - create and append to args list
      args.push(headers = []);
    }

    // Merge cookie values
    var prev = headers[COOKIE_KEY], cookies = this.cookies || [];
    if (prev) cookies.push(prev);
    if (cookies.length > 0) headers[COOKIE_KEY] = cookies.join(" ");

    // Invoke original writeHead()
    _writeHead.apply(this, args);
  };

  http.ServerResponse.prototype.setCookie = function( name, value, options ) {
    var cookies = this.cookies || ( this.cookies = [] ),
        cookie = [ name, "=", value, ";" ];

    options = options || {};

    if ( options.expires )
      cookie.push( " expires=", (new Date(options.expires)).toUTCString(), ";" );

    if ( options.path )
      cookie.push( " path=", options.path, ";" );

    if ( options.domain )
      cookie.push( " domain=", options.domain, ";" );

    if ( options.secure )
      cookie.push( " secure", ";" );

    if ( options.httpOnly )
      cookie.push( " httponly" );

    cookies.push( cookie.join("") );
  };

  http.ServerResponse.prototype.generateCookieValue = function( value, options ) {
    options = options || {};
    value = [ (value + '').length, base64.encode( value ), +options.expires ];
    var signature = hex_hmac_sha1( value.join("|"), cookieSecret() );

    value.push( signature );
    value = value.join("|").replace(/=/g, '*');

    return value;
  };

  http.ServerResponse.prototype.setSecureCookie = function( name, value, options ) {
    options = options || {};
    if (value !== null && typeof value !== 'undefined') value = value.toString();
    else value = '';
    value = this.generateCookieValue(value, options);
    this.setCookie( name, value, options );
  };

  http.ServerResponse.prototype.clearCookie = function( name, options ) {
    options = options || {};
    options.expires = new Date( Date.now() - 30 * 24 * 60 * 60 * 1000 );
    this.setCookie( name, "", options );
  };
};

mutateHttp(require('http'));

function cookieSecret() {
  if ( exports.secret )
    return exports.secret;

  return exports.secret = hex_hmac_sha1( Math.random(), Math.random() );
}
<|endoftext|>


<commit_before>describe( 'Removing children', function(){

  var app = require( '../../../lib/app' )
  var Element = require( '../../../lib/element' )
  var util = require( 'vjs/lib/util' )

  var elem = new Element({
    $key: 'a',
    elemChild: {},
    elemChild2: {}
  })

  var elemInstance = new elem.$Constructor({
    $key: 'b',
    elemInstanceChild: {}
  })

  app.set({
  	elem:elem,
  	elemInstance:elemInstance
  })

  describe( 'Removing child from original', function(){
  	it('app.elem.elemChild.remove()',function(){
      // console.clear()

      //what goes wrong here is

      // elem with isntances

      // context word geset in emit

      // emit is after orig -- set instance
      // not orignal anumore??

      // console.log(elem, elem.elemChild._$context)
      elem.elemChild.$resetContextsUp()

  		elem.elemChild.remove()
      // console.log(elem.
  	})

  	it( 'app.elem.elemChild is removed', function () {
      //this test is wrong
      // console.log('1!@#!@#?',elem.elemChild )
  		expect( elem.elemChild ).to.not.be.ok
  	})

  	it( 'app.elemInstance.elemChild is also removed', function () {
      // console.clear()
      console.log('!@#!@#?',elemInstance.elemChild )
  		expect(elemInstance.elemChild).to.not.be.ok

  	})
    //
  	// //TODO: this test is good, we need to fix remove for nodes, and uncomment the test
  	it( 'app.elem.elemChild and app.elemInstance.elemChild nodes are removed', function () {
  		expect(document.getElementsByClassName('elemChild').length).to.not.be.ok
  	})

  })
  //
  //remove child from instance
  describe( 'Remove child from instance', function(){

  	it('app.elemInstance.elemChild2.remove()',function(){
  		elemInstance.elemChild2.remove()
  	})

  	it( 'app.elemInstance.elemChild2 is removed', function () {
  		expect( elemInstance.elemChild2 ).to.be.null
  	})

  	it( 'app.elem.elemChild2 is not removed', function () {

      //nu deze nog!

  		expect(elem.elemChild2).to.be.ok
  	})

  	//TODO: this test is good, we need to fix remove for nodes, and uncomment the test
  	it( 'only app.elemInstance.elemChild2 node is removed', function () {
  		expect(document.getElementsByClassName('elemChild2').length).to.not.be.one
  	})

  })

  describe( 'Removing original', function(){
  	it('app.elem.remove()',function(){
  		app.elem.remove()
  	})

  	it( 'app.elem is removed', function () {
  		expect(app.elem).to.not.be.ok
  	})

  	it( 'app.elemInstance is removed', function () {
  		expect(app.elemInstance).to.not.be.ok
  	})

  	//TODO: this test is good, we need to fix remove for nodes, and uncomment the test
  	it( 'app.elem.elemChild and app.elemInstance.elemChild nodes are removed', function () {
  		expect(document.getElementsByClassName('elemChild').length).to.not.be.ok
  	})

  })

})
<commit_msg>removed resetContextsUp<commit_after>describe( 'Removing children', function(){

  var app = require( '../../../lib/app' )
  var Element = require( '../../../lib/element' )
  var util = require( 'vjs/lib/util' )

  var elem = new Element({
    $key: 'a',
    elemChild: {},
    elemChild2: {}
  })

  var elemInstance = new elem.$Constructor({
    $key: 'b',
    elemInstanceChild: {}
  })

  app.set({
  	elem:elem,
  	elemInstance:elemInstance
  })

  describe( 'Removing child from original', function(){
  	it('app.elem.elemChild.remove()',function(){
      // console.clear()

      //what goes wrong here is

      // elem with isntances

      // context word geset in emit

      // emit is after orig -- set instance
      // not orignal anumore??

      // console.log(elem, elem.elemChild._$context)
      // elem.elemChild.$resetContextsUp()

  		elem.elemChild.remove()
      // console.log(elem.
  	})

  	it( 'app.elem.elemChild is removed', function () {
      //this test is wrong
      // console.log('1!@#!@#?',elem.elemChild )
  		expect( elem.elemChild ).to.not.be.ok
  	})

  	it( 'app.elemInstance.elemChild is also removed', function () {
      // console.clear()
      console.log('!@#!@#?',elemInstance.elemChild )
  		expect(elemInstance.elemChild).to.not.be.ok

  	})
    //
  	// //TODO: this test is good, we need to fix remove for nodes, and uncomment the test
  	it( 'app.elem.elemChild and app.elemInstance.elemChild nodes are removed', function () {
  		expect(document.getElementsByClassName('elemChild').length).to.not.be.ok
  	})

  })
  //
  //remove child from instance
  describe( 'Remove child from instance', function(){

  	it('app.elemInstance.elemChild2.remove()',function(){
  		elemInstance.elemChild2.remove()
  	})

  	it( 'app.elemInstance.elemChild2 is removed', function () {
  		expect( elemInstance.elemChild2 ).to.be.null
  	})

  	it( 'app.elem.elemChild2 is not removed', function () {

      //nu deze nog!

  		expect(elem.elemChild2).to.be.ok
  	})

  	//TODO: this test is good, we need to fix remove for nodes, and uncomment the test
  	it( 'only app.elemInstance.elemChild2 node is removed', function () {
  		expect(document.getElementsByClassName('elemChild2').length).to.not.be.one
  	})

  })

  describe( 'Removing original', function(){
  	it('app.elem.remove()',function(){
  		app.elem.remove()
  	})

  	it( 'app.elem is removed', function () {
  		expect(app.elem).to.not.be.ok
  	})

  	it( 'app.elemInstance is removed', function () {
  		expect(app.elemInstance).to.not.be.ok
  	})

  	//TODO: this test is good, we need to fix remove for nodes, and uncomment the test
  	it( 'app.elem.elemChild and app.elemInstance.elemChild nodes are removed', function () {
  		expect(document.getElementsByClassName('elemChild').length).to.not.be.ok
  	})

  })

})
<|endoftext|>


<commit_before><commit_msg>it does something! Will get back to this later<commit_after>var tessel = require('tessel');
var myPin = tessel.port['B'].pin['G1'];

var state;

setInterval(function () {
  state = myPin.read();
  console.log(state);
}, 10);

// it just toggles based on flow
// if a plastic sensor use the following calculation
// Sensor Frequency (Hz) = 7.5 * Q (Liters/min)
// Liters = Q * time elapsed (seconds) / 60 (seconds/minute)
// Liters = (Frequency (Pulses/second) / 7.5) * time elapsed (seconds) / 60
// Liters = Pulses / (7.5 * 60)

// Count toggles to get a volume

// Get time between toggles to get an instantaneous flow rate

// What else is useful to measure?
<|endoftext|>


<commit_before>//default service locations
var proxyLocation = process.env.X509_USER_PROXY ? process.env.X509_USER_PROXY : 'user-proxy.pem';
var atmoLocation = process.env.ATMOSPHERE_URL ? process.env.ATMOSPHERE_URL : 'cloud.plgrid.pl';

//default ids of vms
var wfMainId = process.env.WF_MAIN_ID ? process.env.WF_MAIN_ID : 62;
var wfWorkerId = process.env.WF_WORDKER_ID ? process.env.WF_WORDKER_ID : 63;

var wfApplianceSetName = 'hfworkflow';

//default location of user stored config for hflowc
var configLocations = [
    '~/.hflow.config.json'
];

module.exports.default_config = {
    proxyLocation: proxyLocation,
    atmoLocation: atmoLocation,
    wfMainId: wfMainId,
    wfWorkerId: wfWorkerId,
    wfApplianceSetName: wfApplianceSetName
};

module.exports.configLocations = configLocations;
<commit_msg>Update image ids.<commit_after>//default service locations
var proxyLocation = process.env.X509_USER_PROXY ? process.env.X509_USER_PROXY : 'user-proxy.pem';
var atmoLocation = process.env.ATMOSPHERE_URL ? process.env.ATMOSPHERE_URL : 'cloud.plgrid.pl';

//default ids of vms
var wfMainId = process.env.WF_MAIN_ID ? process.env.WF_MAIN_ID : 65;
var wfWorkerId = process.env.WF_WORDKER_ID ? process.env.WF_WORDKER_ID : 63;

var wfApplianceSetName = 'hfworkflow';

//default location of user stored config for hflowc
var configLocations = [
    '~/.hflow.config.json'
];

module.exports.default_config = {
    proxyLocation: proxyLocation,
    atmoLocation: atmoLocation,
    wfMainId: wfMainId,
    wfWorkerId: wfWorkerId,
    wfApplianceSetName: wfApplianceSetName
};

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


<commit_before>var Action = require('node-matrix-import-actions')
var assets = require('node-matrix-asset-list')
var EventEmitter = require('events').EventEmitter
var extend = require('xtend')
var inherits = require('inherits')
var js2php = require('./js2php')
var xml2js = require('xml2js')

function outputAsId (actionId) {
  return '[[output://' + actionId + '.assetid]]'
}

function Importer (opts) {
  if (!(this instanceof Importer)) {
    return new Importer(opts)
  }

  if (!opts || !opts.hasOwnProperty) {
    opts = {}
  }

  EventEmitter.call(this)

  this._ids = []
  this._cache = null
  this._sorted = !!opts.sortActions
  this._actions = this._sorted ? {
    create_asset: [],
    add_web_path: [],
    set_attribute_value: [],
    set_design_parse_file: [],
    set_metadata_schema: [],
    set_metadata_value: [],
    create_link: [],
    set_permission: []
  } : []
  this._createActionId = function createActionId (opts) {
    var action = this.getActionById(opts.assetId)
    var asset = assets(opts.type)

    if (!opts.id) {
      if (action && (asset = assets(action.type_code))) {
        opts.id = asset.name.replace(' ', '_') + '_' + action.id.replace('#', '')
      } else if (asset) {
        opts.id = asset.name.replace(' ', '_') + '_' + (this._ids.length)
      } else if (opts.type) {
        opts.id = opts.type.replace(' ', '_') + '_' + (this._ids.length)
      } else {
        opts.id = Date.now() + ''
      }
    }

    return opts
  }
}

inherits(Importer, EventEmitter)

Importer.prototype.addAction = function addAction (type, opts) {
  var collection = this._sorted ? this._actions[opts.file && type !== 'set_design_parse_file' ? 'create_asset' : type] : this._actions
  var action = new Action(type, this._createActionId(opts))
  var deferredEmitters = ['create_asset', 'create_file_asset']

  // clear cache
  if (this._cache) {
    this._cache = null
  }

  action.action_id = action.action_id.replace(/#/g, '')

  if (this.getActionById(action.asset)) {
    action.asset = outputAsId(this.getActionById(action.asset).action_id)
  }

  if (this.getActionById(action.assetid)) {
    action.assetid = outputAsId(this.getActionById(action.assetid).action_id)
  }

  if (this.getActionById(action.fieldid)) {
    action.fieldid = outputAsId(this.getActionById(action.fieldid).action_id)
  }

  if (this.getActionById(action.parentid)) {
    action.parentid = outputAsId(this.getActionById(action.parentid).action_id)
  }

  if (this.getActionById(action.schemaid)) {
    action.schemaid = outputAsId(this.getActionById(action.schemaid).action_id)
  }

  if (this.getActionById(action.userid)) {
    action.userid = outputAsId(this.getActionById(action.userid).action_id)
  }

  collection.push(action)

  if (!~deferredEmitters.indexOf(type)) {
    this.emit(type, action)
  }

  return action
}

Importer.prototype.addPath = function addPath (opts) {
  return this.addAction('add_web_path', opts)
}

Importer.prototype.createAsset = function createAsset (opts) {
  // move the bulk of this function into `this.addAction`.
  var collection = this._sorted ? this._actions.create_asset : this._actions
  var pointer = this._ids.push(collection.length)
  var type = opts.file ? 'create_file_asset' : 'create_asset'

  try {
    // use valid type_code where possible
    opts.type = assets(opts.type).type_code
  } catch (e) {}

  var action = extend(this.addAction(type, opts), { id: '#' + pointer })

  this.emit(type, action)

  return action
}

Importer.prototype.createLink = function createLink (opts) {
  return this.addAction('create_link', opts)
}

Importer.prototype.setAttribute = function setAttribute (opts) {
  return this.addAction('set_attribute_value', opts)
}

Importer.prototype.setParseFile = function setParseFile (opts) {
  return this.addAction('set_design_parse_file', opts)
}

Importer.prototype.setMetadataSchema = function setAttribute (opts) {
  return this.addAction('set_metadata_schema', opts)
}

Importer.prototype.setMetadataValue = function setAttribute (opts) {
  return this.addAction('set_metadata_value', opts)
}

Importer.prototype.setPermission = function setPermission (opts) {
  return this.addAction('set_permission', opts)
}

Importer.prototype.getActionById = function getActionById (id) {
  var collection = this._sorted ? this._actions.create_asset : this._actions

  if (/#/.test(id += '')) {
    id = +(id.replace('#', ''))
    return extend(collection[this._ids[id - 1]], { id: '#' + id })
  }
}

Importer.prototype.toString = function importerToString (renderOpts) {
  if (this._cache) {
    return this._cache
  }

  var collection = this._sorted ? Object.keys(this._actions)
    .map(function mergeKeys (key) {
      return this[key]
    }, this._actions).reduce(function flatten (a, b) {
      return a.concat(b)
    }) : this._actions
  var opts = {
    rootName: 'actions',
    cdata: true
  }

  if (renderOpts && typeof renderOpts === 'object') {
    opts.renderOpts = renderOpts
  }

  this._cache = new xml2js.Builder(opts).buildObject({
    action: collection.map(function makeCDATA (action) {
      if (action.value) {
        action = extend({}, action)

        action.value = js2php(action.value)
      }
      return action
    })
  })

  return this._cache
}

module.exports = Importer
<commit_msg>Remove try/catch from createAsset method<commit_after>var Action = require('node-matrix-import-actions')
var assets = require('node-matrix-asset-list')
var EventEmitter = require('events').EventEmitter
var extend = require('xtend')
var inherits = require('inherits')
var js2php = require('./js2php')
var xml2js = require('xml2js')

function outputAsId (actionId) {
  return '[[output://' + actionId + '.assetid]]'
}

function Importer (opts) {
  if (!(this instanceof Importer)) {
    return new Importer(opts)
  }

  if (!opts || !opts.hasOwnProperty) {
    opts = {}
  }

  EventEmitter.call(this)

  this._ids = []
  this._cache = null
  this._sorted = !!opts.sortActions
  this._actions = this._sorted ? {
    create_asset: [],
    add_web_path: [],
    set_attribute_value: [],
    set_design_parse_file: [],
    set_metadata_schema: [],
    set_metadata_value: [],
    create_link: [],
    set_permission: []
  } : []
  this._createActionId = function createActionId (opts) {
    var action = this.getActionById(opts.assetId)
    var asset = assets(opts.type)

    if (!opts.id) {
      if (action && (asset = assets(action.type_code))) {
        opts.id = asset.name.replace(' ', '_') + '_' + action.id.replace('#', '')
      } else if (asset) {
        opts.id = asset.name.replace(' ', '_') + '_' + (this._ids.length)
      } else if (opts.type) {
        opts.id = opts.type.replace(' ', '_') + '_' + (this._ids.length)
      } else {
        opts.id = Date.now() + ''
      }
    }

    return opts
  }
}

inherits(Importer, EventEmitter)

Importer.prototype.addAction = function addAction (type, opts) {
  var collection = this._sorted ? this._actions[opts.file && type !== 'set_design_parse_file' ? 'create_asset' : type] : this._actions
  var action = new Action(type, this._createActionId(opts))
  var deferredEmitters = ['create_asset', 'create_file_asset']

  // clear cache
  if (this._cache) {
    this._cache = null
  }

  action.action_id = action.action_id.replace(/#/g, '')

  if (this.getActionById(action.asset)) {
    action.asset = outputAsId(this.getActionById(action.asset).action_id)
  }

  if (this.getActionById(action.assetid)) {
    action.assetid = outputAsId(this.getActionById(action.assetid).action_id)
  }

  if (this.getActionById(action.fieldid)) {
    action.fieldid = outputAsId(this.getActionById(action.fieldid).action_id)
  }

  if (this.getActionById(action.parentid)) {
    action.parentid = outputAsId(this.getActionById(action.parentid).action_id)
  }

  if (this.getActionById(action.schemaid)) {
    action.schemaid = outputAsId(this.getActionById(action.schemaid).action_id)
  }

  if (this.getActionById(action.userid)) {
    action.userid = outputAsId(this.getActionById(action.userid).action_id)
  }

  collection.push(action)

  if (!~deferredEmitters.indexOf(type)) {
    this.emit(type, action)
  }

  return action
}

Importer.prototype.addPath = function addPath (opts) {
  return this.addAction('add_web_path', opts)
}

Importer.prototype.createAsset = function createAsset (opts) {
  // move the bulk of this function into `this.addAction`.
  var collection = this._sorted ? this._actions.create_asset : this._actions
  var pointer = this._ids.push(collection.length)
  var type = opts.file ? 'create_file_asset' : 'create_asset'
  var asset = assets(opts.type)

  if (asset) {
    // use valid type_code where possible
    opts.type = asset.type_code
  }

  var action = extend(this.addAction(type, opts), { id: '#' + pointer })

  this.emit(type, action)

  return action
}

Importer.prototype.createLink = function createLink (opts) {
  return this.addAction('create_link', opts)
}

Importer.prototype.setAttribute = function setAttribute (opts) {
  return this.addAction('set_attribute_value', opts)
}

Importer.prototype.setParseFile = function setParseFile (opts) {
  return this.addAction('set_design_parse_file', opts)
}

Importer.prototype.setMetadataSchema = function setAttribute (opts) {
  return this.addAction('set_metadata_schema', opts)
}

Importer.prototype.setMetadataValue = function setAttribute (opts) {
  return this.addAction('set_metadata_value', opts)
}

Importer.prototype.setPermission = function setPermission (opts) {
  return this.addAction('set_permission', opts)
}

Importer.prototype.getActionById = function getActionById (id) {
  var collection = this._sorted ? this._actions.create_asset : this._actions

  if (/#/.test(id += '')) {
    id = +(id.replace('#', ''))
    return extend(collection[this._ids[id - 1]], { id: '#' + id })
  }
}

Importer.prototype.toString = function importerToString (renderOpts) {
  if (this._cache) {
    return this._cache
  }

  var collection = this._sorted ? Object.keys(this._actions)
    .map(function mergeKeys (key) {
      return this[key]
    }, this._actions).reduce(function flatten (a, b) {
      return a.concat(b)
    }) : this._actions
  var opts = {
    rootName: 'actions',
    cdata: true
  }

  if (renderOpts && typeof renderOpts === 'object') {
    opts.renderOpts = renderOpts
  }

  this._cache = new xml2js.Builder(opts).buildObject({
    action: collection.map(function makeCDATA (action) {
      if (action.value) {
        action = extend({}, action)

        action.value = js2php(action.value)
      }
      return action
    })
  })

  return this._cache
}

module.exports = Importer
<|endoftext|>


<commit_before>"use strict";

var fs            = require('fs');
var through       = require('through');
var transform     = require('require-assets-jstransform');
var requireAssets = require('require-assets');

/**
 * Browserify entry point, decides which one to activate — transform or plugin.
 *
 * @public
 *
 * @param {Browserify|String} b
 * @param {Object} options
 */
module.exports = function requireAssetsBrowserify(b, options) {
  if (typeof b.bundle === 'function' && typeof b.transform === 'function') {
    return plugin(b, options);
  } else {
    return transform(b, options);
  }
}

/**
 * Browserify transform to rewrite requireAssets(...) calls to URLs.
 *
 * Command line usage:
 *
 *    % browserify -t require-assets-browserify ...
 *
 * @public
 *
 * @param {String} filename
 * @param {Object} options
 */
var transform = makeTransform();

/**
 * Browserify plugin to rewrite requireAssets(...) calls to URLs and dump
 * registry in file.
 *
 * Command line usage:
 *
 *    % browserify -p [ require-assets-browserify --output ./assets.json ] ...
 *
 * @param {Browserify} b
 * @param {Object} options
 */
function plugin(b, options) {
  var output = options && (options.o || options.output);

  if (!output) {
    throw new Error(
      'provide output for require-assets/browserify: ' +
      'browserify -p [ require-assets/browserify --output ./url-filename.json ] ...');
  }

  var registry = registryFromOptions(options);

  b.transform(makeTransform(registry));

  b.on('bundle', function(stream) {
    stream.on('end', function() {
      fs.writeFile(output, JSON.stringify(registry), function(err) {
        if (err) stream.emit('error', err);
      });
    });
  });

  return b;
}

/**
 * Aggregate stream and call a callback.
 *
 * @private
 *
 * @param {Function.<String>} cb
 */
function aggregate(cb) {
  var src = '';
  return through(
    function(c) { src += c; },
    function() { cb.call(this, src); }
  );
}

/**
 * Make new browserify transform which populates the registry.
 *
 * @private
 */
function makeTransform(registry) {

  return function(filename, options) {
    options = options || {};

    var registry = registry || registryFromOptions(options);

    return aggregate(function(src) {
      this.queue(transform(src));
      this.queue(null);
    });
  }
}

/**
 * Get registry from options
 */
function registryFromOptions(options) {
  if (options.requireAssets && options.mapping)
    return options;
  if (options.prefix || options.root)
    return requireAssets.createRegistry(options);
  return require.currentRegistry();
}
<commit_msg>Fixes<commit_after>"use strict";

var fs            = require('fs');
var through       = require('through');
var jstransform   = require('require-assets-jstransform');
var requireAssets = require('require-assets');

/**
 * Browserify entry point, decides which one to activate — transform or plugin.
 *
 * @public
 *
 * @param {Browserify|String} b
 * @param {Object} options
 */
module.exports = function requireAssetsBrowserify(b, options) {
  if (typeof b.bundle === 'function' && typeof b.transform === 'function') {
    return plugin(b, options);
  } else {
    return transform(b, options);
  }
}

/**
 * Browserify transform to rewrite requireAssets(...) calls to URLs.
 *
 * Command line usage:
 *
 *    % browserify -t require-assets-browserify ...
 *
 * @public
 *
 * @param {String} filename
 * @param {Object} options
 */
var transform = makeTransform();

/**
 * Browserify plugin to rewrite requireAssets(...) calls to URLs and dump
 * registry in file.
 *
 * Command line usage:
 *
 *    % browserify -p [ require-assets-browserify --output ./assets.json ] ...
 *
 * @param {Browserify} b
 * @param {Object} options
 */
function plugin(b, options) {
  var output = options && (options.o || options.output);

  if (!output) {
    throw new Error(
      'provide output for require-assets/browserify: ' +
      'browserify -p [ require-assets/browserify --output ./url-filename.json ] ...');
  }

  var registry = registryFromOptions(options);

  b.transform(makeTransform(registry));

  b.on('bundle', function(stream) {
    stream.on('end', function() {
      fs.writeFile(output, JSON.stringify(registry), function(err) {
        if (err) stream.emit('error', err);
      });
    });
  });

  return b;
}

/**
 * Aggregate stream and call a callback.
 *
 * @private
 *
 * @param {Function.<String>} cb
 */
function aggregate(cb) {
  var src = '';
  return through(
    function(c) { src += c; },
    function() { cb.call(this, src); }
  );
}

/**
 * Make new browserify transform which populates the registry.
 *
 * @private
 */
function makeTransform(registry) {

  return function(filename, options) {
    options = options || {};

    var registry = registry || registryFromOptions(options);

    return aggregate(function(src) {
      try {
        src = jstransform(src);
      } catch(err) {
        return this.emit('error', err);
      }
      this.queue(src);
      this.queue(null);
    });
  }
}

/**
 * Get registry from options
 */
function registryFromOptions(options) {
  if (options.requireAssets && options.mapping)
    return options;
  if (options.prefix || options.root)
    return requireAssets.createRegistry(options);
  return requireAssets.currentRegistry();
}
<|endoftext|>


<commit_before>/*!
 * question-helper <https://github.com/doowb/question-helper>
 *
 * Copyright (c) 2014-2015, Brian Woodward.
 * Licensed under the MIT License.
 */

'use strict';

var inquirer = require('inquirer');

module.exports = function questionHelper(key, options, next) {
  var ctx = this && (this.ctx || this.context) || {};

  if (typeof options === 'function') {
    next = options;
    options = {};
  }

  if (typeof key !== 'string') {
    return next(new Error('Question expected the first parameter to be a string, but got [' + (typeof key) + ']'));
  }

  var q = ctx && ctx.questions && ctx.questions[key];
  if (!q) q = key;
  var obj = {
    name: key,
    message: q
  };

  inquirer.prompt([obj], function (answers) {
    return next(null, answers[key]);
  });
};
<commit_msg>allow a question object to be passed on opts<commit_after>/*!
 * question-helper <https://github.com/doowb/question-helper>
 *
 * Copyright (c) 2014-2015, Brian Woodward.
 * Licensed under the MIT License.
 */

'use strict';

var isObject = require('isobject');
var inquirer = require('inquirer');
var extend = require('extend-shallow');

module.exports = function questionHelper(key, opts, cb) {
  if (typeof key === 'function') {
    cb = key;
    opts = {};
    key = null;
  }

  if (typeof opts === 'function') {
    cb = opts;
    opts = {};
  }

  if (typeof key !== 'string') {
    var arg = JSON.stringify(key);
    return cb(new Error('question helper expects the first argument to be a string, but got: ' + arg));
  }

  if (typeof opts === 'string') {
    var str = opts;
    opts = {};
    opts[key] = str;
  }

  var context = (this && this.context) || {};
  opts = opts || {};

  context.questions = extend({}, context.questions, opts);
  var question = context.questions[key] || key;

  var result = typeof question === 'string' ? {
    name: key,
    message: question
  } : question;

  inquirer.prompt([result], function (answers) {
    return cb(null, answers[key]);
  });
};
<|endoftext|>


<commit_before>var dc = require('dependency-check');
var format = require('util').format;
var debug = require('debug')('mongodb-js-precommit');
var glob = require('glob');
var CLIEngine = require('eslint').CLIEngine;
var jsfmt = require('jsfmt');
var async = require('async');
var fs = require('fs');

function check(mode, done) {
  var pkg = require(process.cwd() + '/package.json');
  pkg['dependency-check'] = pkg['dependency-check'] || {
      entries: [],
      ignore: []
    };
  pkg.devDependencies = pkg.devDependencies || {};

  var opts = {
    path: process.cwd() + '/package.json',
    entries: pkg['dependency-check'].entries,
    ignore: pkg['dependency-check'].ignore
  };
  opts.ignore = opts.ignore || [];
  opts.entries = opts.entries || [];

  /**
   * Sane defaults for common devDependencies not used via an `entry` script.
   */
  opts.ignore.push.apply(opts.ignore, [
    'eslint-config-mongodb-js',
    'mongodb-js-precommit'
  ]);

  var test = pkg.scripts.test;
  /**
   * If mocha already a dependency and we're using it for `test`,
   * ignore it so it doesn't show up as an extra dependency.
   */
  if (test && test.indexOf('mocha') > -1 && pkg.devDependencies.mocha) {
    opts.ignore.push('mocha');
  }

  function filterIgnored(results) {
    return results.filter(function(name) {
      return opts.ignore.indexOf(name) === -1;
    });
  }

  dc(opts, function(err, data) {
    if (err) return done(err);
    var pkg = data.package;
    var deps = data.used;
    var results;
    var errMsg;
    var corrector;

    if (mode === 'extra') {
      // Are all dependencies in package.json are used in the code?
      results = filterIgnored(dc.extra(pkg, deps, {
        excludeDev: true
      }));
      errMsg = 'Modules in package.json not used in code';
      corrector = 'npm uninstall --save ' + results.join(' ') + ';';
    } else {
      // Are we missing any dependencies in package.json?
      results = filterIgnored(dc.missing(pkg, deps));
      errMsg = 'Dependencies not listed in package.json';
      corrector = 'npm install --save ' + results.join(' ') + ';';
    }

    if (results.length === 0) {
      return done();
    }
    console.error('Error: ' + errMsg + '. To fix this, run:\n\n    ' + corrector + '\n');
    return done(new Error(errMsg));
  });
}

var lint = function(opts, done) {
  var cli = new CLIEngine({
    useEslintrc: true
  });

  debug('Getting paths to lint...');
  debug('Linting files', opts.files);
  var report = cli.executeOnFiles(opts.files);
  var formatter = cli.getFormatter();
  console.log(formatter(report.results));

  if (report.errorCount > 0) {
    return done(new Error(format('Please fix the %d error(s) above and try again.',
      report.errorCount)));
  }
  done();
};

var fmt = function(opts, done) {
  var config = jsfmt.getConfig();

  function fmt(src, cb) {
    fs.readFile(src, function(err, buf) {
      if (err) return cb(err);
      try {
        var formatted = jsfmt.format(buf.toString('utf-8'), config);
        fs.writeFile(src, formatted, cb);
      } catch (e) {
        return cb(e);
      }
    });
  }
  async.parallel(opts.files.map(function(file) {
    return fmt.bind(null, file);
  }), done);
};

module.exports = function(done) {
  var opts = {};
  glob('**/*.js', {
    ignore: ['node_modules/**']
  }, function(err, files) {
    if (err) return done(err);

    opts.files = files;

    async.series({
      'missing dependencies': check.bind(null, 'missing'),
      'extra dependencies': check.bind(null, 'extra'),
      fmt: fmt.bind(null, opts),
      lint: lint.bind(null, opts)
    }, done);
  });
};
<commit_msg>allow ignoring build dirs, run all zee checks<commit_after>var dc = require('dependency-check');
var format = require('util').format;
var debug = require('debug')('mongodb-js-precommit');
var glob = require('glob');
var CLIEngine = require('eslint').CLIEngine;
var jsfmt = require('jsfmt');
var async = require('async');
var fs = require('fs');

function check(options, mode, done) {
  var pkg = require(process.cwd() + '/package.json');
  pkg['dependency-check'] = pkg['dependency-check'] || {
      entries: [],
      ignore: []
    };
  pkg.devDependencies = pkg.devDependencies || {};

  var opts = {
    path: process.cwd() + '/package.json',
    entries: pkg['dependency-check'].entries,
    ignore: pkg['dependency-check'].ignore
  };
  opts.ignore = opts.ignore || [];
  opts.entries = opts.entries || [];

  /**
   * Sane defaults for common devDependencies not used via an `entry` script.
   */
  opts.ignore.push.apply(opts.ignore, [
    'eslint-config-mongodb-js',
    'mongodb-js-precommit'
  ]);

  var test = pkg.scripts.test;
  /**
   * If mocha already a dependency and we're using it for `test`,
   * ignore it so it doesn't show up as an extra dependency.
   */
  if (test && test.indexOf('mocha') > -1 && pkg.devDependencies.mocha) {
    opts.ignore.push('mocha');
  }

  function filterIgnored(results) {
    return results.filter(function(name) {
      return opts.ignore.indexOf(name) === -1;
    });
  }

  dc(opts, function(err, data) {
    if (err) return done(err);
    var pkg = data.package;
    var deps = data.used;
    var results;
    var errMsg;
    var corrector;

    if (mode === 'extra') {
      // Are all dependencies in package.json are used in the code?
      results = filterIgnored(dc.extra(pkg, deps, {
        excludeDev: true
      }));
      errMsg = 'Modules in package.json not used in code';
      corrector = 'npm uninstall --save ' + results.join(' ') + ';';
    } else {
      // Are we missing any dependencies in package.json?
      results = filterIgnored(dc.missing(pkg, deps));
      errMsg = 'Dependencies not listed in package.json';
      corrector = 'npm install --save ' + results.join(' ') + ';';
    }

    if (results.length === 0) {
      return done();
    }
    console.error('Error: ' + errMsg + '. To fix this, run:\n\n    ' + corrector + '\n');
    options.result.errors.push(new Error(errMsg));
    return done();
  });
}

var lint = function(opts, done) {
  var cli = new CLIEngine({
    useEslintrc: true
  });

  debug('Getting paths to lint...');
  debug('Linting files', opts.files);
  var report = cli.executeOnFiles(opts.files);
  var formatter = cli.getFormatter();
  console.log(formatter(report.results));

  if (report.errorCount > 0) {
    var err = new Error(format(
      'Please fix the %d error(s) above and try again.', report.errorCount));
    opts.result.errors.push(err);
    return done();
  }
  done();
};

var fmt = function(opts, done) {
  var config = jsfmt.getConfig();

  function fmt(src, cb) {
    fs.readFile(src, function(err, buf) {
      if (err) return cb(err);
      try {
        var formatted = jsfmt.format(buf.toString('utf-8'), config);
        fs.writeFile(src, formatted, cb);
      } catch (e) {
        return cb(e);
      }
    });
  }
  async.parallel(opts.files.map(function(file) {
    return fmt.bind(null, file);
  }), function(err) {
    if (err) {
      opts.result.errors.push(err);
    }
    done();
  });
};

module.exports = function(done) {
  var pkg = require(process.cwd() + '/package.json');
  var opts = {
    ignore: [
      'node_modules/**'
    ]
  };
  pkg.check = pkg.check || {};
  pkg.check.ignore = pkg.check.ignore || [];

  opts.ignore.push.apply(opts.ignore, pkg.check.ignore);
  opts.result = {
    errors: []
  };

  glob('**/*.js', opts, function(err, files) {
    if (err) return done(err);

    opts.files = files;
    async.series({
      'missing dependencies': check.bind(null, opts, 'missing'),
      'extra dependencies': check.bind(null, opts, 'extra'),
      fmt: fmt.bind(null, opts),
      lint: lint.bind(null, opts)
    }, function(err) {
      if (err) {
        return done(err);
      }
      if (opts.result.errors.length > 0) {
        var error = new Error(format('%d check(s) failed', opts.result.errors.length));
        error.errors = opts.result.errors;
        return done(error);
      }
      return done();
    });
  });
};
<|endoftext|>


<commit_before>const hljs = require('highlight.js');
const fs = require('fs');
const css = require('css');
const he = require('he');
const getInstalledPath = require('get-installed-path');
const parse = require('parse-color');

const sourceFile = fs.readFileSync('index.js', 'utf8');
var htmlString = hljs.highlight('js', sourceFile).value;

const cssObject = loadStyle('darcula');
const conversionTable = generateHTMLToConsoleConversionTable(cssObject);

conversionTable.forEach(({ name, value }) => {
  const rgbArray = parse(value).rgb;
  const fixedRgbArray = rgbArray == undefined ? [255, 255, 255] : rgbArray;
  //'\x1b' +
  htmlString = htmlString
    .split(name)
    .join(
      '\x1b' +
        '[38;2;' +
        `${fixedRgbArray[0]};${fixedRgbArray[1]};${fixedRgbArray[2]}m`
    );
});
htmlString = htmlString.split('').join('\x1b[0m');
htmlString = htmlString.replace(//gm, '');
const unescapedHtmlString = he.unescape(htmlString);

console.log(unescapedHtmlString);

function generateHTMLToConsoleConversionTable(cssObject) {
  var lookupObject = [];
  cssObject.stylesheet.rules.forEach(rule => {
    if (rule.type == 'rule') {
      rule.declarations.forEach(declaration => {
        if (declaration.property == 'color') {
          rule.selectors.forEach(cssName => {
            const splitNames = cssName.split(' ');
            splitNames.forEach(splitCssName => {
              lookupObject.push({
                name: `<span class="${splitCssName.substr(1)}">`,
                value: `${declaration.value}`
              });
            });
          });
        }
      });
    }
  });
  return lookupObject;
}

function replaceAllEndSpansWithReset(code) {
  return code.replace('', '\x1b[0m');
}

function loadStyle(style) {
  const pathToStyle = _getPathToStyleFolder();
  const cssFileContents = fs.readFileSync(
    `${pathToStyle}/${style}.css`,
    'utf8'
  );
  return cssFileContents && css.parse(cssFileContents, {});
}

function _getPathToStyleFolder() {
  const path = getInstalledPath.sync('highlight.js', {
    local: true
  });
  return path + '/styles';
}
<commit_msg>Moved colour logic into table builder<commit_after>const hljs = require('highlight.js');
const fs = require('fs');
const css = require('css');
const he = require('he');
const getInstalledPath = require('get-installed-path');
const parse = require('parse-color');

const sourceFile = fs.readFileSync('index.js', 'utf8');
var htmlString = hljs.highlight('js', sourceFile).value;

const cssObject = loadStyle('darcula');
const conversionTable = generateHTMLToConsoleConversionTable(cssObject);

conversionTable.forEach(({ name, value }) => {
  htmlString = htmlString
    .split(name)
    .join('\x1b' + '[38;2;' + `${value[0]};${value[1]};${value[2]}m`);
});
htmlString = htmlString.split('').join('\x1b[0m');
htmlString = htmlString.replace(//gm, '');
const unescapedHtmlString = he.unescape(htmlString);

console.log(unescapedHtmlString);

function generateHTMLToConsoleConversionTable(cssObject) {
  var lookupObject = [];
  cssObject.stylesheet.rules.forEach(rule => {
    if (rule.type == 'rule') {
      rule.declarations.forEach(declaration => {
        if (declaration.property == 'color') {
          rule.selectors.forEach(cssName => {
            const splitNames = cssName.split(' ');
            splitNames.forEach(splitCssName => {
              const rgbArray = parse(declaration.value).rgb;
              const fixedRgbArray = rgbArray == undefined
                ? [255, 255, 255]
                : rgbArray;
              lookupObject.push({
                name: `<span class="${splitCssName.substr(1)}">`,
                value: rgbArray
              });
            });
          });
        }
      });
    }
  });
  return lookupObject;
}

function replaceAllEndSpansWithReset(code) {
  return code.replace('', '\x1b[0m');
}

function loadStyle(style) {
  const pathToStyle = _getPathToStyleFolder();
  const cssFileContents = fs.readFileSync(
    `${pathToStyle}/${style}.css`,
    'utf8'
  );
  return cssFileContents && css.parse(cssFileContents, {});
}

function _getPathToStyleFolder() {
  const path = getInstalledPath.sync('highlight.js', {
    local: true
  });
  return path + '/styles';
}
<|endoftext|>


<commit_before>/*!
 * colorz <https://github.com/akileez/colorz>
 *
 * Copyright (c) 2015 Keith Williams.
 * Licensed under the ISC license.
 */

var colorz = {}
var styles = {
  // modifiers
  reset         : [0, 0],
  bold          : [1, 22],
  dim           : [2, 22],
  italic        : [3, 23],
  underline     : [4, 24],
  inverse       : [7, 27],
  hidden        : [8, 28],
  strikethrough : [9, 29],
  // foregrounds
  black         : [30, 39],
  gray          : [30, 39],
  grey          : [30, 39],
  red           : [31, 39],
  green         : [32, 39],
  yellow        : [33, 39],
  blue          : [34, 39],
  magenta       : [35, 39],
  cyan          : [36, 39],
  white         : [37, 39],
  // bright foregrounds
  brBlack       : [90, 39],
  brGray        : [90, 39],
  brGrey        : [90, 39],
  brRed         : [91, 39],
  brGreen       : [92, 39],
  brYellow      : [93, 39],
  brBlue        : [94, 39],
  brMagenta     : [95, 39],
  brCyan        : [96, 39],
  brWhite       : [97, 39],
  // backgrounds
  bgBlack       : [40, 49],
  bgGray        : [40, 49],
  bgGrey        : [40, 49],
  bgRed         : [41, 49],
  bgGreen       : [42, 49],
  bgYellow      : [43, 49],
  bgBlue        : [44, 49],
  bgMagenta     : [45, 49],
  bgCyan        : [46, 49],
  bgWhite       : [47, 49],
  // bright backgrounds
  bbBlack       : [100, 49],
  bbGray        : [100, 49],
  bbGrey        : [100, 49],
  bbRed         : [101, 49],
  bbGreen       : [102, 49],
  bbYellow      : [103, 49],
  bbBlue        : [104, 49],
  bbMagenta     : [105, 49],
  bbCyan        : [106, 49],
  bbWhite       : [107, 49]
}

forEach(keys(styles), function (style) {
  var open = '\u001b[' + styles[style][0] + 'm'
  var clos = '\u001b[' + styles[style][1] + 'm'

  colorz[style] = function (msg) {
    return open + msg + clos
  }
})

function strip (str) {
  return str.replace(/(?:\u001b\[)\d+m/g, '')
}

function expose (style, str, noColor) {
  str = str || 'Hello World'
  return noColor
    ? style + ': ' + JSON.stringify(colorz[style](str))
    : style + ': '
      + JSON.stringify(colorz[style](str))
      .replace(/(\\u001b\[\d+m)/g, colorz[style](['$1']))
}

function keys (obj) {
  var result = []
  var key

  for (key in obj) {
    if (obj.hasOwnProperty(key)) result.push(key)
  }
  return result
}

function forEach (arr, fn) {
  var i = -1
  var len = arr.length

  while (++i < len) if (fn(arr[i], i, arr) === false) break
}

module.exports = colorz
module.exports.strip = strip
module.exports.expose = expose
<commit_msg>update index<commit_after>/*!
 * colorz <https://github.com/akileez/colorz>
 *
 * Copyright (c) 2015 Keith Williams.
 * Licensed under the ISC license.
 */

var colorz = {}
var styles = {
  // modifiers
  reset         : [0, 0],
  bold          : [1, 22],
  dim           : [2, 22],
  italic        : [3, 23],
  underline     : [4, 24],
  inverse       : [7, 27],
  hidden        : [8, 28],
  strikethrough : [9, 29],
  // foregrounds
  black         : [30, 39],
  gray          : [30, 39],
  grey          : [30, 39],
  red           : [31, 39],
  green         : [32, 39],
  yellow        : [33, 39],
  blue          : [34, 39],
  magenta       : [35, 39],
  cyan          : [36, 39],
  white         : [37, 39],
  // bright foregrounds
  brBlack       : [90, 39],
  brGray        : [90, 39],
  brGrey        : [90, 39],
  brRed         : [91, 39],
  brGreen       : [92, 39],
  brYellow      : [93, 39],
  brBlue        : [94, 39],
  brMagenta     : [95, 39],
  brCyan        : [96, 39],
  brWhite       : [97, 39],
  // backgrounds
  bgBlack       : [40, 49],
  bgGray        : [40, 49],
  bgGrey        : [40, 49],
  bgRed         : [41, 49],
  bgGreen       : [42, 49],
  bgYellow      : [43, 49],
  bgBlue        : [44, 49],
  bgMagenta     : [45, 49],
  bgCyan        : [46, 49],
  bgWhite       : [47, 49],
  // bright backgrounds
  bbBlack       : [100, 49],
  bbGray        : [100, 49],
  bbGrey        : [100, 49],
  bbRed         : [101, 49],
  bbGreen       : [102, 49],
  bbYellow      : [103, 49],
  bbBlue        : [104, 49],
  bbMagenta     : [105, 49],
  bbCyan        : [106, 49],
  bbWhite       : [107, 49]
}

forEach(keys(styles), function (style) {
  var open = '\u001b[' + styles[style][0] + 'm'
  var clos = '\u001b[' + styles[style][1] + 'm'

  colorz[style] = function (msg) {
    return open + msg + clos
  }
})

function strip (str) {
  return str.replace(/(?:\u001b\[)\d+m/g, '')
}

function expose (style, str, noColor) {
  if (typeof str === 'boolean') {
    noColor = str
    str = 'Hello World'
  }

  str = str || 'Hello World'

  return noColor
    ? style + ': ' + JSON.stringify(colorz[style](str))
    : style + ': '
      + JSON.stringify(colorz[style](str))
      .replace(/(\\u001b\[\d+m)/g, colorz[style](['$1']))
}

function keys (obj) {
  var result = []
  var key

  for (key in obj) {
    if (obj.hasOwnProperty(key)) result.push(key)
  }
  return result
}

function forEach (arr, fn) {
  var i = -1
  var len = arr.length

  while (++i < len) if (fn(arr[i], i, arr) === false) break
}

module.exports = colorz
module.exports.strip = strip
module.exports.expose = expose
<|endoftext|>


<commit_before>//     keymaster.js
//     (c) 2011 Thomas Fuchs
//     keymaster.js may be freely distributed under the MIT license.

;(function(global){
  var k,
    _handlers = {},
    _mods = { 16: false, 18: false, 17: false, 91: false },
    _scope = 'all',
    // modifier keys
    _MODIFIERS = {
      '⇧': 16, shift: 16,
      option: 18, '⌥': 18, alt: 18,
      ctrl: 17, control: 17,
      command: 91, '⌘': 91
    },
    // special keys
    _MAP = {
      backspace: 8, tab: 9, clear: 12,
      enter: 13, 'return': 13,
      esc: 27, escape: 27, space: 32,
      left: 37, up: 38,
      right: 39, down: 40,
      del: 46, 'delete': 46,
      home: 36, end: 35,
      pageup: 33, pagedown: 34,
      ',': 188, '.': 190, '/': 191,
      '`': 192, '-': 189, '=': 187,
      ';': 186, '\'': 222,
      '[': 219, ']': 221, '\\': 220
    };

  for(k=1;k<20;k++) _MODIFIERS['f'+k] = 111+k;

  // IE doesn't support Array#indexOf, so have a simple replacement
  function index(array, item){
    var i = array.length;
    while(i--) if(array[i]===item) return i;
    return -1;
  }

  // handle keydown event
  function dispatch(event){
    var key, tagName, handler, k, i, modifiersMatch;
    tagName = (event.target || event.srcElement).tagName;
    key = event.keyCode;

    // if a modifier key, set the key.<modifierkeyname> property to true and return
    if(key == 93 || key == 224) key = 91; // right command on webkit, command on Gecko
    if(key in _mods) {
      _mods[key] = true;
      // 'assignKey' from inside this closure is exported to window.key
      for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = true;
      return;
    }

    // ignore keypressed in any elements that support keyboard data input
//     if (tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA') return;

    // abort if no potentially matching shortcuts found
    if (!(key in _handlers)) return;

    // for each potential shortcut
    for (i = 0; i < _handlers[key].length; i++) {
      handler = _handlers[key][i];

      // see if it's in the current scope
      if(handler.scope == _scope || handler.scope == 'all'){
        // check if modifiers match if any
        modifiersMatch = handler.mods.length > 0;
        for(k in _mods)
          if((!_mods[k] && index(handler.mods, +k) > -1) ||
            (_mods[k] && index(handler.mods, +k) == -1)) modifiersMatch = false;
        // call the handler and stop the event if neccessary
        if((handler.mods.length == 0 && !_mods[16] && !_mods[18] && !_mods[17] && !_mods[91]) || modifiersMatch){
          if(handler.method(event, handler)===false){
            if(event.preventDefault) event.preventDefault();
              else event.returnValue = false;
            if(event.stopPropagation) event.stopPropagation();
            if(event.cancelBubble) event.cancelBubble = true;
          }
        }
      }
	}
  };

  // unset modifier keys on keyup
  function clearModifier(event){
    var key = event.keyCode, k;
    if(key == 93 || key == 224) key = 91;
    if(key in _mods) {
      _mods[key] = false;
      for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = false;
    }
  };

  // parse and assign shortcut
  function assignKey(key, scope, method){
    var keys, mods, i, mi;
    if (method === undefined) {
      method = scope;
      scope = 'all';
    }
    key = key.replace(/\s/g,'');
    keys = key.split(',');

    if((keys[keys.length-1])=='')
      keys[keys.length-2] += ',';
    // for each shortcut
    for (i = 0; i < keys.length; i++) {
      // set modifier keys if any
      mods = [];
      key = keys[i].split(/-|\+/);
      if(key.length > 1){
        mods = key.slice(0,key.length-1);
        for (mi = 0; mi < mods.length; mi++)
          mods[mi] = _MODIFIERS[mods[mi].toLowerCase()];
        key = [key[key.length-1]];
      }
      // convert to keycode and...
      key = key[0]
      key = _MAP[key] || key.toUpperCase().charCodeAt(0);
      // ...store handler
      if (!(key in _handlers)) _handlers[key] = [];
      _handlers[key].push({ shortcut: keys[i], scope: scope, method: method, key: keys[i], mods: mods });
    }
  };

  // initialize key.<modifier> to false
  for(k in _MODIFIERS) assignKey[k] = false;

  // set current scope (default 'all')
  function setScope(scope){ _scope = scope || 'all' };

  // cross-browser events
  function addEvent(object, event, method) {
    if (object.addEventListener)
      object.addEventListener(event, method, false);
    else if(object.attachEvent)
      object.attachEvent('on'+event, function(){ method(window.event) });
  };

  // set the handlers globally on document
  addEvent(document, 'keydown', dispatch);
  addEvent(document, 'keyup', clearModifier);

  // set window.key and window.key.setScope
  global.key = assignKey;
  global.key.setScope = setScope;

  if(typeof module !== 'undefined') module.exports = global.key;

})(this);
<commit_msg>blur matters<commit_after>//     keymaster.js
//     (c) 2011 Thomas Fuchs
//     keymaster.js may be freely distributed under the MIT license.

;(function(global){
  var k,
    _handlers = {},
    _mods = { 16: false, 18: false, 17: false, 91: false },
    _scope = 'all',
    // modifier keys
    _MODIFIERS = {
      '⇧': 16, shift: 16,
      option: 18, '⌥': 18, alt: 18,
      ctrl: 17, control: 17,
      command: 91, '⌘': 91
    },
    // special keys
    _MAP = {
      backspace: 8, tab: 9, clear: 12,
      enter: 13, 'return': 13,
      esc: 27, escape: 27, space: 32,
      left: 37, up: 38,
      right: 39, down: 40,
      del: 46, 'delete': 46,
      home: 36, end: 35,
      pageup: 33, pagedown: 34,
      ',': 188, '.': 190, '/': 191,
      '`': 192, '-': 189, '=': 187,
      ';': 186, '\'': 222,
      '[': 219, ']': 221, '\\': 220
    };

  for(k=1;k<20;k++) _MODIFIERS['f'+k] = 111+k;

  // IE doesn't support Array#indexOf, so have a simple replacement
  function index(array, item){
    var i = array.length;
    while(i--) if(array[i]===item) return i;
    return -1;
  }

  // handle keydown event
  function dispatch(event){
    var key, tagName, handler, k, i, modifiersMatch;
    tagName = (event.target || event.srcElement).tagName;
    key = event.keyCode;

    // if a modifier key, set the key.<modifierkeyname> property to true and return
    if(key == 93 || key == 224) key = 91; // right command on webkit, command on Gecko
    if(key in _mods) {
      _mods[key] = true;
      // 'assignKey' from inside this closure is exported to window.key
      for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = true;
      return;
    }

    // ignore keypressed in any elements that support keyboard data input
//     if (tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA') return;

    // abort if no potentially matching shortcuts found
    if (!(key in _handlers)) return;

    // for each potential shortcut
    for (i = 0; i < _handlers[key].length; i++) {
      handler = _handlers[key][i];

      // see if it's in the current scope
      if(handler.scope == _scope || handler.scope == 'all'){
        // check if modifiers match if any
        modifiersMatch = handler.mods.length > 0;
        for(k in _mods)
          if((!_mods[k] && index(handler.mods, +k) > -1) ||
            (_mods[k] && index(handler.mods, +k) == -1)) modifiersMatch = false;
        // call the handler and stop the event if neccessary
        if((handler.mods.length == 0 && !_mods[16] && !_mods[18] && !_mods[17] && !_mods[91]) || modifiersMatch){
          if(handler.method(event, handler)===false){
            if(event.preventDefault) event.preventDefault();
              else event.returnValue = false;
            if(event.stopPropagation) event.stopPropagation();
            if(event.cancelBubble) event.cancelBubble = true;
          }
        }
      }
	}
  };

  // unset modifier keys on keyup
  function clearModifier(event){
    var key = event.keyCode, k;
    if(key == 93 || key == 224) key = 91;
    if(key in _mods) {
      _mods[key] = false;
      for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = false;
    }
  };

  // parse and assign shortcut
  function assignKey(key, scope, method){
    var keys, mods, i, mi;
    if (method === undefined) {
      method = scope;
      scope = 'all';
    }
    key = key.replace(/\s/g,'');
    keys = key.split(',');

    if((keys[keys.length-1])=='')
      keys[keys.length-2] += ',';
    // for each shortcut
    for (i = 0; i < keys.length; i++) {
      // set modifier keys if any
      mods = [];
      key = keys[i].split(/-|\+/);
      if(key.length > 1){
        mods = key.slice(0,key.length-1);
        for (mi = 0; mi < mods.length; mi++)
          mods[mi] = _MODIFIERS[mods[mi].toLowerCase()];
        key = [key[key.length-1]];
      }
      // convert to keycode and...
      key = key[0]
      key = _MAP[key] || key.toUpperCase().charCodeAt(0);
      // ...store handler
      if (!(key in _handlers)) _handlers[key] = [];
      _handlers[key].push({ shortcut: keys[i], scope: scope, method: method, key: keys[i], mods: mods });
    }
  };

  // initialize key.<modifier> to false
  for(k in _MODIFIERS) assignKey[k] = false;

  // set current scope (default 'all')
  function setScope(scope){ _scope = scope || 'all' };

  // cross-browser events
  function addEvent(object, event, method) {
    if (object.addEventListener)
      object.addEventListener(event, method, false);
    else if(object.attachEvent)
      object.attachEvent('on'+event, function(){ method(window.event) });
  };

  // set the handlers globally on document
  addEvent(document, 'keydown', dispatch);
  addEvent(document, 'keyup', clearModifier);
  addEvent(document, 'blur', clearModifier);

  // set window.key and window.key.setScope
  global.key = assignKey;
  global.key.setScope = setScope;

  if(typeof module !== 'undefined') module.exports = global.key;

})(this);
<|endoftext|>


<commit_before>var postcss = require('postcss');
var valueParser = require('postcss-value-parser');
var colorUtil = require('color');

var rProp = /(^background|-image)$/;
var rGradient = /-gradient/;
var rTransparent = /\btransparent\b/;
var rHsl = /^hsla?$/;

var errorString = 'Cannot calculate a stop position for `transparent` value. Please use explicit stop positions.';

// ----- UTILITY FUNCTIONS -----

function hasGradient(str) {
    return rGradient.test(str);
}

function hasTransparent(str) {
    return rTransparent.test(str);
}

function isHsl(str) {
    return rHsl.test(str);
}

function isCalc(node) {
    return node && node.type === 'function' && node.value === 'calc';
}

function isTransparentStop(stop) {
    return !!stop.colorNode && stop.colorNode.type === 'word' && stop.colorNode.value === 'transparent';
}

function getColor(node, logErrors) {
    var ret;
    try {
        ret = colorUtil(valueParser.stringify(node));
    } catch (e) {
        ret = false;
        if (logErrors) {
            console.warn(e);
        }
    }
    return ret;
}

function unitValue(node) {
    return node ? valueParser.unit(node.value) : false;
}

/**
 * Generate a range of evenly-spaced numbers between start and end values (inclusive)
 */
function midRange(start, end, count) {
    count = Math.max(+count || 0, 2); // Force a number greater than 1 (must have at least start/end values)
    count -= 1; // Makes the maths easier
    var diff = end - start;
    var incr = diff / count;
    var ret = [];
    for (var i = 0; i <= count; i++) {
        ret.push(start + incr * i);
    }
    return ret;
}

function round(num, precision) {
    var exp = Math.pow(10, precision);
    return Math.round(num * exp) / exp;
}

// ----- DOMAIN OBJECT: COLOR STOP -----

function ColorStop(nodes) {
    this.parent = null;
    nodes = nodes || {};
    this.beforeNode    = nodes.beforeNode;
    this.colorNode     = nodes.colorNode;
    this.separatorNode = nodes.separatorNode;
    this.positionNode  = nodes.positionNode;
    this.parsePosition();
}

ColorStop.prototype.nodes = function () {
    var nodes = [];
    if (this.beforeNode)    nodes.push(this.beforeNode);
    if (this.colorNode)     nodes.push(this.colorNode);
    if (this.separatorNode) nodes.push(this.separatorNode);
    if (this.positionNode)  nodes.push(this.positionNode);
    return nodes;
};

ColorStop.prototype.clone = function () {
    var nodes = {};
    ['before', 'color', 'separator', 'position'].forEach(function (prop) {
        var key = prop + 'Node';
        if (this[key]) {
            nodes[key] = JSON.parse(JSON.stringify(this[key]));
        }
    }, this);
    return new ColorStop(nodes);
};

ColorStop.prototype.setColor = function (colorString) {
    if (!this.colorNode) {
        this.colorNode = {};
        if (this.parent) {
            this.parent.syncNodes();
        }
    }
    this.colorNode.type = 'word';
    this.colorNode.value = colorString;
};

ColorStop.prototype.setPosition = function (positionString, unit) {
    if (unit !== undefined) {
        positionString = '' + positionString + unit;
    }
    var isDirty = false;
    if (!this.separatorNode) {
        this.separatorNode = { type: 'space', value: ' ' };
        isDirty = true;
    }
    if (!this.positionNode) {
        this.positionNode = {};
        isDirty = true;
    }
    if (isDirty && this.parent) {
        this.parent.syncNodes();
    }
    this.positionNode.type = 'word';
    this.positionNode.value = positionString;
    this.parsePosition();
};

ColorStop.prototype.parsePosition = function () {
    var parsed = unitValue(this.positionNode);
    if (parsed) {
        this.positionNumber = +parsed.number || 0;
        this.positionUnit = parsed.unit;
    } else {
        this.positionNumber = undefined;
        this.positionUnit = isCalc(this.positionNode) ? 'calc' : undefined;
    }
};

ColorStop.prototype.getTransparentColor = function () {
    var node = this.colorNode;
    if (!node) {
        return 'rgba(0, 0, 0, 0)';
    }
    var parsed = getColor(node, true);
    parsed.alpha(0);
    // Try to match the input format as much as possible
    var fn = 'rgbString';
    if (node.type === 'function' && isHsl(node.value)) {
        fn = 'hslString';
    }
    return parsed[fn]();
};

// ----- DOMAIN OBJECT: GRADIENT -----

function Gradient(parsedNode) {
    this.node = {};
    this.preludeNodes = [];
    this.stops = [];
    this.setNode(parsedNode);

    this._actionQueue = [];
    this._walking = false;
}

Gradient.prototype.setNode = function (node) {
    this.node = node;
    var stopList = this.stops = [];
    if (node.nodes) {
        var curStop = new ColorStop();
        curStop.parent = this;
        var isPrelude = false;
        var isFirst = true;
        node.nodes.forEach(function (subNode) {
            // Dividers (commas) define the end of a stop
            if (subNode.type === 'div') {
                if (!isPrelude) {
                    stopList.push(curStop);
                    curStop = new ColorStop();
                    curStop.parent = this;
                    curStop.beforeNode = subNode;
                }
                isPrelude = false;
                return;
            }
            // Work out if the "stop" is actually prelude matter (angle/size definitions)
            if (isFirst) {
                isFirst = false;
                var color = getColor(subNode);
                if (!color) {
                    isPrelude = true;
                }
            }
            if (isPrelude) {
                this.preludeNodes.push(subNode);
            // Spaces are value separators
            } else if (subNode.type === 'space') {
                curStop.separatorNode = subNode;
            // Function or word is either a colour or a stop position
            } else if (subNode.type === 'function' || subNode.type === 'word') {
                if (curStop.colorNode) {
                    curStop.positionNode = subNode;
                    curStop.parsePosition();
                } else {
                    curStop.colorNode = subNode;
                }
            }
        }, this);
        if (curStop.colorNode) {
            stopList.push(curStop);
        }
    }
};

Gradient.prototype.walkStops = function (fn) {
    this._walking = true;
    this.stops.forEach(fn);
    this._walking = false;
    if (this._actionQueue.length) {
        this._actionQueue.forEach(function (action) {
            action.call(this);
        }, this);
        this._actionQueue = [];
        this.syncNodes();
    }
};

Gradient.prototype.insertStopAfter = function (newStop, afterStop) {
    var action = function () {
        // Guarantee that the new stop has a comma node before it
        newStop.beforeNode = { type: 'div', value: ',', before: '', after: ' ' };

        // Add stop to stops list
        var stopIndex = this.stops.indexOf(afterStop);
        if (stopIndex === -1) {
            stopIndex = this.stops.length - 1;
        }
        this.stops.splice(stopIndex + 1, 0, newStop);
    };
    if (this._walking) {
        this._actionQueue.push(action);
    } else {
        action();
    }
};

Gradient.prototype.syncNodes = function () {
    var stopNodes = this.stops.reduce(function (memo, stop) {
        return memo.concat(stop.nodes());
    }, []);
    this.node.nodes = [].concat(this.preludeNodes, stopNodes);
};

// ----- MAIN ACTIONS -----

/**
 * Try to calculate a new stop position exactly halfway between two other stops.
 */
function calculateStopPositions(stop1, stop2, count) {
    var good = function (values, unit) {
        return { values: values, unit: unit };
    };
    var bad = function (warning) {
        return { values: false, unit: '', warning: warning };
    };

    // Exit early if either value is calc()
    if (stop1 && isCalc(stop1.positionNode) || stop2 && isCalc(stop2.positionNode)) {
        return bad(errorString);
    }

    var startPos, endPos, baseUnit;
    var hasStartPos = true;
    var hasEndPos = true;

    var pos1 = stop1 && unitValue(stop1.positionNode);
    var pos2 = stop2 && unitValue(stop2.positionNode);
    if (!pos1) {
        hasStartPos = false;
        pos1 = { number: '0', unit: '%' };
    } else {
        count++;
    }
    if (!pos2) {
        hasEndPos = false;
        pos2 = { number: '100', unit: '%' };
    } else {
        count++;
    }

    // Check if missing stops can be calculated
    if (pos1.unit !== pos2.unit) {
        return bad(errorString);
    }
    startPos = +pos1.number || 0;
    endPos = +pos2.number || 0;
    baseUnit = pos1.unit;

    // Generate as many missing positions as required
    var positions = midRange(startPos, endPos, count);
    // Take off any known positions
    if (hasStartPos) {
        positions.shift();
    }
    if (hasEndPos) {
        positions.pop();
    }

    return good(positions, baseUnit);
}

function assignStopPositions(gradient, warnings) {
    var stops = gradient.stops;
    var stop, beforeStop, midStops, afterStop, si, checkStop, positions;
    for (var i = 0, ii = stops.length; i < ii; i++) {
        stop = stops[i];
        if (stop.positionUnit === undefined) {
            beforeStop = stops[i - 1];
            midStops = [stop];
            afterStop = undefined;
            for (si = i + 1; si < ii; si++) {
                checkStop = stops[si];
                if (checkStop.positionNumber === undefined) {
                    midStops.push(checkStop);
                } else {
                    afterStop = checkStop;
                    break;
                }
            }
            // Check for missing values
            var shouldWarn = midStops.some(function (s) {
                return isTransparentStop(s);
            });
            positions = calculateStopPositions(beforeStop, afterStop, midStops.length);
            if (positions.warning) {
                if (shouldWarn) {
                    warnings.push(positions.warning);
                }
                i += midStops.length;
            } else {
                positions.values && positions.values.forEach(function (value, vi) {
                    midStops[vi].positionNumber = value;
                    midStops[vi].positionUnit = positions.unit;
                });
            }
        }
    }
}

function fixGradient(imageNode, warnings) {
    var gradient = new Gradient(imageNode);

    // Run through each stop and pre-calculate any missing stop positions (where possible)
    assignStopPositions(gradient, warnings);

    // Fix transparent values
    gradient.walkStops(function (stop, i) {
        if (isTransparentStop(stop)) {
            var prevStop = gradient.stops[i - 1];
            var nextStop = gradient.stops[i + 1];
            // (red, transparent)
            if (prevStop && !nextStop) {
                stop.setColor(prevStop.getTransparentColor());
            // (transparent, red)
            } else if (!prevStop && nextStop) {
                stop.setColor(nextStop.getTransparentColor());
            // (red, transparent, blue)
            } else if (prevStop && nextStop) {
                // TODO: Skip this section if prev colour and next colour are the same (#2)
                if (!stop.positionNode) {
                    // Position number/unit should have been pre-calculated.
                    // If it's missing, the position can't be worked out, so nothing more can be done for this stop.
                    if (!stop.positionUnit) {
                        return;
                    }
                    stop.setPosition(round(stop.positionNumber, 2), stop.positionUnit);
                }
                // Create an extra stop at the same position
                var extraStop = stop.clone();
                stop.setColor(prevStop.getTransparentColor());
                extraStop.setColor(nextStop.getTransparentColor());
                gradient.insertStopAfter(extraStop, stop);
            }
        }
    });
}

function fixAllGradients(value) {
    var parsed = valueParser(value);
    var warnings = [];
    parsed.walk(function (node) {
        if (node.type === 'function' && hasGradient(node.value)) {
            fixGradient(node, warnings);
            return false;
        }
    });
    return {
        value: parsed.toString(),
        warnings: warnings
    };
}

module.exports = postcss.plugin('postcss-gradient-transparency-fix', function (opts) {
    opts = opts || {};

    return function (css, result) {
        css.walkDecls(rProp, function (decl) {
            if (hasGradient(decl.value) && hasTransparent(decl.value)) {
                var fixedValue = fixAllGradients(decl.value);
                decl.value = fixedValue.value;
                fixedValue.warnings.forEach(function (warning) {
                    decl.warn(result, warning);
                });
            }
        });
    };
});

module.exports.ERROR_STOP_POSITION = errorString;
<commit_msg>Better ColorStop cloning that includes the parent Gradient<commit_after>var postcss = require('postcss');
var valueParser = require('postcss-value-parser');
var colorUtil = require('color');

var rProp = /(^background|-image)$/;
var rGradient = /-gradient/;
var rTransparent = /\btransparent\b/;
var rHsl = /^hsla?$/;

var errorString = 'Cannot calculate a stop position for `transparent` value. Please use explicit stop positions.';

// ----- UTILITY FUNCTIONS -----

function hasGradient(str) {
    return rGradient.test(str);
}

function hasTransparent(str) {
    return rTransparent.test(str);
}

function isHsl(str) {
    return rHsl.test(str);
}

function isCalc(node) {
    return node && node.type === 'function' && node.value === 'calc';
}

function isTransparentStop(stop) {
    return !!stop.colorNode && stop.colorNode.type === 'word' && stop.colorNode.value === 'transparent';
}

function getColor(node, logErrors) {
    var ret;
    try {
        ret = colorUtil(valueParser.stringify(node));
    } catch (e) {
        ret = false;
        if (logErrors) {
            console.warn(e);
        }
    }
    return ret;
}

function unitValue(node) {
    return node ? valueParser.unit(node.value) : false;
}

/**
 * Generate a range of evenly-spaced numbers between start and end values (inclusive)
 */
function midRange(start, end, count) {
    count = Math.max(+count || 0, 2); // Force a number greater than 1 (must have at least start/end values)
    count -= 1; // Makes the maths easier
    var diff = end - start;
    var incr = diff / count;
    var ret = [];
    for (var i = 0; i <= count; i++) {
        ret.push(start + incr * i);
    }
    return ret;
}

function round(num, precision) {
    var exp = Math.pow(10, precision);
    return Math.round(num * exp) / exp;
}

// ----- DOMAIN OBJECT: COLOR STOP -----

function ColorStop() {
    this.parent = null;
    this.beforeNode = null;
    this.colorNode = null;
    this.separatorNode = null;
    this.positionNode = null;
    this.parsePosition();
}

ColorStop.prototype.nodes = function () {
    var nodes = [];
    if (this.beforeNode)    nodes.push(this.beforeNode);
    if (this.colorNode)     nodes.push(this.colorNode);
    if (this.separatorNode) nodes.push(this.separatorNode);
    if (this.positionNode)  nodes.push(this.positionNode);
    return nodes;
};

ColorStop.prototype.clone = function () {
    var stop = new ColorStop();
    var keys = [
        'parent', 'beforeNode', 'colorNode', 'separatorNode', 'positionNode'
    ];
    keys.forEach(function (key) {
        if (this[key] !== undefined) {
            var value = this[key];
            stop[key] = key === 'parent' ? value : JSON.parse(JSON.stringify(value));
        }
    }, this);
    return stop;
};

ColorStop.prototype.setColor = function (colorString) {
    if (!this.colorNode) {
        this.colorNode = {};
        if (this.parent) {
            this.parent.syncNodes();
        }
    }
    this.colorNode.type = 'word';
    this.colorNode.value = colorString;
};

ColorStop.prototype.setPosition = function (positionString, unit) {
    if (unit !== undefined) {
        positionString = '' + positionString + unit;
    }
    var isDirty = false;
    if (!this.separatorNode) {
        this.separatorNode = { type: 'space', value: ' ' };
        isDirty = true;
    }
    if (!this.positionNode) {
        this.positionNode = {};
        isDirty = true;
    }
    if (isDirty && this.parent) {
        this.parent.syncNodes();
    }
    this.positionNode.type = 'word';
    this.positionNode.value = positionString;
    this.parsePosition();
};

ColorStop.prototype.parsePosition = function () {
    var parsed = unitValue(this.positionNode);
    if (parsed) {
        this.positionNumber = +parsed.number || 0;
        this.positionUnit = parsed.unit;
    } else {
        this.positionNumber = undefined;
        this.positionUnit = isCalc(this.positionNode) ? 'calc' : undefined;
    }
};

ColorStop.prototype.getTransparentColor = function () {
    var node = this.colorNode;
    if (!node) {
        return 'rgba(0, 0, 0, 0)';
    }
    var parsed = getColor(node, true);
    parsed.alpha(0);
    // Try to match the input format as much as possible
    var fn = 'rgbString';
    if (node.type === 'function' && isHsl(node.value)) {
        fn = 'hslString';
    }
    return parsed[fn]();
};

// ----- DOMAIN OBJECT: GRADIENT -----

function Gradient(parsedNode) {
    this.node = {};
    this.preludeNodes = [];
    this.stops = [];
    this.setNode(parsedNode);

    this._actionQueue = [];
    this._walking = false;
}

Gradient.prototype.setNode = function (node) {
    this.node = node;
    var stopList = this.stops = [];
    if (node.nodes) {
        var curStop = new ColorStop();
        curStop.parent = this;
        var isPrelude = false;
        var isFirst = true;
        node.nodes.forEach(function (subNode) {
            // Dividers (commas) define the end of a stop
            if (subNode.type === 'div') {
                if (!isPrelude) {
                    stopList.push(curStop);
                    curStop = new ColorStop();
                    curStop.parent = this;
                    curStop.beforeNode = subNode;
                }
                isPrelude = false;
                return;
            }
            // Work out if the "stop" is actually prelude matter (angle/size definitions)
            if (isFirst) {
                isFirst = false;
                var color = getColor(subNode);
                if (!color) {
                    isPrelude = true;
                }
            }
            if (isPrelude) {
                this.preludeNodes.push(subNode);
            // Spaces are value separators
            } else if (subNode.type === 'space') {
                curStop.separatorNode = subNode;
            // Function or word is either a colour or a stop position
            } else if (subNode.type === 'function' || subNode.type === 'word') {
                if (curStop.colorNode) {
                    curStop.positionNode = subNode;
                    curStop.parsePosition();
                } else {
                    curStop.colorNode = subNode;
                }
            }
        }, this);
        if (curStop.colorNode) {
            stopList.push(curStop);
        }
    }
};

Gradient.prototype.walkStops = function (fn) {
    this._walking = true;
    this.stops.forEach(fn);
    this._walking = false;
    if (this._actionQueue.length) {
        this._actionQueue.forEach(function (action) {
            action.call(this);
        }, this);
        this._actionQueue = [];
        this.syncNodes();
    }
};

Gradient.prototype.insertStopAfter = function (newStop, afterStop) {
    var action = function () {
        // Guarantee that the new stop has a comma node before it
        newStop.beforeNode = { type: 'div', value: ',', before: '', after: ' ' };

        // Add stop to stops list
        var stopIndex = this.stops.indexOf(afterStop);
        if (stopIndex === -1) {
            stopIndex = this.stops.length - 1;
        }
        this.stops.splice(stopIndex + 1, 0, newStop);
    };
    if (this._walking) {
        this._actionQueue.push(action);
    } else {
        action();
    }
};

Gradient.prototype.syncNodes = function () {
    var stopNodes = this.stops.reduce(function (memo, stop) {
        return memo.concat(stop.nodes());
    }, []);
    this.node.nodes = [].concat(this.preludeNodes, stopNodes);
};

// ----- MAIN ACTIONS -----

/**
 * Try to calculate a new stop position exactly halfway between two other stops.
 */
function calculateStopPositions(stop1, stop2, count) {
    var good = function (values, unit) {
        return { values: values, unit: unit };
    };
    var bad = function (warning) {
        return { values: false, unit: '', warning: warning };
    };

    // Exit early if either value is calc()
    if (stop1 && isCalc(stop1.positionNode) || stop2 && isCalc(stop2.positionNode)) {
        return bad(errorString);
    }

    var startPos, endPos, baseUnit;
    var hasStartPos = true;
    var hasEndPos = true;

    var pos1 = stop1 && unitValue(stop1.positionNode);
    var pos2 = stop2 && unitValue(stop2.positionNode);
    if (!pos1) {
        hasStartPos = false;
        pos1 = { number: '0', unit: '%' };
    } else {
        count++;
    }
    if (!pos2) {
        hasEndPos = false;
        pos2 = { number: '100', unit: '%' };
    } else {
        count++;
    }

    // Check if missing stops can be calculated
    if (pos1.unit !== pos2.unit) {
        return bad(errorString);
    }
    startPos = +pos1.number || 0;
    endPos = +pos2.number || 0;
    baseUnit = pos1.unit;

    // Generate as many missing positions as required
    var positions = midRange(startPos, endPos, count);
    // Take off any known positions
    if (hasStartPos) {
        positions.shift();
    }
    if (hasEndPos) {
        positions.pop();
    }

    return good(positions, baseUnit);
}

function assignStopPositions(gradient, warnings) {
    var stops = gradient.stops;
    var stop, beforeStop, midStops, afterStop, si, checkStop, positions;
    for (var i = 0, ii = stops.length; i < ii; i++) {
        stop = stops[i];
        if (stop.positionUnit === undefined) {
            beforeStop = stops[i - 1];
            midStops = [stop];
            afterStop = undefined;
            for (si = i + 1; si < ii; si++) {
                checkStop = stops[si];
                if (checkStop.positionNumber === undefined) {
                    midStops.push(checkStop);
                } else {
                    afterStop = checkStop;
                    break;
                }
            }
            // Check for missing values
            var shouldWarn = midStops.some(function (s) {
                return isTransparentStop(s);
            });
            positions = calculateStopPositions(beforeStop, afterStop, midStops.length);
            if (positions.warning) {
                if (shouldWarn) {
                    warnings.push(positions.warning);
                }
                i += midStops.length;
            } else {
                positions.values && positions.values.forEach(function (value, vi) {
                    midStops[vi].positionNumber = value;
                    midStops[vi].positionUnit = positions.unit;
                });
            }
        }
    }
}

function fixGradient(imageNode, warnings) {
    var gradient = new Gradient(imageNode);

    // Run through each stop and pre-calculate any missing stop positions (where possible)
    assignStopPositions(gradient, warnings);

    // Fix transparent values
    gradient.walkStops(function (stop, i) {
        if (isTransparentStop(stop)) {
            var prevStop = gradient.stops[i - 1];
            var nextStop = gradient.stops[i + 1];
            // (red, transparent)
            if (prevStop && !nextStop) {
                stop.setColor(prevStop.getTransparentColor());
            // (transparent, red)
            } else if (!prevStop && nextStop) {
                stop.setColor(nextStop.getTransparentColor());
            // (red, transparent, blue)
            } else if (prevStop && nextStop) {
                // TODO: Skip this section if prev colour and next colour are the same (#2)
                if (!stop.positionNode) {
                    // Position number/unit should have been pre-calculated.
                    // If it's missing, the position can't be worked out, so nothing more can be done for this stop.
                    if (!stop.positionUnit) {
                        return;
                    }
                    stop.setPosition(round(stop.positionNumber, 2), stop.positionUnit);
                }
                // Create an extra stop at the same position
                var extraStop = stop.clone();
                stop.setColor(prevStop.getTransparentColor());
                extraStop.setColor(nextStop.getTransparentColor());
                gradient.insertStopAfter(extraStop, stop);
            }
        }
    });
}

function fixAllGradients(value) {
    var parsed = valueParser(value);
    var warnings = [];
    parsed.walk(function (node) {
        if (node.type === 'function' && hasGradient(node.value)) {
            fixGradient(node, warnings);
            return false;
        }
    });
    return {
        value: parsed.toString(),
        warnings: warnings
    };
}

module.exports = postcss.plugin('postcss-gradient-transparency-fix', function (opts) {
    opts = opts || {};

    return function (css, result) {
        css.walkDecls(rProp, function (decl) {
            if (hasGradient(decl.value) && hasTransparent(decl.value)) {
                var fixedValue = fixAllGradients(decl.value);
                decl.value = fixedValue.value;
                fixedValue.warnings.forEach(function (warning) {
                    decl.warn(result, warning);
                });
            }
        });
    };
});

module.exports.ERROR_STOP_POSITION = errorString;
<|endoftext|>


<commit_before>'use strict';

var allowedPattern,
    extensions,
    prevcount,
    watchlog,
    chokidar,
    watcher,
    allowed,
    ignored,
    count,
    cwd,
    fs;

if (process.argv.indexOf('--disable-devwatch') > -1) {
	return;
}

if (alchemy.settings.kill_on_file_change) {

	chokidar = alchemy.use('chokidar');

	if (!chokidar) {
		log.warn('Can not watch files because Chokidar is not installed');
		return;
	}

	fs = alchemy.use('fs');

	prevcount = 0;
	count = 0;

	ignored = /^app\/public\/views|^temp/;
	extensions = ['js', 'json'];
	cwd = process.cwd();

	// Get the extensions allowed to kill the server
	if (Array.isArray(alchemy.settings.kill_extensions)) {
		extensions = alchemy.settings.kill_extensions;
	}

	allowedPattern = '';

	// Go over every extensionin the array
	extensions.forEach(function eachExtension(extension) {

		if (allowedPattern) {
			allowedPattern += '|';
		}

		allowedPattern += '\\.' + extension + '$';
	});

	// Create the regex
	allowed = new RegExp(allowedPattern);

	watchlog = Function.throttle(function watchlog() {

		if (prevcount == count) {
			return;
		}

		log.warn(count, 'files are being monitored for changes');
		prevcount = count;
	}, 1500, false, true);

	// Start watching all the files, starting with the current working directory
	watcher = chokidar.watch(cwd, {ignored: function ignoreThisPath(_path) {

		var isAllowed,
		    depth,
		    path = _path,
		    stat,
		    file;

		// Ignore git folders
		if (~path.indexOf('.git')) {
			return true;
		}

		// Ignore non-stylesheet files in asset or public folders
		if (~path.indexOf('/assets/') || ~path.indexOf('/public/')) {
			if (path.indexOf('.') > -1 && !path.endsWith('.less') && !path.endsWith('.css') && !path.endsWith('.scss')) {
				return true;
			} else {
				isAllowed = true;
			}
		}

		// Skip some big module folders by default
		if (path.endsWith('/less') || path.endsWith('/caniuse-lite') || path.endsWith('/bcrypt') || path.endsWith('/node-sass') || path.endsWith('/mmmagic') || path.endsWith('/node-gyp') || path.endsWith('/lodash')) {
			return true;
		}

		watchlog();

		path = path.replace(cwd+'/', '');
		file = path.split('/');
		file = file[file.length-1];

		depth = path.count('/');

		if (depth > 7) {
			return false;
		}

		if (count > 4999) {
			if (count == 5000) {
				count++
				log.warn('Already watching 5000 files, not watching any more');
			}

			return false;
		}

		if (isAllowed == null) {
			// Only allow the specified extensions
			isAllowed = allowed.exec(file);
		}

		// If it's already false, return it
		if (!isAllowed) {
			// Only disallow if it's not a directory
			try {
				if (!fs.statSync(path).isDirectory()) {
					return true;
				}
			} catch (err) {
				// Ignore files that have been removed
				return true;
			}
		}

		// See if it's still allowed based on patterns to ignore
		isAllowed = !ignored.exec(path);

		// If it's still allowed, make sure it isn't 2 or more node_modules deep
		if (isAllowed && path.count('node_modules') > 1) {

			if (path.count('node_modules') == 2 && path.endsWith('node_modules')) {
				isAllowed = true;
			} else

			if (path.count('protoblast') || path.count('hawkejs')) {
				if (path.count('node_modules') > 2) {
					isAllowed = false;
				}
			} else {
				isAllowed = false;
			}
		}

		// If it's still allowed, increase the watch count
		if (isAllowed) {
			count++;
		}

		// Return if it should be ignored or not
		return !isAllowed;

	}, persistent: true});

	// Kill the server when any of the files change
	watcher.on('change', function onFileChange(path, stats) {

		// Skip hawkejs client file
		if (path.indexOf('hawkejs-client-side.js') > -1) {
			return false;
		}

		// Skip protoblast client files
		if (path.indexOf('protoblast/client-file') > -1) {
			return false;
		}

		// Also skip files in the temp directory
		if (path.indexOf('temp/') === 0) {
			return false;
		}

		// Skip assets or public files
		if (path.indexOf('/assets/') > -1 || path.indexOf('/public/') > -1) {

			if (path.endsWith('.css') || path.endsWith('.scss') || path.endsWith('.less')) {
				broadcastReload(path);
			}

			return false;
		}

		// Only allow defined extensions
		if (!allowed.exec(path)) {
			return false;
		}

		// Kill the process, run together with something like "forever" to restart
		die('Killing server because', JSON.stringify(path.replace(cwd + '/', '')), 'has been modified');
	});

	let broadcastReload = Function.throttle(function broadcastReload(path) {
		alchemy.broadcast('css_reload', path);
	}, 100, false, true);
}<commit_msg>Tweak devwatch so it works with plugins in the /plugins/ folder<commit_after>'use strict';

var allowedPattern,
    extensions,
    prevcount,
    watchlog,
    chokidar,
    watcher,
    allowed,
    ignored,
    count,
    cwd,
    fs;

if (process.argv.indexOf('--disable-devwatch') > -1) {
	return;
}

if (alchemy.settings.kill_on_file_change) {

	chokidar = alchemy.use('chokidar');

	if (!chokidar) {
		log.warn('Can not watch files because Chokidar is not installed');
		return;
	}

	fs = alchemy.use('fs');

	prevcount = 0;
	count = 0;

	ignored = /^app\/public\/views|^temp/;
	extensions = ['js', 'json'];
	cwd = process.cwd();

	// Get the extensions allowed to kill the server
	if (Array.isArray(alchemy.settings.kill_extensions)) {
		extensions = alchemy.settings.kill_extensions;
	}

	allowedPattern = '';

	// Go over every extensionin the array
	extensions.forEach(function eachExtension(extension) {

		if (allowedPattern) {
			allowedPattern += '|';
		}

		allowedPattern += '\\.' + extension + '$';
	});

	// Create the regex
	allowed = new RegExp(allowedPattern);

	watchlog = Function.throttle(function watchlog() {

		if (prevcount == count) {
			return;
		}

		log.warn(count, 'files are being monitored for changes');
		prevcount = count;
	}, 1500, false, true);

	// Start watching all the files, starting with the current working directory
	watcher = chokidar.watch(cwd, {ignored: function ignoreThisPath(_path) {

		var isAllowed,
		    depth,
		    path = _path,
		    stat,
		    file;

		// Ignore git folders
		if (~path.indexOf('.git')) {
			return true;
		}

		// Ignore non-stylesheet files in asset or public folders
		if (~path.indexOf('/assets/') || ~path.indexOf('/public/')) {
			if (path.indexOf('.') > -1 && !path.endsWith('.less') && !path.endsWith('.css') && !path.endsWith('.scss')) {
				return true;
			} else {
				isAllowed = true;
			}
		}

		// Skip some big module folders by default
		if (path.endsWith('/less') || path.endsWith('/caniuse-lite') || path.endsWith('/bcrypt') || path.endsWith('/node-sass') || path.endsWith('/mmmagic') || path.endsWith('/node-gyp') || path.endsWith('/lodash')) {
			return true;
		}

		watchlog();

		path = path.replace(cwd+'/', '');
		file = path.split('/');
		file = file[file.length-1];

		depth = path.count('/');

		if (depth > 7) {
			return false;
		}

		if (count > 4999) {
			if (count == 5000) {
				count++
				log.warn('Already watching 5000 files, not watching any more');
			}

			return false;
		}

		if (isAllowed == null) {
			// Only allow the specified extensions
			isAllowed = allowed.exec(file);
		}

		// If it's already false, return it
		if (!isAllowed) {
			// Only disallow if it's not a directory
			try {
				if (!fs.statSync(path).isDirectory()) {
					return true;
				}
			} catch (err) {
				// Ignore files that have been removed
				return true;
			}
		}

		// See if it's still allowed based on patterns to ignore
		isAllowed = !ignored.exec(path);

		if (isAllowed && path.count('/plugins/') == 1 && path.count('node_modules')) {
			isAllowed = false;
		}

		// If it's still allowed, make sure it isn't 2 or more node_modules deep
		if (isAllowed && path.count('node_modules') > 1) {

			if (path.count('node_modules') == 2 && path.endsWith('node_modules')) {
				isAllowed = true;
			} else if (path.count('protoblast') || path.count('hawkejs')) {
				if (path.count('node_modules') > 2) {
					isAllowed = false;
				}
			} else {
				isAllowed = false;
			}
		}

		// If it's still allowed, increase the watch count
		if (isAllowed) {
			count++;
		}

		// Return if it should be ignored or not
		return !isAllowed;

	}, persistent: true});

	// Kill the server when any of the files change
	watcher.on('change', function onFileChange(path, stats) {

		// Skip hawkejs client file
		if (path.indexOf('hawkejs-client-side.js') > -1) {
			return false;
		}

		// Skip protoblast client files
		if (path.indexOf('protoblast/client-file') > -1) {
			return false;
		}

		// Also skip files in the temp directory
		if (path.indexOf('temp/') === 0) {
			return false;
		}

		// Skip assets or public files
		if (path.indexOf('/assets/') > -1 || path.indexOf('/public/') > -1) {

			if (path.endsWith('.css') || path.endsWith('.scss') || path.endsWith('.less')) {
				broadcastReload(path);
			}

			return false;
		}

		// Only allow defined extensions
		if (!allowed.exec(path)) {
			return false;
		}

		// Kill the process, run together with something like "forever" to restart
		die('Killing server because', JSON.stringify(path.replace(cwd + '/', '')), 'has been modified');
	});

	let broadcastReload = Function.throttle(function broadcastReload(path) {
		alchemy.broadcast('css_reload', path);
	}, 100, false, true);
}<|endoftext|>