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

'use strict';

var is = require('is');
var path = require('path');
var join = path.join;
var dirname = path.dirname;
var relative = path.relative;
var util = require('util');
var colors = require('colors/safe');
var debug = require('debug')('gulp-css');

// The work cwd
var cwd = process.cwd();

// Set debug color use 6
debug.color = 2;

/**
 * Create a plugin
 * @param name
 * @param transport
 * @returns {Function}
 */

function plugin(name, transport){
  return function (vinyl, options){
    // debug
    debug('load plugin: %s', colors.cyan(name));
    // debug
    debug('read file: %s', colors.magenta(pathFromCwd(vinyl.path)));

    vinyl = transport(vinyl, options);

    return vinyl;
  };
}

/**
 * Normalize path
 * @param path
 * @returns {string}
 */

function normalize(path){
  path = path.replace(/\\+/g, '/');
  path = path.replace(/([^:/])\/+\//g, '$1/');
  path = path.replace(/(:)?\/{2,}/, '$1//');

  return path;
}

/**
 * Resolve a `relative` path base on `base` path
 * @param relative
 * @param vinyl
 * @param wwwroot
 * @returns {string}
 */

function resolve(relative, vinyl, wwwroot){
  var base;
  var absolute;

  // debug
  debug('resolve path: %s', colors.magenta(normalize(relative)));

  // resolve
  if (isAbsolute(relative)) {
    base = wwwroot;
    absolute = join(base, relative.substring(1));
  } else {
    base = dirname(vinyl.path);
    absolute = join(base, relative);

    // out of base, use wwwroot
    if (isRelative(absolute)) {
      base = wwwroot;
      absolute = join(base, relative);

      // out of wwwroot
      if (isOutBound(absolute, wwwroot)) {
        throwError('file: %s is out of bound of wwwroot: %s.', normalize(absolute), normalize(wwwroot));
      }
    }
  }

  // debug
  debug('of base path: %s', colors.magenta(pathFromCwd(base)));
  debug('to: %s', colors.magenta(pathFromCwd(absolute)));

  return absolute;
}

/**
 * Test path is relative path or not
 * @param path
 * @returns {boolean}
 */

function isRelative(path){
  return /^\.{1,2}[\\/]/.test(path);
}

/**
 * Test path is absolute path or not
 * @param path
 * @returns {boolean}
 */

function isAbsolute(path){
  return /^[\\/](?:[^\\/]+|$)/.test(path);
}

/**
 * Test path is local path or not
 * @param path
 * @returns {boolean}
 */

function isLocal(path){
  return !/^https?:\/\/|^\/\//.test(path) && !/^data:/.test(path);
}

/**
 * Test path is out of bound of base
 * @param path
 * @param base
 * @returns {boolean}
 */

function isOutBound(path, base){
  return /(?:^|[\\\/])\.\.(?:[\\\/]|$)/.test(relative(base, path));
}

/**
 * Get relative path from cwd
 * @param path
 * @returns {string}
 */

function pathFromCwd(path){
  return normalize(relative(cwd, path)) || './';
}

/**
 * Plugin error
 */

function throwError(){
  var slice = [].slice;
  var message = util.format
    .apply(null, slice.call(arguments));

  throw new Error(message);
}

/**
 * Node extend
 * Copyright 2011, John Resig
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * @fileoverview
 * Port of jQuery.extend that actually works on node.js
 */

function extend(){
  var target = arguments[0] || {};
  var i = 1;
  var length = arguments.length;
  var deep = false;
  var options, name, src, copy, copy_is_array, clone;

  // handle a deep copy situation
  if (typeof target === 'boolean') {
    deep = target;
    target = arguments[1] || {};
    // skip the boolean and the target
    i = 2;
  }

  // handle case when target is a string or something (possible in deep copy)
  if (typeof target !== 'object' && !is.fn(target)) {
    target = {};
  }

  for (; i < length; i++) {
    // only deal with non-null/undefined values
    options = arguments[i];

    if (options !== null) {
      if (typeof options === 'string') {
        options = options.split('');
      }

      // extend the base object
      for (name in options) {
        if (options.hasOwnProperty(name)) {
          src = target[name];
          copy = options[name];

          // prevent never-ending loop
          if (target === copy) {
            continue;
          }

          // recurse if we're merging plain objects or arrays
          if (deep && copy && (is.hash(copy) || (copy_is_array = Array.isArray(copy)))) {
            if (copy_is_array) {
              copy_is_array = false;
              clone = src && Array.isArray(src) ? src : [];
            } else {
              clone = src && is.hash(src) ? src : {};
            }

            // never move original objects, clone them
            target[name] = extend(deep, clone, copy);

            // don't bring in undefined values
          } else if (typeof copy !== 'undefined') {
            target[name] = copy;
          }
        }
      }
    }
  }

  // return the modified object
  return target;
}

/**
 * Exports module.
 */

module.exports.cwd = cwd;
module.exports.normalize = normalize;
module.exports.isRelative = isRelative;
module.exports.isAbsolute = isAbsolute;
module.exports.isLocal = isLocal;
module.exports.isOutBound = isOutBound;
module.exports.resolve = resolve;
module.exports.pathFromCwd = pathFromCwd;
module.exports.throwError = throwError;
module.exports.extend = extend;
module.exports.colors = colors;
module.exports.debug = debug;
module.exports.plugin = plugin;
<commit_msg>bug fixed<commit_after>/**
 * Created by nuintun on 2015/4/27.
 */

'use strict';

var is = require('is');
var path = require('path');
var join = path.join;
var dirname = path.dirname;
var relative = path.relative;
var util = require('util');
var colors = require('colors/safe');
var debug = require('debug')('gulp-css');

// The work cwd
var cwd = process.cwd();

// Set debug color use 6
debug.color = 2;

/**
 * Create a plugin
 * @param name
 * @param transport
 * @returns {Function}
 */

function plugin(name, transport){
  return function (vinyl, options){
    // debug
    debug('load plugin: %s', colors.cyan(name));
    // debug
    debug('read file: %s', colors.magenta(pathFromCwd(vinyl.path)));

    vinyl = transport(vinyl, options);

    return vinyl;
  };
}

/**
 * Normalize path
 * @param path
 * @returns {string}
 */

function normalize(path){
  path = path.replace(/\\+/g, '/');
  path = path.replace(/([^:/])\/+\//g, '$1/');
  path = path.replace(/(:)?\/{2,}/, '$1//');

  return path;
}

/**
 * Resolve a `relative` path base on `base` path
 * @param relative
 * @param vinyl
 * @param wwwroot
 * @returns {string}
 */

function resolve(relative, vinyl, wwwroot){
  var base;
  var absolute;

  // debug
  debug('resolve path: %s', colors.magenta(normalize(relative)));

  // resolve
  if (isAbsolute(relative)) {
    base = wwwroot;
    absolute = join(base, relative.substring(1));
  } else {
    base = dirname(vinyl.path);
    absolute = join(base, relative);

    // out of base, use wwwroot
    if (isRelative(absolute)) {
      base = wwwroot;
      absolute = join(base, relative);

      // out of wwwroot
      if (isOutBound(absolute, wwwroot)) {
        throwError('file: %s is out of bound of wwwroot: %s.', normalize(absolute), normalize(wwwroot));
      }
    }
  }

  // debug
  debug('of base path: %s', colors.magenta(pathFromCwd(base)));
  debug('to: %s', colors.magenta(pathFromCwd(absolute)));

  return absolute;
}

/**
 * Test path is relative path or not
 * @param path
 * @returns {boolean}
 */

function isRelative(path){
  return /^\.{1,2}[\\/]/.test(path);
}

/**
 * Test path is absolute path or not
 * @param path
 * @returns {boolean}
 */

function isAbsolute(path){
  return /^[\\/](?:[^\\/]+|$)/.test(path);
}

/**
 * Test path is local path or not
 * @param path
 * @returns {boolean}
 */

function isLocal(path){
  return !/^https?:\/\/|^\/\//.test(path) && !/^data:/.test(path);
}

/**
 * Test path is out of bound of base
 * @param path
 * @param base
 * @returns {boolean}
 */

function isOutBound(path, base){
  return /(?:^[\\\/]?)\.\.(?:[\\\/]|$)/.test(relative(base, path));
}

/**
 * Get relative path from cwd
 * @param path
 * @returns {string}
 */

function pathFromCwd(path){
  return normalize(relative(cwd, path)) || './';
}

/**
 * Plugin error
 */

function throwError(){
  var slice = [].slice;
  var message = util.format
    .apply(null, slice.call(arguments));

  throw new Error(message);
}

/**
 * Node extend
 * Copyright 2011, John Resig
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * @fileoverview
 * Port of jQuery.extend that actually works on node.js
 */

function extend(){
  var target = arguments[0] || {};
  var i = 1;
  var length = arguments.length;
  var deep = false;
  var options, name, src, copy, copy_is_array, clone;

  // handle a deep copy situation
  if (typeof target === 'boolean') {
    deep = target;
    target = arguments[1] || {};
    // skip the boolean and the target
    i = 2;
  }

  // handle case when target is a string or something (possible in deep copy)
  if (typeof target !== 'object' && !is.fn(target)) {
    target = {};
  }

  for (; i < length; i++) {
    // only deal with non-null/undefined values
    options = arguments[i];

    if (options !== null) {
      if (typeof options === 'string') {
        options = options.split('');
      }

      // extend the base object
      for (name in options) {
        if (options.hasOwnProperty(name)) {
          src = target[name];
          copy = options[name];

          // prevent never-ending loop
          if (target === copy) {
            continue;
          }

          // recurse if we're merging plain objects or arrays
          if (deep && copy && (is.hash(copy) || (copy_is_array = Array.isArray(copy)))) {
            if (copy_is_array) {
              copy_is_array = false;
              clone = src && Array.isArray(src) ? src : [];
            } else {
              clone = src && is.hash(src) ? src : {};
            }

            // never move original objects, clone them
            target[name] = extend(deep, clone, copy);

            // don't bring in undefined values
          } else if (typeof copy !== 'undefined') {
            target[name] = copy;
          }
        }
      }
    }
  }

  // return the modified object
  return target;
}

/**
 * Exports module.
 */

module.exports.cwd = cwd;
module.exports.normalize = normalize;
module.exports.isRelative = isRelative;
module.exports.isAbsolute = isAbsolute;
module.exports.isLocal = isLocal;
module.exports.isOutBound = isOutBound;
module.exports.resolve = resolve;
module.exports.pathFromCwd = pathFromCwd;
module.exports.throwError = throwError;
module.exports.extend = extend;
module.exports.colors = colors;
module.exports.debug = debug;
module.exports.plugin = plugin;
<|endoftext|>


<commit_before>com.flowmate.util = {
	options : com.flowmate.options,
	super : com.flowmate,

	addLayer : function (name, type, parent) {
		var parent = parent ? parent : this.super.current,
			layer = parent.addLayerOfType(type);

		if (name) {
			layer.setName(name);
		}

		 return layer;
	},

	addShape : function (name, parent) {
		var layer = this.addLayer(name, 'rectangle', parent);

		if (this.isShape(layer)){
			return layer;
		}
		return this.shapeWithPath(layer);
	},

	addGroup : function (name, parent) {
		return this.addLayer(name, 'group', parent);
	},

	removeLayer : function (group, layer) {
		this.debug ("removeLayer");

		if (group) {
			group.removeLayer(layer);
		}
	},

	moveLayer : function (opt) {
		this.debug ("moveLayer");
		var layer = opt.target,
			newGroup = opt.newGroup,
			oldGroup = layer.parentGroup();

		layer.setIsSelected(false);

		if (this.isGroup(newGroup)) {
			newGroup.addLayers ([layer]);
			this.removeLayer(oldGroup, layer);
		}
	},

	is : function (layer, theClass) {
		var klass = layer.class();
		return klass === theClass;
	},

	isPage : function (layer) {
		return this.is(layer, MSPage);
	},

	isGroup : function (layer) {
		return this.is(layer, MSLayerGroup);
	},

	isText : function (layer) {
		return this.is(layer, MSTextLayer);
	},

	isShape : function (layer){
		return this.is(layer, MSShapeGroup);
	},

	getFrame : function (layer) {
		var frame = layer.frame();

		return {
			x: Math.round(frame.x()),
			y: Math.round(frame.y()),
			width: Math.round(frame.width()),
			height: Math.round(frame.height())
		};
	},

	getRect : function (layer) {
		var rect = layer.absoluteRect();
		return {
			x: Math.round(rect.x()),
			y: Math.round(rect.y()),
			width: Math.round(rect.width()),
			height: Math.round(rect.height())
		};
	},

	setSize : function (opt) {
		//layer, width, height, absolute
		this.debug(opt.layer);

		var layer = opt.target;

		if(opt.absolute){
			layer.absoluteRect().setWidth(opt.width);
			layer.absoluteRect().setHeight(opt.height);
		}
		else{
			layer.frame().setWidth(opt.width);
			layer.frame().setHeight(opt.height);
		}

		return layer;
	},

	setPosition : function (opt) {
		//layer, x, y, absolute
		//
		var layer = opt.target;

		this.debug (layer.absoluteRect().setMidX)

		if (opt.type == "topleft") {
			if(opt.absolute){
				layer.absoluteRect().setX(opt.x);
				layer.absoluteRect().setY(opt.y);
			}
			else{
				layer.frame().setX(opt.x);
				layer.frame().setY(opt.y);
			}
		} else if (opt.type == "middle") {
			if(opt.absolute){
				layer.absoluteRect().setMidX(opt.x);
				layer.absoluteRect().setMidY(opt.y);
			}
			else{
				layer.frame().setMidX(opt.x);
				layer.frame().setMidY(opt.y);
			}
		}

		return layer;
	},

	setFontStyle :function (label, opt) {
		this.debug("setFontStyle");
		var opt 	= opt || {},
			name 	= (opt.name) ? opt.name : this.options.fontName,
			size 	= (opt.size) ? opt.size : this.options.fontSize,
			color 	= (opt.color) ? MSColor.colorWithSVGString(opt.color] :  MSColor.colorWithSVGString(this.options.fontColor],
			align 	= (opt.align) ? (opt.align) : this.options.align;

		var originalFrame = label.frame();

		label.setFontPostscriptName (name);
		label.setFontSize (size);
		label.setTextColor (color);
		label.setTextAlignment(align); // center
	},

	setBorder : function (opt) {
		var layer = opt.target;
		if (this.isShape(layer)) {
			var border 			= layer.style().borders().addNewStylePart();
			border.color 		= MSColor.colorWithSVGString(opt.color);
			border.thickness 	= opt.thickness;
		}
	},

	setShapeColor : function (opt) {
		//layer, hex, alpha
		var layer = opt.target;

		if(this.isShape(layer)) {

			var	color = MSColor.alloc().init()),
				rgb = this.hexToRgb(opt.hex),
				red = rgb.r / 255,
				green = rgb.g / 255,
				blue = rgb.b / 255;

			this.debug (rgb);

			var alpha = (opt.alpha) ? opt.alpha : 1;
			//alphe = (alpha && !isNaN(alpha) && (alpha <= 1 || alpha >= 0)) ? alpha : 1;

			color.setRed(red);
			color.setGreen(green);
			color.setBlue(blue);
			color.setAlpha(alpha);

			var fills = layer.style().fills();
			if (fills.count() <= 0) {
				fills.addNewStylePart();
			}

			layer.style().fill().setFillType(0);
			layer.style().fill().setColor(color);
		}
	},

	setGradient : function (opt) {
		var layer = opt.target;

		if (this.isShape(layer)) {
			var fills = layer.style().fills();
			if (fills.count() <= 0) {
				fills.addNewStylePart();
			}

			layer.style().fill().setFillType(1);
			var gradient 	= layer.style().fill().gradient(),
				startColor 	= opt.startColor,
				endColor 	= opt.endColor;

			[gradient setColor:[MSColor colorWithSVGString:startColor] atIndex:0];
			[gradient setColor:[MSColor colorWithSVGString:endColor] atIndex:1];
		}
	},

	didSelect : function () {
		if (selection.count() > 0) {
			return true;
		} else {
			this.showToast ("Must Select Text Layer to create flochart node.");
		}
	},

	showToast : function (message) {
		this.runCommand(['-c', 'afplay /System/Library/Sounds/Basso.aiff']);
		[doc showMessage: message];
	},

	runCommand: function(cmd,path){
        var task = [[NSTask alloc] init];
        task.setLaunchPath("/bin/bash");
        task.setArguments(cmd);
        task.launch();
    },

	debug : function(msg){
        if(this.isModeDebug()) log(msg);
    },

    isModeDebug : function() {
    	return (com.flowmate.options.mode == "debug");
    },

	hexToRgb : function (hex) {
		var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
		return result ? {
			r: parseInt(result[1], 16),
			g: parseInt(result[2], 16),
			b: parseInt(result[3], 16)
		} : null;
	},

    shapeWithPath : function (shape) {
		if ( shape.embedInShapeGroup != undefined ) {
			return shape.embedInShapeGroup()
		} else if ( MSShapeGroup.shapeWithPath != undefined ) {
			return MSShapeGroup.shapeWithPath(shape)
		}
     },

	dump : function (obj) {
	    this.debugLog("#####################################################################################");
	    this.debugLog("## Dumping object " + obj );
	    this.debugLog("## obj class is: " + [obj className]);
	    this.debugLog("#####################################################################################");

	    this.debugLog("############################# obj.properties:");
	    this.debugLog([obj class].mocha().properties());
	    this.debugLog("############################# obj.propertiesWithAncestors:");
	    this.debugLog([obj class].mocha().propertiesWithAncestors());

	    this.debugLog("############################# obj.classMethods:");
	    this.debugLog([obj class].mocha().classMethods());
	    this.debugLog("############################# obj.classMethodsWithAncestors:");
	    this.debugLog([obj class].mocha().classMethodsWithAncestors());

	    this.debugLog("############################# obj.instanceMethods:");
	    this.debugLog([obj class].mocha().instanceMethods());
	    this.debugLog("############################# obj.instanceMethodsWithAncestors:");
	    this.debugLog([obj class].mocha().instanceMethodsWithAncestors());

	    this.debugLog("############################# obj.protocols:");
	    this.debugLog([obj class].mocha().protocols())
	    this.debugLog("############################# obj.protocolsWithAncestors:");
	    this.debugLog([obj class].mocha().protocolsWithAncestors());

	    this.debugLog("############################# obj.treeAsDictionary():");
	    this.debugLog(obj.treeAsDictionary());
	}
}<commit_msg>Decision Yes and No label add<commit_after>com.flowmate.util = {
	options : com.flowmate.options,
	super : com.flowmate,

	addLayer : function (name, type, parent) {
		var parent = parent ? parent : this.super.current,
			layer = parent.addLayerOfType(type);

		if (name) {
			layer.setName(name);
		}

		 return layer;
	},

	addShape : function (name, parent) {
		var layer = this.addLayer(name, 'rectangle', parent);

		if (this.isShape(layer)){
			return layer;
		}
		return this.shapeWithPath(layer);
	},

	addGroup : function (name, parent) {
		return this.addLayer(name, 'group', parent);
	},

	addText : function (opt) {
		// this.util.debugLog("addText");

		// var parent 		= opt.parent || doc.currentPage(),
		// 	name 		= opt.name || "new text layer",
		// 	color 		= MSColor.colorWithSVGString(opt.color || this.options.fontColor),
		// 	fontName	= opt.fontNamr || this.options.fontName,
		// 	fontSize 	= opt.fontSize || this.options.fontSize,
		// 	string 		= opt.string || "Type something",
		// 	w 			= opt.width || 400,
		// 	h 			= opt.height || 24,
		// 	x 			= opt.x || 0,
		// 	y 			= opt.y || 0,
		// 	fixed 		= opt.fixed || false;

		// var textLayer = parent.addLayerOfType("text");

		// textLayer.textColor = color;
		// textLayer.fontSize = fontSize;

		// textLayer.setName(name);
		// textLayer.setNameIsFixed(true);
		// this.setStringValue(textLayer, string);
		// textLayer.setFontPostscriptName(fontName);

		// var textLayerFrame = textLayer.frame();

		// textLayerFrame.setWidth(w);
		// textLayerFrame.setX(y);
		// textLayerFrame.setY(y);

		// if(fixed){
		//     textLayer.setTextBehaviour(1) // BCTextBehaviourFixedWidth
		// }

		// return textLayer;
		return this.addLayer(name, 'text', parent);
	},

	removeLayer : function (group, layer) {
		this.debug ("removeLayer");

		if (group) {
			group.removeLayer(layer);
		}
	},

	moveLayer : function (opt) {
		this.debug ("moveLayer");
		var layer = opt.target,
			newGroup = opt.newGroup,
			oldGroup = layer.parentGroup();

		layer.setIsSelected(false);

		if (this.isGroup(newGroup)) {
			newGroup.addLayers ([layer]);
			this.removeLayer(oldGroup, layer);
		}
	},

	is : function (layer, theClass) {
		var klass = layer.class();
		return klass === theClass;
	},

	isPage : function (layer) {
		return this.is(layer, MSPage);
	},

	isGroup : function (layer) {
		return this.is(layer, MSLayerGroup);
	},

	isText : function (layer) {
		return this.is(layer, MSTextLayer);
	},

	isShape : function (layer){
		return this.is(layer, MSShapeGroup);
	},

	getFrame : function (layer) {
		var frame = layer.frame();

		return {
			x: Math.round(frame.x()),
			y: Math.round(frame.y()),
			width: Math.round(frame.width()),
			height: Math.round(frame.height())
		};
	},

	getRect : function (layer) {
		var rect = layer.absoluteRect();
		return {
			x: Math.round(rect.x()),
			y: Math.round(rect.y()),
			width: Math.round(rect.width()),
			height: Math.round(rect.height())
		};
	},

	setSize : function (opt) {
		//layer, width, height, absolute
		this.debug(opt.layer);

		var layer = opt.target;

		if(opt.absolute){
			layer.absoluteRect().setWidth(opt.width);
			layer.absoluteRect().setHeight(opt.height);
		}
		else{
			layer.frame().setWidth(opt.width);
			layer.frame().setHeight(opt.height);
		}

		return layer;
	},

	setPosition : function (opt) {
		//layer, x, y, absolute
		//
		var layer = opt.target;

		this.debug (layer.absoluteRect().setMidX)

		if (opt.type == "topleft") {
			if(opt.absolute){
				layer.absoluteRect().setX(opt.x);
				layer.absoluteRect().setY(opt.y);
			}
			else{
				layer.frame().setX(opt.x);
				layer.frame().setY(opt.y);
			}
		} else if (opt.type == "middle") {
			if(opt.absolute){
				layer.absoluteRect().setMidX(opt.x);
				layer.absoluteRect().setMidY(opt.y);
			}
			else{
				layer.frame().setMidX(opt.x);
				layer.frame().setMidY(opt.y);
			}
		}

		return layer;
	},

	setFontStyle :function (label, opt) {
		this.debug("setFontStyle");
		var opt 	= opt || {},
			name 	= (opt.name) ? opt.name : this.options.fontName,
			size 	= (opt.size) ? opt.size : this.options.fontSize,
			color 	= (opt.color) ? MSColor.colorWithSVGString(opt.color] :  MSColor.colorWithSVGString(this.options.fontColor],
			align 	= (opt.align) ? (opt.align) : this.options.align;

		var originalFrame = label.frame();

		label.setFontPostscriptName (name);
		label.setFontSize (size);
		label.setTextColor (color);
		label.setTextAlignment(align); // center
	},

	setBorder : function (opt) {
		var layer = opt.target;
		if (this.isShape(layer)) {
			var border 			= layer.style().borders().addNewStylePart();
			border.color 		= MSColor.colorWithSVGString(opt.color);
			border.thickness 	= opt.thickness;
		}
	},

	setShapeColor : function (opt) {
		//layer, hex, alpha
		var layer = opt.target;

		if(this.isShape(layer)) {

			var	color = MSColor.alloc().init()),
				rgb = this.hexToRgb(opt.hex),
				red = rgb.r / 255,
				green = rgb.g / 255,
				blue = rgb.b / 255;

			this.debug (rgb);

			var alpha = (opt.alpha) ? opt.alpha : 1;
			//alphe = (alpha && !isNaN(alpha) && (alpha <= 1 || alpha >= 0)) ? alpha : 1;

			color.setRed(red);
			color.setGreen(green);
			color.setBlue(blue);
			color.setAlpha(alpha);

			var fills = layer.style().fills();
			if (fills.count() <= 0) {
				fills.addNewStylePart();
			}

			layer.style().fill().setFillType(0);
			layer.style().fill().setColor(color);
		}
	},

	setGradient : function (opt) {
		var layer = opt.target;

		if (this.isShape(layer)) {
			var fills = layer.style().fills();
			if (fills.count() <= 0) {
				fills.addNewStylePart();
			}

			layer.style().fill().setFillType(1);
			var gradient 	= layer.style().fill().gradient(),
				startColor 	= opt.startColor,
				endColor 	= opt.endColor;

			[gradient setColor:[MSColor colorWithSVGString:startColor] atIndex:0];
			[gradient setColor:[MSColor colorWithSVGString:endColor] atIndex:1];
		}
	},

	didSelect : function () {
		if (selection.count() > 0) {
			return true;
		} else {
			this.showToast ("Must Select Text Layer to create flochart node.");
		}
	},

	showToast : function (message) {
		this.runCommand(['-c', 'afplay /System/Library/Sounds/Basso.aiff']);
		[doc showMessage: message];
	},

	runCommand: function(cmd,path){
        var task = [[NSTask alloc] init];
        task.setLaunchPath("/bin/bash");
        task.setArguments(cmd);
        task.launch();
    },

	debug : function(msg){
        if(this.isModeDebug()) log(msg);
    },

    isModeDebug : function() {
    	return (com.flowmate.options.mode == "debug");
    },

	hexToRgb : function (hex) {
		var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
		return result ? {
			r: parseInt(result[1], 16),
			g: parseInt(result[2], 16),
			b: parseInt(result[3], 16)
		} : null;
	},

    shapeWithPath : function (shape) {
		if ( shape.embedInShapeGroup != undefined ) {
			return shape.embedInShapeGroup()
		} else if ( MSShapeGroup.shapeWithPath != undefined ) {
			return MSShapeGroup.shapeWithPath(shape)
		}
     },

	dump : function (obj) {
	    this.debugLog("#####################################################################################");
	    this.debugLog("## Dumping object " + obj );
	    this.debugLog("## obj class is: " + [obj className]);
	    this.debugLog("#####################################################################################");

	    this.debugLog("############################# obj.properties:");
	    this.debugLog([obj class].mocha().properties());
	    this.debugLog("############################# obj.propertiesWithAncestors:");
	    this.debugLog([obj class].mocha().propertiesWithAncestors());

	    this.debugLog("############################# obj.classMethods:");
	    this.debugLog([obj class].mocha().classMethods());
	    this.debugLog("############################# obj.classMethodsWithAncestors:");
	    this.debugLog([obj class].mocha().classMethodsWithAncestors());

	    this.debugLog("############################# obj.instanceMethods:");
	    this.debugLog([obj class].mocha().instanceMethods());
	    this.debugLog("############################# obj.instanceMethodsWithAncestors:");
	    this.debugLog([obj class].mocha().instanceMethodsWithAncestors());

	    this.debugLog("############################# obj.protocols:");
	    this.debugLog([obj class].mocha().protocols())
	    this.debugLog("############################# obj.protocolsWithAncestors:");
	    this.debugLog([obj class].mocha().protocolsWithAncestors());

	    this.debugLog("############################# obj.treeAsDictionary():");
	    this.debugLog(obj.treeAsDictionary());
	}
}<|endoftext|>


<commit_before>/**
 * Sitespeed.io - How speedy is your site? (http://www.sitespeed.io)
 * Copyright (c) 2014, Peter Hedenskog, Tobias Lidskog
 * and other contributors
 * Released under the Apache 2.0 License
 */
'use strict';
var ySlowUtil = require('./util/yslowUtil'),
  util = require('./util/util'),
  simplehar = require('simplehar'),
  path = require('path'),
  fs = require('fs-extra'),
  render = require('./util/htmlRenderer');

function SiteHTMLRenderer(config) {
  this.numberOfAnalyzedPages = 0;
  this.config = config;
  this.ruleDictionary = {};
}

SiteHTMLRenderer.prototype.renderPage = function(url, pageData, cb) {
  this.numberOfAnalyzedPages++;

  var renderData = {};
  if (pageData.yslow) {
    renderData = {
      'url': pageData.yslow.originalUrl,
      'score': pageData.yslow.o,
      'size': ySlowUtil.getSize(pageData.yslow.comps),
      'rules': pageData.yslow.g,
      'assets': pageData.yslow.comps,
      'noOfDomains': ySlowUtil.getNumberOfDomains(pageData.yslow.comps),
      'timeSinceLastModificationStats': ySlowUtil.getLastModStats(pageData.yslow.comps),
      'cacheTimeStats': ySlowUtil.getCacheTimeStats(pageData.yslow.comps),
      'noOfAssetsThatIsCached': (pageData.yslow.comps.length - pageData.yslow.g.expiresmod.components.length),
      'assetsPerDomain': ySlowUtil.getAssetsPerDomain(pageData.yslow.comps),
      'assetsPerContentType': ySlowUtil.getAssetsPerContentType(pageData.yslow.comps),
      'sizePerContentType': ySlowUtil.getAssetsSizePerContentType(pageData.yslow.comps),
      'ruleDictionary': pageData.yslow.dictionary.rules
    };

    this.ruleDictionary = pageData.yslow.dictionary.rules;
  } else {
    renderData.url = util.getURLFromPageData(pageData);
  }

  renderData.gpsiData = pageData.gpsi;
  if (pageData.browsertime) {
    renderData.browsertimeData = pageData.browsertime.browsertime;
  }
  if (pageData.webpagetest) {
    renderData.wptData = pageData.webpagetest.wpt;
  }
  if (pageData.headless) {
    renderData.headlessData = pageData.headless.getStats();
  }

  renderData.config = this.config;
  renderData.pageMeta = {
    'path': '../',
    'title': 'Page data, collected by sitespeed.io for page ' + url,
    'description': 'All data collected for this individual page.'
  };
  var hash = util.getFileName(url);
  render('page', renderData, this.config.run.absResultDir, cb, hash + '.html', 'pages');
};

SiteHTMLRenderer.prototype.renderHAR = function(url, pageData, cb) {

  var config = this.config;

  this.config.browsertime.forEach(function(browser) {

    var hash = util.getFileName(url);

    var result = simplehar({
      har: path.join(config.run.absResultDir, 'data', 'har', browser, hash + '.har'),
      lng: false,
      frame: true,
      return: true,
      frameContent: {
        css: false,
        js: false
      }
    });

    var run = 0;

    result.html = Array.isArray(result.html) ?
      result.html : [result.html];

    result.html.forEach(function(har) {
      var renderData = {
        'har': har,
        'run': run,
        'browser': browser,
        'url': util.getURLFromPageData(pageData),
        'config': config
      };
      renderData.pageMeta = {
        'path': '../../',
        'title': 'HAR waterfall using ' + browser + ' run ' + (run + 1) + ' for ' + url,
        'description': 'HAR waterfall graph.'
      };

      render('har', renderData, config.run.absResultDir, cb, hash + '-' + run + '.html', path.join('har',
        browser));
      run++;
    });
  });
};

module.exports = SiteHTMLRenderer;
<commit_msg>ok, we can not handle some chars in handlebars, so catch the error for now #662<commit_after>/**
 * Sitespeed.io - How speedy is your site? (http://www.sitespeed.io)
 * Copyright (c) 2014, Peter Hedenskog, Tobias Lidskog
 * and other contributors
 * Released under the Apache 2.0 License
 */
'use strict';
var ySlowUtil = require('./util/yslowUtil'),
  util = require('./util/util'),
  simplehar = require('simplehar'),
  path = require('path'),
  fs = require('fs-extra'),
  winston = require('winston'),
  render = require('./util/htmlRenderer');

function SiteHTMLRenderer(config) {
  this.numberOfAnalyzedPages = 0;
  this.config = config;
  this.ruleDictionary = {};
  this.log = winston.loggers.get('sitespeed.io');
}

SiteHTMLRenderer.prototype.renderPage = function(url, pageData, cb) {
  this.numberOfAnalyzedPages++;

  var renderData = {};
  if (pageData.yslow) {
    renderData = {
      'url': pageData.yslow.originalUrl,
      'score': pageData.yslow.o,
      'size': ySlowUtil.getSize(pageData.yslow.comps),
      'rules': pageData.yslow.g,
      'assets': pageData.yslow.comps,
      'noOfDomains': ySlowUtil.getNumberOfDomains(pageData.yslow.comps),
      'timeSinceLastModificationStats': ySlowUtil.getLastModStats(pageData.yslow.comps),
      'cacheTimeStats': ySlowUtil.getCacheTimeStats(pageData.yslow.comps),
      'noOfAssetsThatIsCached': (pageData.yslow.comps.length - pageData.yslow.g.expiresmod.components.length),
      'assetsPerDomain': ySlowUtil.getAssetsPerDomain(pageData.yslow.comps),
      'assetsPerContentType': ySlowUtil.getAssetsPerContentType(pageData.yslow.comps),
      'sizePerContentType': ySlowUtil.getAssetsSizePerContentType(pageData.yslow.comps),
      'ruleDictionary': pageData.yslow.dictionary.rules
    };

    this.ruleDictionary = pageData.yslow.dictionary.rules;
  } else {
    renderData.url = util.getURLFromPageData(pageData);
  }

  renderData.gpsiData = pageData.gpsi;
  if (pageData.browsertime) {
    renderData.browsertimeData = pageData.browsertime.browsertime;
  }
  if (pageData.webpagetest) {
    renderData.wptData = pageData.webpagetest.wpt;
  }
  if (pageData.headless) {
    renderData.headlessData = pageData.headless.getStats();
  }

  renderData.config = this.config;
  renderData.pageMeta = {
    'path': '../',
    'title': 'Page data, collected by sitespeed.io for page ' + url,
    'description': 'All data collected for this individual page.'
  };
  var hash = util.getFileName(url);
  render('page', renderData, this.config.run.absResultDir, cb, hash + '.html', 'pages');
};

SiteHTMLRenderer.prototype.renderHAR = function(url, pageData, cb) {

  var config = this.config;
  var log = this.log;

  this.config.browsertime.forEach(function(browser) {

    var hash = util.getFileName(url);

    try {

    console.log('Lets create the simplehar result');
    var result = simplehar({
      har: path.join(config.run.absResultDir, 'data', 'har', browser, hash + '.har'),
      lng: false,
      frame: true,
      return: true,
      frameContent: {
        css: false,
        js: false
      }
    });

    console.log('We have the result');

    var run = 0;

    result.html = Array.isArray(result.html) ?
      result.html : [result.html];

    result.html.forEach(function(har) {
      var renderData = {
        'har': har,
        'run': run,
        'browser': browser,
        'url': util.getURLFromPageData(pageData),
        'config': config
      };
      renderData.pageMeta = {
        'path': '../../',
        'title': 'HAR waterfall using ' + browser + ' run ' + (run + 1) + ' for ' + url,
        'description': 'HAR waterfall graph.'
      };

      render('har', renderData, config.run.absResultDir, cb, hash + '-' + run + '.html', path.join('har',
        browser));
      run++;
      });
    }
    catch (err) {
      log.error('Could not generate HAR for ' + url + '  err:' + err);
    }
  });
};

module.exports = SiteHTMLRenderer;
<|endoftext|>


<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Ajax.org Code Editor (ACE).
 *
 * The Initial Developer of the Original Code is
 * Ajax.org B.V.
 * Portions created by the Initial Developer are Copyright (C) 2010
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *      Fabian Jakobs <fabian AT ajax DOT org>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {

var oop = require("pilot/oop");
var EventEmitter = require("pilot/event_emitter").EventEmitter;
var Range = require("ace/range").Range;

var Document = function(text) {
    this.$lines = [];

    if (Array.isArray(text)) {
        this.insertLines(0, text);
    } else {
        this.insert({row: 0, column:0}, text);
    }
};

(function() {

    oop.implement(this, EventEmitter);

    this.setValue = function(text) {
        this.remove(new Range(0, 0, this.$lines.length, this.$lines[this.$lines.length-1].length));
        this.insertLines(0, this.$split(text));
    };

    this.getValue = function() {
        return this.$lines.join(this.getNewLineCharacter());
    };

    // check for IE split bug
    if ("aaa".split(/a/).length == 0)
        this.$split = function(text) {
            return text.replace(/\r\n|\r/g, "\n").split("\n");
        }
    else
        this.$split = function(text) {
            return text.split(/\r\n|\r|\n/);
        };

    this.$detectNewLine = function(text) {
        var match = text.match(/^.*?(\r?\n)/m);
        if (match) {
            this.$autoNewLine = match[1];
        } else {
            this.$autoNewLine = "\n";
        }
    };

    this.getNewLineCharacter = function() {
      switch (this.$newLineMode) {
          case "windows":
              return "\r\n";

          case "unix":
              return "\n";

          case "auto":
              return this.$autoNewLine;
      }
    },

    this.$autoNewLine = "\n";
    this.$newLineMode = "auto";
    this.setNewLineMode = function(newLineMode) {
        if (this.$newLineMode === newLineMode) return;

        this.$newLineMode = newLineMode;
    };

    this.getNewLineMode = function() {
        return this.$newLineMode;
    };

    this.isNewLine = function(text) {
        return (text == "\r\n" || text == "\r" || text == "\n");
    };

    /**
     * Get a verbatim copy of the given line as it is in the document
     */
    this.getLine = function(row) {
        return this.$lines[row] || "";
    };

    this.getLines = function(firstRow, lastRow) {
        return this.$lines.slice(firstRow, lastRow+1);
    };

    /**
     * Returns all lines in the document as string array. Warning: The caller
     * should not modify this array!
     */
    this.getAllLines = function() {
        return this.$lines;
    };

    this.getLength = function() {
        return this.$lines.length;
    };

    this.getTextRange = function(range) {
        if (range.start.row == range.end.row) {
            return this.$lines[range.start.row].substring(range.start.column,
                                                         range.end.column);
        }
        else {
            var lines = [];
            lines.push(this.$lines[range.start.row].substring(range.start.column));
            lines.push.apply(lines, this.getLines(range.start.row+1, range.end.row-1));
            lines.push(this.$lines[range.end.row].substring(0, range.end.column));
            return lines.join(this.getNewLineCharacter());
        }
    };

    this.$clipPosition = function(position) {
        var length = this.$lines.length;
        if (position.row >= length) {
            position.row = Math.max(0, length - 1);
            position.column = this.getLine(length-1).length;
        }
        return position;
    }

    this.insert = function(position, text) {
        if (text.length == 0)
            return position;

        position = this.$clipPosition(position);

        if (this.$lines.length <= 1) {
            this.$detectNewLine(text);
        }

        var newLines = this.$split(text);

        if (this.isNewLine(text)) {
            var end = this.insertNewLine(position);
        }
        else if (newLines.length == 1) {
            var end = this.insertInLine(position, text);
        }
        else {
            var end = this.insertInLine(position, newLines[0]);
            this.insertNewLine(end);
            if (newLines.length > 2)
                this.insertLines(position.row+1, newLines.slice(1, newLines.length-1));

            var end = this.insertInLine({row: position.row + newLines.length - 1, column: 0}, newLines[newLines.length-1]);
        }

        return end;
    };

    this.insertLines = function(row, lines) {
        if (lines.length == 0)
            return {row: row, column: 0};

        var args = [row, 0];
        args.push.apply(args, lines);
        this.$lines.splice.apply(this.$lines, args);

        var range = new Range(row, 0, row + lines.length - 1, 0);
        var delta = {
            action: "insertLines",
            range: range,
            lines: lines
        };
        this._dispatchEvent("change", { data: delta });
        return range.end;
    },

    this.insertNewLine = function(position) {
        position = this.$clipPosition(position);
        var line = this.$lines[position.row] || "";
        this.$lines[position.row] = line.substring(0, position.column);
        this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length));

        var end = {
            row : position.row + 1,
            column : 0
        };

        var delta = {
            action: "insertText",
            range: Range.fromPoints(position, end),
            text: this.getNewLineCharacter()
        };
        this._dispatchEvent("change", { data: delta });

        return end;
    };

    this.insertInLine = function(position, text) {
        if (text.length == 0)
            return position;

        var line = this.$lines[position.row] || "";
        this.$lines[position.row] = line.substring(0, position.column) + text
                + line.substring(position.column);

        var end = {
            row : position.row,
            column : position.column + text.length
        };

        var delta = {
            action: "insertText",
            range: Range.fromPoints(position, end),
            text: text
        };
        this._dispatchEvent("change", { data: delta });

        return end;
    };

    this.remove = function(range) {
        // clip to document
        range.start = this.$clipPosition(range.start);
        range.end = this.$clipPosition(range.end);

        if (range.isEmpty())
            return range.start;

        var firstRow = range.start.row;
        var lastRow = range.end.row;

        if (range.isMultiLine()) {

            // TODO removeInLine can be optimized away!
            this.removeInLine(lastRow, 0, range.end.column);
            if (lastRow - firstRow >= 2)
                this.removeLines(firstRow + 1, lastRow - 1);
            this.removeInLine(firstRow, range.start.column, this.$lines[firstRow].length);
            this.removeNewLine(range.start.row);
        }
        else {
            this.removeInLine(firstRow, range.start.column, range.end.column);
        }
        return range.start;
    };

    this.removeInLine = function(row, startColumn, endColumn) {
        if (startColumn == endColumn)
            return;

        var range = new Range(row, startColumn, row, endColumn);
        var line = this.getLine(row);
        var removed = line.substring(startColumn, endColumn);
        var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length);
        this.$lines.splice(row, 1, newLine);

        var delta = {
            action: "removeText",
            range: range,
            text: removed
        };
        this._dispatchEvent("change", { data: delta });
        return range.start;
    };

    /**
     * Removes a range of full lines
     *
     * @param firstRow {Integer} The first row to be removed
     * @param firstRow {Integer} The first row to be removed
     * @return {String[]} The removed lines
     */
    this.removeLines = function(firstRow, lastRow) {
        var range = new Range(firstRow, 0, lastRow, this.$lines[lastRow].length);
        var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);

        var delta = {
            action: "removeLines",
            range: range,
            nl: this.getNewLineCharacter(),
            lines: removed
        };
        this._dispatchEvent("change", { data: delta });
        return removed;
    };

    this.removeNewLine = function(row) {
        var firstLine = this.getLine(row);
        var secondLine = this.getLine(row+1);

        var range = new Range(row, firstLine.length, row+1, 0);
        var line = firstLine + secondLine;

        this.$lines.splice(row, 2, line);

        var delta = {
            action: "removeText",
            range: range,
            text: this.getNewLineCharacter()
        };
        this._dispatchEvent("change", { data: delta });
    };

    this.replace = function(range, text) {
        // Shortcut: Nothing to replace in this case.
        if (text.length == 0 && range.isEmpty())
            return range.start;

        // Shortcut: If the text we want to insert is the same as it is already
        // in the document, we don't have to replace anything.
        if (text == this.getTextRange(range)) {
            return range.end;
        }

        this.remove(range);
        if (text) {
            var end = this.insert(range.start, text);
        }
        else {
            end = range.start;
        }

        return end;
    };

    this.applyDeltas = function(deltas) {
        for (var i=0; i<deltas.length; i++) {
            var delta = deltas[i];
            var range = delta.range;

            if (delta.action == "insertLines")
                this.insertLines(range.start.row, delta.lines)
            else if (delta.action == "insertText")
                this.insert(range.start, delta.text)
            else if (delta.action == "removeLines")
                this.removeLines(range.start.row, range.end.row)
            else if (delta.action == "removeText")
                this.remove(range)
        }
    };

    this.revertDeltas = function(deltas) {
        for (var i=deltas.length-1; i>=0; i--) {
            var delta = deltas[i];
            var range = delta.range;

            if (delta.action == "insertLines")
                this.removeLines(range.start.row, range.end.row)
            else if (delta.action == "insertText")
                this.remove(range)
            else if (delta.action == "removeLines")
                this.insertLines(range.start.row, delta.lines)
            else if (delta.action == "removeText")
                this.insert(range.start, delta.text)
        }
    };

}).call(Document.prototype);

exports.Document = Document;
});
<commit_msg>set value on empty document<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Ajax.org Code Editor (ACE).
 *
 * The Initial Developer of the Original Code is
 * Ajax.org B.V.
 * Portions created by the Initial Developer are Copyright (C) 2010
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *      Fabian Jakobs <fabian AT ajax DOT org>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {

var oop = require("pilot/oop");
var EventEmitter = require("pilot/event_emitter").EventEmitter;
var Range = require("ace/range").Range;

var Document = function(text) {
    this.$lines = [];

    if (Array.isArray(text)) {
        this.insertLines(0, text);
    } else {
        this.insert({row: 0, column:0}, text);
    }
};

(function() {

    oop.implement(this, EventEmitter);

    this.setValue = function(text) {
        this.remove(new Range(0, 0, this.$lines.length, this.getLine(this.$lines.length-1).length));
        this.insertLines(0, this.$split(text));
    };

    this.getValue = function() {
        return this.$lines.join(this.getNewLineCharacter());
    };

    // check for IE split bug
    if ("aaa".split(/a/).length == 0)
        this.$split = function(text) {
            return text.replace(/\r\n|\r/g, "\n").split("\n");
        }
    else
        this.$split = function(text) {
            return text.split(/\r\n|\r|\n/);
        };

    this.$detectNewLine = function(text) {
        var match = text.match(/^.*?(\r?\n)/m);
        if (match) {
            this.$autoNewLine = match[1];
        } else {
            this.$autoNewLine = "\n";
        }
    };

    this.getNewLineCharacter = function() {
      switch (this.$newLineMode) {
          case "windows":
              return "\r\n";

          case "unix":
              return "\n";

          case "auto":
              return this.$autoNewLine;
      }
    },

    this.$autoNewLine = "\n";
    this.$newLineMode = "auto";
    this.setNewLineMode = function(newLineMode) {
        if (this.$newLineMode === newLineMode) return;

        this.$newLineMode = newLineMode;
    };

    this.getNewLineMode = function() {
        return this.$newLineMode;
    };

    this.isNewLine = function(text) {
        return (text == "\r\n" || text == "\r" || text == "\n");
    };

    /**
     * Get a verbatim copy of the given line as it is in the document
     */
    this.getLine = function(row) {
        return this.$lines[row] || "";
    };

    this.getLines = function(firstRow, lastRow) {
        return this.$lines.slice(firstRow, lastRow+1);
    };

    /**
     * Returns all lines in the document as string array. Warning: The caller
     * should not modify this array!
     */
    this.getAllLines = function() {
        return this.$lines;
    };

    this.getLength = function() {
        return this.$lines.length;
    };

    this.getTextRange = function(range) {
        if (range.start.row == range.end.row) {
            return this.$lines[range.start.row].substring(range.start.column,
                                                         range.end.column);
        }
        else {
            var lines = [];
            lines.push(this.$lines[range.start.row].substring(range.start.column));
            lines.push.apply(lines, this.getLines(range.start.row+1, range.end.row-1));
            lines.push(this.$lines[range.end.row].substring(0, range.end.column));
            return lines.join(this.getNewLineCharacter());
        }
    };

    this.$clipPosition = function(position) {
        var length = this.$lines.length;
        if (position.row >= length) {
            position.row = Math.max(0, length - 1);
            position.column = this.getLine(length-1).length;
        }
        return position;
    }

    this.insert = function(position, text) {
        if (text.length == 0)
            return position;

        position = this.$clipPosition(position);

        if (this.$lines.length <= 1) {
            this.$detectNewLine(text);
        }

        var newLines = this.$split(text);

        if (this.isNewLine(text)) {
            var end = this.insertNewLine(position);
        }
        else if (newLines.length == 1) {
            var end = this.insertInLine(position, text);
        }
        else {
            var end = this.insertInLine(position, newLines[0]);
            this.insertNewLine(end);
            if (newLines.length > 2)
                this.insertLines(position.row+1, newLines.slice(1, newLines.length-1));

            var end = this.insertInLine({row: position.row + newLines.length - 1, column: 0}, newLines[newLines.length-1]);
        }

        return end;
    };

    this.insertLines = function(row, lines) {
        if (lines.length == 0)
            return {row: row, column: 0};

        var args = [row, 0];
        args.push.apply(args, lines);
        this.$lines.splice.apply(this.$lines, args);

        var range = new Range(row, 0, row + lines.length - 1, 0);
        var delta = {
            action: "insertLines",
            range: range,
            lines: lines
        };
        this._dispatchEvent("change", { data: delta });
        return range.end;
    },

    this.insertNewLine = function(position) {
        position = this.$clipPosition(position);
        var line = this.$lines[position.row] || "";
        this.$lines[position.row] = line.substring(0, position.column);
        this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length));

        var end = {
            row : position.row + 1,
            column : 0
        };

        var delta = {
            action: "insertText",
            range: Range.fromPoints(position, end),
            text: this.getNewLineCharacter()
        };
        this._dispatchEvent("change", { data: delta });

        return end;
    };

    this.insertInLine = function(position, text) {
        if (text.length == 0)
            return position;

        var line = this.$lines[position.row] || "";
        this.$lines[position.row] = line.substring(0, position.column) + text
                + line.substring(position.column);

        var end = {
            row : position.row,
            column : position.column + text.length
        };

        var delta = {
            action: "insertText",
            range: Range.fromPoints(position, end),
            text: text
        };
        this._dispatchEvent("change", { data: delta });

        return end;
    };

    this.remove = function(range) {
        // clip to document
        range.start = this.$clipPosition(range.start);
        range.end = this.$clipPosition(range.end);

        if (range.isEmpty())
            return range.start;

        var firstRow = range.start.row;
        var lastRow = range.end.row;

        if (range.isMultiLine()) {

            // TODO removeInLine can be optimized away!
            this.removeInLine(lastRow, 0, range.end.column);
            if (lastRow - firstRow >= 2)
                this.removeLines(firstRow + 1, lastRow - 1);
            this.removeInLine(firstRow, range.start.column, this.$lines[firstRow].length);
            this.removeNewLine(range.start.row);
        }
        else {
            this.removeInLine(firstRow, range.start.column, range.end.column);
        }
        return range.start;
    };

    this.removeInLine = function(row, startColumn, endColumn) {
        if (startColumn == endColumn)
            return;

        var range = new Range(row, startColumn, row, endColumn);
        var line = this.getLine(row);
        var removed = line.substring(startColumn, endColumn);
        var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length);
        this.$lines.splice(row, 1, newLine);

        var delta = {
            action: "removeText",
            range: range,
            text: removed
        };
        this._dispatchEvent("change", { data: delta });
        return range.start;
    };

    /**
     * Removes a range of full lines
     *
     * @param firstRow {Integer} The first row to be removed
     * @param firstRow {Integer} The first row to be removed
     * @return {String[]} The removed lines
     */
    this.removeLines = function(firstRow, lastRow) {
        var range = new Range(firstRow, 0, lastRow, this.$lines[lastRow].length);
        var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);

        var delta = {
            action: "removeLines",
            range: range,
            nl: this.getNewLineCharacter(),
            lines: removed
        };
        this._dispatchEvent("change", { data: delta });
        return removed;
    };

    this.removeNewLine = function(row) {
        var firstLine = this.getLine(row);
        var secondLine = this.getLine(row+1);

        var range = new Range(row, firstLine.length, row+1, 0);
        var line = firstLine + secondLine;

        this.$lines.splice(row, 2, line);

        var delta = {
            action: "removeText",
            range: range,
            text: this.getNewLineCharacter()
        };
        this._dispatchEvent("change", { data: delta });
    };

    this.replace = function(range, text) {
        // Shortcut: Nothing to replace in this case.
        if (text.length == 0 && range.isEmpty())
            return range.start;

        // Shortcut: If the text we want to insert is the same as it is already
        // in the document, we don't have to replace anything.
        if (text == this.getTextRange(range)) {
            return range.end;
        }

        this.remove(range);
        if (text) {
            var end = this.insert(range.start, text);
        }
        else {
            end = range.start;
        }

        return end;
    };

    this.applyDeltas = function(deltas) {
        for (var i=0; i<deltas.length; i++) {
            var delta = deltas[i];
            var range = delta.range;

            if (delta.action == "insertLines")
                this.insertLines(range.start.row, delta.lines)
            else if (delta.action == "insertText")
                this.insert(range.start, delta.text)
            else if (delta.action == "removeLines")
                this.removeLines(range.start.row, range.end.row)
            else if (delta.action == "removeText")
                this.remove(range)
        }
    };

    this.revertDeltas = function(deltas) {
        for (var i=deltas.length-1; i>=0; i--) {
            var delta = deltas[i];
            var range = delta.range;

            if (delta.action == "insertLines")
                this.removeLines(range.start.row, range.end.row)
            else if (delta.action == "insertText")
                this.remove(range)
            else if (delta.action == "removeLines")
                this.insertLines(range.start.row, delta.lines)
            else if (delta.action == "removeText")
                this.insert(range.start, delta.text)
        }
    };

}).call(Document.prototype);

exports.Document = Document;
});
<|endoftext|>


<commit_before>"use strict";
var pluginVersion = require('babel-plugin-streamline/package').version;
var fs = require('fs');
var fsp = require("path");

var util = exports;

exports.idem = function(x) {
	return x;
}

var colors;
try {
	colors = require(util.idem("colors/safe"));
} catch (ex) {}
if (!colors) colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'gray'] //
.reduce(function(r, c) {
	r[c] = util.idem;
	return r;
}, {});

exports.log = function(message) {
	console.log(colors.gray("[STREAMLINE] " + message));
};
exports.warn = function(message) {
	console.warn(colors.yellow("[STREAMLINE] " + message));
};
exports.error = function(message) {
	console.error(colors.magenta("[STREAMLINE] " + message));
};

exports.extend = function(dst, src) {
	dst = dst || {};
	Array.prototype.slice.call(arguments, 1).forEach(function(src) {
		src && Object.keys(src).forEach(function(k) {
			dst[k] = src[k];
		});
	});
	return dst;
};

function defaultRuntime() {
	var _defRT;
	return _defRT || (_defRT = (function() {
		try {
			require(util.idem('fibers'));
			return 'fibers';
		} catch (ex) {}
		try {
			eval("(function*(){})");
			return 'generators';
		} catch (ex) {}
		return "callbacks";
	})());
}

function homeDir() {
	if ((process.env.HOME === undefined) && (process.env.HOMEDRIVE === undefined)) return null;
	return process.env.HOME || (process.env.HOMEDRIVE + process.env.HOMEPATH);
}

// Loads the first `.streamline.json` options file found (searching in priority
// order), or an empty object if no such file found.

exports.envOptions = function() {
	var dirs = ['.'];
	if (require.main) { // REPL doesn't have a require.main
		dirs.push(path.dirname(require.main.filename));
	}
	dirs.push(homeDir());
	for (var i = 0; i < dirs.length; i++) {
		var dir = dirs[i];
		if (dir && fs.existsSync(fsp.join(dir, '.streamline.json'))) {
			return JSON.parse(fs.readFileSync(fsp.join(dir, '.streamline.json'), 'utf8'));
		}
	}
	return {};
}

// straighten options and warns about obsolete ones
exports.getOptions = function(options) {
	var opts = {
		cache: true,
		quiet: false,
	};
	Object.keys(options || {}).forEach(function(opt) {
		if (/^(fibers|generators)$/.test(opt)) {
			if (!opts.quiet) util.warn('obsolete option: ' + opt + ', use runtime instead');
			opts.runtime = opt;
		} else if (/^(sourceMap|map)$/.test(opt)) {
			if (!opts.quiet) util.warn('obsolete option: ' + opt + ', use sourceMaps instead');
			opts.sourceMaps = !! options.sourceMap;
		} else if (opt === 'sourceMapFile') {
			if (!opts.quiet) util.warn('obsolete option: sourceMapFile, use sourceMapTarget instead');
			opts.sourceMapTarget = options.sourceMapFile;
		} else if (opt === 'outputDir') {
			if (!opts.quiet) util.warn('obsolete option: outputDir, use outDir instead');
			opts.outDir = options.outputDir;
		} else if (opt === 'verbose') {
			opts.quiet = !options.verbose;
			if (!opts.quiet) util.warn('obsolete option: verbose, use quiet instead');
		} else if (/^(lines|standalone|fast|old-style-future|promise|cb|aggressive)$/.test(opt)) {
			if (!opts.quiet) util.warn('ignoring obsolete option: ' + opt);
		} else if (/^(compile|outDir|cache|cacheDir|cacheKeep|force|runtime|sourceMaps|sourceMapTarget|quiet|preload|ignore)$/.test(opt) || //
		/^(args|babel|ext|extensions|sourceRoot)$/.test(opt)) {
			// valid option
			opts[opt] = options[opt];
		} else if (/^(program|options|rawArgs|args|commands|filename)$/.test(opt)) {
			// discard silently
		} else {
			if (!opts.quiet) util.warn('invalid option: ' + opt);
		}
	});
	opts.runtime = opts.runtime || defaultRuntime();
	return opts;
};

exports.babelOptions = function(options, filename) {
	options.babel = options.babel || {};
	var babelOpts = {
		plugins: [],
	};
	Object.keys(options.babel).forEach(function(opt) {
		if (options.babel[opt] != null) babelOpts[opt] = options.babel[opt];
	});
	if (babelOpts.plugins.indexOf('streamline') < 0) babelOpts.plugins.push('streamline');
	// see https://github.com/babel/babel/issues/1833
	babelOpts.extra = {
		streamline: {
			runtime: options.runtime,
			quiet: options.quiet,
			forceTransform: !/\.(coffee|js)$/.test(options.ext || filename || ''),
		},
	};
	if (options.runtime !== 'callbacks') {
		babelOpts.blacklist = babelOpts.blacklist || [];
		if (babelOpts.blacklist.indexOf('regenerator') < 0) babelOpts.blacklist.push('regenerator');
	}
	// always return source maps - cache needs them
	babelOpts.sourceMaps = true;
	if (filename) {
		babelOpts.filename = filename;
		babelOpts.sourceFileName = filename;
	}
	return babelOpts;
};

exports.canCompile = function(path) {
	return /\._(js|coffee)$/.test(path);
};

exports.removeShebang = function(code) {
	// replace #! by // - preserves offsets in file
	return (code[0] === '#' && code[1] === '!') ? '//' + code.substring(2) : code;
}

function cacheRoot(options) {
	if (options.cacheDir) return options.cacheDir;
	var home = homeDir();
	if (!home) throw new Error("HOME not found, unable to store Streamline callback cache");
	return fsp.join(home, ".streamline");
}

function delCache(path) {
	fs.readdirSync(path).forEach(function(name) {
		var p = fsp.join(path, name);
		if (fs.statSync(p).isDirectory()) delCache(p);
		else fs.unlinkSync(p);
	});
	fs.rmdirSync(path);
}

// cache subdir changes every time plugin version changes so we need to cleanup old plugin caches
var cleanedUp = false;

function cleanup(dir, max) {
	// do it only once
	if (cleanedUp) return dir;
	cleanedUp = true;
	if (!fs.existsSync(dir)) return dir;
	var paths = fs.readdirSync(dir).map(function(name) {
		return fsp.join(dir, name);
	});
	if (paths.length <= max) return dir;
	paths = paths.sort(function(p1, p2) {
		return fs.statSync(p2).mtime - fs.statSync(p1).mtime;
	});
	paths.slice(max).forEach(delCache);
	return dir;
}

function fastHash(str) {
	var hash = 0;
	for (var i = 0, len = str.length; i < len; i++) hash = (((hash << 5) - hash) + str.charCodeAt(i) | 0);
	return hash + 0x7fffffff; // make it positive
}

exports.cacheDir = function(options) {
	var subdir = 'v' + pluginVersion + '-' + options.runtime + '-' + fastHash(JSON.stringify(util.extend({}, options, {
		ext: undefined // clear ext to have a single subdir for .js and ._js
	})));
	return fsp.join(cleanup(cacheRoot(options), options.cacheKeep || 6), subdir)
}

exports.deprecate = function(module, message, redirected) {
	util.warn("Module " + module.id + " is deprecated: " + message);
	if (!redirected) Object.keys(module.exports).forEach(function(name) {
		var fn = module.exports[name];
		if (typeof fn === 'function') {
			module.exports[name] = function() {
				if (!module.exports[name].warned) util.warn("Module " + module.id + ": calling deprecated function: " + name);
				module.exports[name].warned = true;
				return fn.apply(this, arguments);
			};
		}
	})
};<commit_msg>issue #282 - one more fix for npm test<commit_after>"use strict";
var pluginVersion = require('babel-plugin-streamline/package').version;
var fs = require('fs');
var fsp = require("path");

var util = exports;

exports.idem = function(x) {
	return x;
}

var colors;
try {
	colors = require(util.idem("colors/safe"));
} catch (ex) {}
if (!colors) colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'gray'] //
.reduce(function(r, c) {
	r[c] = util.idem;
	return r;
}, {});

exports.log = function(message) {
	console.log(colors.gray("[STREAMLINE] " + message));
};
exports.warn = function(message) {
	console.warn(colors.yellow("[STREAMLINE] " + message));
};
exports.error = function(message) {
	console.error(colors.magenta("[STREAMLINE] " + message));
};

exports.extend = function(dst, src) {
	dst = dst || {};
	Array.prototype.slice.call(arguments, 1).forEach(function(src) {
		src && Object.keys(src).forEach(function(k) {
			dst[k] = src[k];
		});
	});
	return dst;
};

function defaultRuntime() {
	var _defRT;
	return _defRT || (_defRT = (function() {
		try {
			require(util.idem('fibers'));
			return 'fibers';
		} catch (ex) {}
		try {
			eval("(function*(){})");
			return 'generators';
		} catch (ex) {}
		return "callbacks";
	})());
}

function homeDir() {
	if ((process.env.HOME === undefined) && (process.env.HOMEDRIVE === undefined)) return null;
	return process.env.HOME || (process.env.HOMEDRIVE + process.env.HOMEPATH);
}

// Loads the first `.streamline.json` options file found (searching in priority
// order), or an empty object if no such file found.

exports.envOptions = function() {
	var dirs = ['.'];
	if (require.main) { // REPL doesn't have a require.main
		dirs.push(fsp.dirname(require.main.filename));
	}
	dirs.push(homeDir());
	for (var i = 0; i < dirs.length; i++) {
		var dir = dirs[i];
		if (dir && fs.existsSync(fsp.join(dir, '.streamline.json'))) {
			return JSON.parse(fs.readFileSync(fsp.join(dir, '.streamline.json'), 'utf8'));
		}
	}
	return {};
}

// straighten options and warns about obsolete ones
exports.getOptions = function(options) {
	var opts = {
		cache: true,
		quiet: false,
	};
	Object.keys(options || {}).forEach(function(opt) {
		if (/^(fibers|generators)$/.test(opt)) {
			if (!opts.quiet) util.warn('obsolete option: ' + opt + ', use runtime instead');
			opts.runtime = opt;
		} else if (/^(sourceMap|map)$/.test(opt)) {
			if (!opts.quiet) util.warn('obsolete option: ' + opt + ', use sourceMaps instead');
			opts.sourceMaps = !! options.sourceMap;
		} else if (opt === 'sourceMapFile') {
			if (!opts.quiet) util.warn('obsolete option: sourceMapFile, use sourceMapTarget instead');
			opts.sourceMapTarget = options.sourceMapFile;
		} else if (opt === 'outputDir') {
			if (!opts.quiet) util.warn('obsolete option: outputDir, use outDir instead');
			opts.outDir = options.outputDir;
		} else if (opt === 'verbose') {
			opts.quiet = !options.verbose;
			if (!opts.quiet) util.warn('obsolete option: verbose, use quiet instead');
		} else if (/^(lines|standalone|fast|old-style-future|promise|cb|aggressive)$/.test(opt)) {
			if (!opts.quiet) util.warn('ignoring obsolete option: ' + opt);
		} else if (/^(compile|outDir|cache|cacheDir|cacheKeep|force|runtime|sourceMaps|sourceMapTarget|quiet|preload|ignore)$/.test(opt) || //
		/^(args|babel|ext|extensions|sourceRoot)$/.test(opt)) {
			// valid option
			opts[opt] = options[opt];
		} else if (/^(program|options|rawArgs|args|commands|filename)$/.test(opt)) {
			// discard silently
		} else {
			if (!opts.quiet) util.warn('invalid option: ' + opt);
		}
	});
	opts.runtime = opts.runtime || defaultRuntime();
	return opts;
};

exports.babelOptions = function(options, filename) {
	options.babel = options.babel || {};
	var babelOpts = {
		plugins: [],
	};
	Object.keys(options.babel).forEach(function(opt) {
		if (options.babel[opt] != null) babelOpts[opt] = options.babel[opt];
	});
	if (babelOpts.plugins.indexOf('streamline') < 0) babelOpts.plugins.push('streamline');
	// see https://github.com/babel/babel/issues/1833
	babelOpts.extra = {
		streamline: {
			runtime: options.runtime,
			quiet: options.quiet,
			forceTransform: !/\.(coffee|js)$/.test(options.ext || filename || ''),
		},
	};
	if (options.runtime !== 'callbacks') {
		babelOpts.blacklist = babelOpts.blacklist || [];
		if (babelOpts.blacklist.indexOf('regenerator') < 0) babelOpts.blacklist.push('regenerator');
	}
	// always return source maps - cache needs them
	babelOpts.sourceMaps = true;
	if (filename) {
		babelOpts.filename = filename;
		babelOpts.sourceFileName = filename;
	}
	return babelOpts;
};

exports.canCompile = function(path) {
	return /\._(js|coffee)$/.test(path);
};

exports.removeShebang = function(code) {
	// replace #! by // - preserves offsets in file
	return (code[0] === '#' && code[1] === '!') ? '//' + code.substring(2) : code;
}

function cacheRoot(options) {
	if (options.cacheDir) return options.cacheDir;
	var home = homeDir();
	if (!home) throw new Error("HOME not found, unable to store Streamline callback cache");
	return fsp.join(home, ".streamline");
}

function delCache(path) {
	fs.readdirSync(path).forEach(function(name) {
		var p = fsp.join(path, name);
		if (fs.statSync(p).isDirectory()) delCache(p);
		else fs.unlinkSync(p);
	});
	fs.rmdirSync(path);
}

// cache subdir changes every time plugin version changes so we need to cleanup old plugin caches
var cleanedUp = false;

function cleanup(dir, max) {
	// do it only once
	if (cleanedUp) return dir;
	cleanedUp = true;
	if (!fs.existsSync(dir)) return dir;
	var paths = fs.readdirSync(dir).map(function(name) {
		return fsp.join(dir, name);
	});
	if (paths.length <= max) return dir;
	paths = paths.sort(function(p1, p2) {
		return fs.statSync(p2).mtime - fs.statSync(p1).mtime;
	});
	paths.slice(max).forEach(delCache);
	return dir;
}

function fastHash(str) {
	var hash = 0;
	for (var i = 0, len = str.length; i < len; i++) hash = (((hash << 5) - hash) + str.charCodeAt(i) | 0);
	return hash + 0x7fffffff; // make it positive
}

exports.cacheDir = function(options) {
	var subdir = 'v' + pluginVersion + '-' + options.runtime + '-' + fastHash(JSON.stringify(util.extend({}, options, {
		ext: undefined // clear ext to have a single subdir for .js and ._js
	})));
	return fsp.join(cleanup(cacheRoot(options), options.cacheKeep || 6), subdir)
}

exports.deprecate = function(module, message, redirected) {
	util.warn("Module " + module.id + " is deprecated: " + message);
	if (!redirected) Object.keys(module.exports).forEach(function(name) {
		var fn = module.exports[name];
		if (typeof fn === 'function') {
			module.exports[name] = function() {
				if (!module.exports[name].warned) util.warn("Module " + module.id + ": calling deprecated function: " + name);
				module.exports[name].warned = true;
				return fn.apply(this, arguments);
			};
		}
	})
};<|endoftext|>


<commit_before>// wamp.rt
// Copyright Orange 2014

module.exports.randomId = function() {
    return String(Math.random() * Math.random()).substr(3);
};
<commit_msg>Fix for ID generation<commit_after>// wamp.rt
// Copyright Orange 2014

module.exports.randomId = function() {
    return Math.floor(Math.random() * 9007199254740992);
};
<|endoftext|>


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

'use strict';

var is = require('is');
var path = require('path');
var join = path.join;
var dirname = path.dirname;
var relative = path.relative;
var util = require('util');
var colors = require('colors/safe');
var debug = require('debug')('gulp-css');

// The work cwd
var cwd = process.cwd();

// Set debug color use 6
debug.color = 2;

/**
 * Create a plugin
 * @param name
 * @param transport
 * @returns {Function}
 */

function plugin(name, transport){
  return function (vinyl, options){
    // debug
    debug('load plugin: %s', colors.cyan(name));
    // debug
    debug('read file: %s', colors.magenta(pathFromCwd(vinyl.path)));

    vinyl = transport(vinyl, options);

    return vinyl;
  };
}

/**
 * Normalize path
 * @param path
 * @returns {string}
 */

function normalize(path){
  path = path.replace(/\\+/g, '/');
  path = path.replace(/([^:/])\/+\//g, '$1/');
  path = path.replace(/(:)?\/{2,}/, '$1//');

  return path;
}

/**
 * Resolve a `relative` path base on `base` path
 * @param relative
 * @param vinyl
 * @param wwwroot
 * @returns {string}
 */

function resolve(relative, vinyl, wwwroot){
  var base;
  var absolute;

  // debug
  debug('resolve path: %s', colors.magenta(normalize(relative)));

  // resolve
  if (isAbsolute(relative)) {
    base = wwwroot;
    absolute = join(base, relative.substring(1));
  } else {
    base = dirname(vinyl.path);
    absolute = join(base, relative);

    // out of base, use wwwroot
    if (isRelative(absolute)) {
      base = wwwroot;
      absolute = join(base, relative);

      // out of wwwroot
      if (isRelative(absolute)) {
        throwError('file: %s is out of bound of wwwroot: %s.', normalize(absolute), normalize(base));
      }
    }
  }

  // debug
  debug('of base path: %s', colors.magenta(pathFromCwd(base)));
  debug('to: %s', colors.magenta(pathFromCwd(absolute)));

  return absolute;
}

/**
 * Test path is relative path or not
 * @param path
 * @returns {boolean}
 */

function isRelative(path){
  return /^\.{1,2}[\\/]/.test(path);
}

/**
 * Test path is absolute path or not
 * @param path
 * @returns {boolean}
 */

function isAbsolute(path){
  return /^[\\/](?:[^\\/]+|$)/.test(path);
}

/**
 * Test path is local path or not
 * @param path
 * @returns {boolean}
 */

function isLocal(path){
  return !/^https?:\/\/|^\/\//.test(path) && !/^data:/.test(path);
}

/**
 * Get relative path from cwd
 * @param path
 * @returns {string}
 */

function pathFromCwd(path){
  return normalize(relative(cwd, path)) || './';
}

/**
 * Plugin error
 */

function throwError(){
  var slice = [].slice;
  var message = util.format
    .apply(null, slice.call(arguments));

  throw new Error(message);
}

/**
 * Node extend
 * Copyright 2011, John Resig
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * @fileoverview
 * Port of jQuery.extend that actually works on node.js
 */

function extend(){
  var target = arguments[0] || {};
  var i = 1;
  var length = arguments.length;
  var deep = false;
  var options, name, src, copy, copy_is_array, clone;

  // handle a deep copy situation
  if (typeof target === 'boolean') {
    deep = target;
    target = arguments[1] || {};
    // skip the boolean and the target
    i = 2;
  }

  // handle case when target is a string or something (possible in deep copy)
  if (typeof target !== 'object' && !is.fn(target)) {
    target = {};
  }

  for (; i < length; i++) {
    // only deal with non-null/undefined values
    options = arguments[i];

    if (options !== null) {
      if (typeof options === 'string') {
        options = options.split('');
      }

      // extend the base object
      for (name in options) {
        if (options.hasOwnProperty(name)) {
          src = target[name];
          copy = options[name];

          // prevent never-ending loop
          if (target === copy) {
            continue;
          }

          // recurse if we're merging plain objects or arrays
          if (deep && copy && (is.hash(copy) || (copy_is_array = Array.isArray(copy)))) {
            if (copy_is_array) {
              copy_is_array = false;
              clone = src && Array.isArray(src) ? src : [];
            } else {
              clone = src && is.hash(src) ? src : {};
            }

            // never move original objects, clone them
            target[name] = extend(deep, clone, copy);

            // don't bring in undefined values
          } else if (typeof copy !== 'undefined') {
            target[name] = copy;
          }
        }
      }
    }
  }

  // return the modified object
  return target;
}

/**
 * Exports module.
 */

module.exports.cwd = cwd;
module.exports.normalize = normalize;
module.exports.isRelative = isRelative;
module.exports.isAbsolute = isAbsolute;
module.exports.isLocal = isLocal;
module.exports.resolve = resolve;
module.exports.pathFromCwd = pathFromCwd;
module.exports.throwError = throwError;
module.exports.extend = extend;
module.exports.colors = colors;
module.exports.debug = debug;
module.exports.plugin = plugin;
<commit_msg>bug fixed<commit_after>/**
 * Created by nuintun on 2015/4/27.
 */

'use strict';

var is = require('is');
var path = require('path');
var join = path.join;
var dirname = path.dirname;
var relative = path.relative;
var util = require('util');
var colors = require('colors/safe');
var debug = require('debug')('gulp-css');

// The work cwd
var cwd = process.cwd();

// Set debug color use 6
debug.color = 2;

/**
 * Create a plugin
 * @param name
 * @param transport
 * @returns {Function}
 */

function plugin(name, transport){
  return function (vinyl, options){
    // debug
    debug('load plugin: %s', colors.cyan(name));
    // debug
    debug('read file: %s', colors.magenta(pathFromCwd(vinyl.path)));

    vinyl = transport(vinyl, options);

    return vinyl;
  };
}

/**
 * Normalize path
 * @param path
 * @returns {string}
 */

function normalize(path){
  path = path.replace(/\\+/g, '/');
  path = path.replace(/([^:/])\/+\//g, '$1/');
  path = path.replace(/(:)?\/{2,}/, '$1//');

  return path;
}

/**
 * Resolve a `relative` path base on `base` path
 * @param relative
 * @param vinyl
 * @param wwwroot
 * @returns {string}
 */

function resolve(relative, vinyl, wwwroot){
  var base;
  var absolute;

  // debug
  debug('resolve path: %s', colors.magenta(normalize(relative)));

  // resolve
  if (isAbsolute(relative)) {
    base = wwwroot;
    absolute = join(base, relative.substring(1));
  } else {
    base = dirname(vinyl.path);
    absolute = join(base, relative);

    // out of base, use wwwroot
    if (isRelative(absolute)) {
      base = wwwroot;
      absolute = join(base, relative);

      // out of wwwroot
      if (isOutBound(absolute, base)) {
        throwError('file: %s is out of bound of wwwroot: %s.', normalize(absolute), normalize(base));
      }
    }
  }

  // debug
  debug('of base path: %s', colors.magenta(pathFromCwd(base)));
  debug('to: %s', colors.magenta(pathFromCwd(absolute)));

  return absolute;
}

/**
 * Test path is relative path or not
 * @param path
 * @returns {boolean}
 */

function isRelative(path){
  return /^\.{1,2}[\\/]/.test(path);
}

/**
 * Test path is absolute path or not
 * @param path
 * @returns {boolean}
 */

function isAbsolute(path){
  return /^[\\/](?:[^\\/]+|$)/.test(path);
}

/**
 * Test path is local path or not
 * @param path
 * @returns {boolean}
 */

function isLocal(path){
  return !/^https?:\/\/|^\/\//.test(path) && !/^data:/.test(path);
}

/**
 * Test path is out of bound of base
 * @param path
 * @param base
 * @returns {boolean}
 */

function isOutBound(path, base){
  return /(?:^|[\\\/])\.\.(?:[\\\/]|$)/.test(relative(base, path));
}

/**
 * Get relative path from cwd
 * @param path
 * @returns {string}
 */

function pathFromCwd(path){
  return normalize(relative(cwd, path)) || './';
}

/**
 * Plugin error
 */

function throwError(){
  var slice = [].slice;
  var message = util.format
    .apply(null, slice.call(arguments));

  throw new Error(message);
}

/**
 * Node extend
 * Copyright 2011, John Resig
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * @fileoverview
 * Port of jQuery.extend that actually works on node.js
 */

function extend(){
  var target = arguments[0] || {};
  var i = 1;
  var length = arguments.length;
  var deep = false;
  var options, name, src, copy, copy_is_array, clone;

  // handle a deep copy situation
  if (typeof target === 'boolean') {
    deep = target;
    target = arguments[1] || {};
    // skip the boolean and the target
    i = 2;
  }

  // handle case when target is a string or something (possible in deep copy)
  if (typeof target !== 'object' && !is.fn(target)) {
    target = {};
  }

  for (; i < length; i++) {
    // only deal with non-null/undefined values
    options = arguments[i];

    if (options !== null) {
      if (typeof options === 'string') {
        options = options.split('');
      }

      // extend the base object
      for (name in options) {
        if (options.hasOwnProperty(name)) {
          src = target[name];
          copy = options[name];

          // prevent never-ending loop
          if (target === copy) {
            continue;
          }

          // recurse if we're merging plain objects or arrays
          if (deep && copy && (is.hash(copy) || (copy_is_array = Array.isArray(copy)))) {
            if (copy_is_array) {
              copy_is_array = false;
              clone = src && Array.isArray(src) ? src : [];
            } else {
              clone = src && is.hash(src) ? src : {};
            }

            // never move original objects, clone them
            target[name] = extend(deep, clone, copy);

            // don't bring in undefined values
          } else if (typeof copy !== 'undefined') {
            target[name] = copy;
          }
        }
      }
    }
  }

  // return the modified object
  return target;
}

/**
 * Exports module.
 */

module.exports.cwd = cwd;
module.exports.normalize = normalize;
module.exports.isRelative = isRelative;
module.exports.isAbsolute = isAbsolute;
module.exports.isLocal = isLocal;
module.exports.isOutBound = isOutBound;
module.exports.resolve = resolve;
module.exports.pathFromCwd = pathFromCwd;
module.exports.throwError = throwError;
module.exports.extend = extend;
module.exports.colors = colors;
module.exports.debug = debug;
module.exports.plugin = plugin;
<|endoftext|>


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

'use strict';

var path = require('path');
var util = require('util');
var css = require('@nuintun/css-deps');
var debug = require('debug')('gulp-css');
var gutil = require('@nuintun/gulp-util');

var join = path.join;

// set debug color use 6
debug.color = 6;

/**
 * rename
 *
 * @param {any} path
 * @param {any} transform
 * @returns {String}
 */
function rename(path, transform) {
  return gutil.rename(path, transform, debug);
}

/**
 * transport
 *
 * @param {any} vinyl
 * @param {any} options
 * @param {any} done
 * @returns {void}
 */
function transport(vinyl, options, done) {
  return gutil.transport(vinyl, options, done, debug);
}

/**
 * resolve
 *
 * @param {any} relative
 * @param {any} vinyl
 * @param {any} wwwroot
 * @returns {String}
 */
function resolve(relative, vinyl, wwwroot) {
  return gutil.resolve(relative, vinyl, wwwroot, debug);
}

/**
 * pring
 *
 * @returns {void}
 */
function print() {
  var message = gutil.apply(util.format, null, gutil.slice.call(arguments));

  process.stdout.write(gutil.colors.cyan.bold('  gulp-css ') + message + '\n');
}

/**
 * get rename options
 *
 * @param transform
 * @returns {object}
 */
function initRenameOptions(transform) {
  if (gutil.isFunction(transform)) {
    return transform;
  }

  transform = transform || {};

  if (transform.min) {
    transform.suffix = '-min';
  }

  if (transform.debug) {
    transform.suffix = '-debug';
  }

  return transform;
}

/**
 * init options
 *
 * @param options
 * @returns {object}
 */
function initOptions(options) {
  options = gutil.extend(true, {
    include: false, // include
    prefix: null, // css prefix
    onpath: null, // css resource path callback
    cache: true, // use memory file cahe
    wwwroot: '', // web root
    rename: null // { debug: boolean, min: boolean }
  }, options);

  // wwwroot must be string
  if (!gutil.isString(options.wwwroot)) {
    gutil.throwError('options.wwwroot\'s value should be string.');
  }

  // init wwwroot
  options.wwwroot = join(gutil.cwd, options.wwwroot);
  // init plugins
  options.plugins = gutil.plugins(options.plugins, require('./plugins/index'));
  // init rename
  options.rename = initRenameOptions(options.rename);

  return options;
}

/**
 * transport css dependencies.
 *
 * @param vinyl
 * @param options
 * @returns {Array}
 */
function transportCssDeps(vinyl, options) {
  var deps = [];
  var remote = [];
  var include = [];
  var pkg = vinyl.package || {};
  var onpath = options.onpath;
  var prefix = options.prefix;

  // init css settings
  onpath = gutil.isFunction(onpath) ? function(path, property) {
    return options.onpath(path, property, vinyl.path, options.wwwroot);
  } : null;

  prefix = gutil.isFunction(prefix) ? prefix(vinyl.path, options.wwwroot) : prefix;

  // replace imports and collect dependencies
  vinyl.contents = new Buffer(css(vinyl.contents, function(id) {
    var path;

    // id is not a local file
    if (!gutil.isLocal(id)) {
      // cache dependencie id
      deps.push(id);
      remote.push(id);
    } else {
      // normalize id
      id = gutil.normalize(id);

      // if end with /, find index file
      if (id.substring(id.length - 1) === '/') {
        id += 'index.css';
      }

      // set path
      path = id;
      // rename id
      id = rename(path, options.rename);

      // normalize id
      id = gutil.normalize(id);

      // debug
      debug('transport deps: %s', colors.magenta(id));

      // get absolute path
      path = resolve(path, vinyl, options.wwwroot);

      // cache dependencie id
      deps.push(id);
      // cache dependencie absolute path
      include.push(path);
    }

    // include import css file
    if (options.include) {
      // delete all import
      return false;
    }

    // onpath callback
    if (gutil.isString(path = onpath(id, 'import'))) {
      return path;
    }

    // don't make changes
    return id;
  }, { prefix: prefix, onpath: onpath }));

  // cache file dependencies
  vinyl.package = gutil.extend(pkg, {
    remote: remote,
    include: include,
    dependencies: deps
  });

  return deps;
}

/**
 * exports module
 */
module.exports = {
  debug: debug,
  rename: rename,
  transport: transport,
  resolve: resolve,
  print: print,
  initOptions: initOptions,
  transportCssDeps: transportCssDeps
};
<commit_msg>update files<commit_after>/**
 * Created by nuintun on 2015/4/27.
 */

'use strict';

var path = require('path');
var util = require('util');
var css = require('@nuintun/css-deps');
var debug = require('debug')('gulp-css');
var gutil = require('@nuintun/gulp-util');

var join = path.join;

// set debug color use 6
debug.color = 6;

/**
 * rename
 *
 * @param {any} path
 * @param {any} transform
 * @returns {String}
 */
function rename(path, transform) {
  return gutil.rename(path, transform, debug);
}

/**
 * transport
 *
 * @param {any} vinyl
 * @param {any} options
 * @param {any} done
 * @returns {void}
 */
function transport(vinyl, options, done) {
  return gutil.transport(vinyl, options, done, debug);
}

/**
 * resolve
 *
 * @param {any} relative
 * @param {any} vinyl
 * @param {any} wwwroot
 * @returns {String}
 */
function resolve(relative, vinyl, wwwroot) {
  return gutil.resolve(relative, vinyl, wwwroot, debug);
}

/**
 * pring
 *
 * @returns {void}
 */
function print() {
  var message = gutil.apply(util.format, null, gutil.slice.call(arguments));

  process.stdout.write(gutil.colors.cyan.bold('  gulp-css ') + message + '\n');
}

/**
 * get rename options
 *
 * @param transform
 * @returns {object}
 */
function initRenameOptions(transform) {
  if (gutil.isFunction(transform)) {
    return transform;
  }

  transform = transform || {};

  if (transform.min) {
    transform.suffix = '-min';
  }

  if (transform.debug) {
    transform.suffix = '-debug';
  }

  return transform;
}

/**
 * init options
 *
 * @param options
 * @returns {object}
 */
function initOptions(options) {
  options = gutil.extend(true, {
    include: false, // include
    prefix: null, // css prefix
    onpath: null, // css resource path callback
    cache: true, // use memory file cahe
    wwwroot: '', // web root
    rename: null // { debug: boolean, min: boolean }
  }, options);

  // wwwroot must be string
  if (!gutil.isString(options.wwwroot)) {
    gutil.throwError('options.wwwroot\'s value should be string.');
  }

  // init wwwroot
  options.wwwroot = join(gutil.cwd, options.wwwroot);
  // init plugins
  options.plugins = gutil.plugins(options.plugins, require('./plugins/index'));
  // init rename
  options.rename = initRenameOptions(options.rename);

  return options;
}

/**
 * transport css dependencies.
 *
 * @param vinyl
 * @param options
 * @returns {Array}
 */
function transportCssDeps(vinyl, options) {
  var deps = [];
  var remote = [];
  var include = [];
  var pkg = vinyl.package || {};
  var onpath = options.onpath;
  var prefix = options.prefix;

  // init css settings
  onpath = gutil.isFunction(onpath) ? function(path, property) {
    return options.onpath(path, property, vinyl.path, options.wwwroot);
  } : null;

  prefix = gutil.isFunction(prefix) ? prefix(vinyl.path, options.wwwroot) : prefix;

  // replace imports and collect dependencies
  vinyl.contents = new Buffer(css(vinyl.contents, function(id) {
    var path;

    // id is not a local file
    if (!gutil.isLocal(id)) {
      // cache dependencie id
      deps.push(id);
      remote.push(id);
    } else {
      // normalize id
      id = gutil.normalize(id);

      // if end with /, find index file
      if (id.substring(id.length - 1) === '/') {
        id += 'index.css';
      }

      // set path
      path = id;
      // rename id
      id = rename(path, options.rename);

      // normalize id
      id = gutil.normalize(id);

      // debug
      debug('transport deps: %s', gutil.colors.magenta(id));

      // get absolute path
      path = resolve(path, vinyl, options.wwwroot);

      // cache dependencie id
      deps.push(id);
      // cache dependencie absolute path
      include.push(path);
    }

    // include import css file
    if (options.include) {
      // delete all import
      return false;
    }

    // onpath callback
    if (gutil.isString(path = onpath(id, 'import'))) {
      return path;
    }

    // don't make changes
    return id;
  }, { prefix: prefix, onpath: onpath }));

  // cache file dependencies
  vinyl.package = gutil.extend(pkg, {
    remote: remote,
    include: include,
    dependencies: deps
  });

  return deps;
}

/**
 * exports module
 */
module.exports = {
  debug: debug,
  rename: rename,
  transport: transport,
  resolve: resolve,
  print: print,
  initOptions: initOptions,
  transportCssDeps: transportCssDeps
};
<|endoftext|>


<commit_before>const util = {
    boundingBoxCollide({pos: {x: x1, y: y1}, width: w1, height: h1}, {pos: {x: x2, y: y2}, width: w2, height: h2}) {
        return x1 < x2 + w2
            && x1 + w1 > x2
            && y1 < y2 + h2
            && y1 + h1 > y2;
    }
};

export default util;
<commit_msg>Add five.util.rotateTransform(ctx, pos, rot) for easy rotation around an origin<commit_after>const DEG2RAD = 180 / Math.PI;

const util = {
    boundingBoxCollide({pos: {x: x1, y: y1}, width: w1, height: h1}, {pos: {x: x2, y: y2}, width: w2, height: h2}) {
        return x1 < x2 + w2
            && x1 + w1 > x2
            && y1 < y2 + h2
            && y1 + h1 > y2;
    },

    rotateTransform(ctx, {x, y}, rot) {
        ctx.translate(x, y);
        ctx.rotate(rot / DEG2RAD);
        ctx.translate(-x, -y);
    }
};

export default util;
<|endoftext|>