<commit_before>var through = require('through2');
var path = require('path');
var gulp = require('gulp');
var fs = require('fs');
var gutil = require('gulp-util');
var objectAssign = require('object-assign');
var PluginError = gutil.PluginError;
var File = gutil.File;

// Consts
const PLUGIN_NAME = 'sass-generate-contents';

function sassGenerateContents(destFilePath, creds, options){

	var defaults = {
		forceComments: true
	};
	var opts = objectAssign(defaults, options);
	var comments = '';
	var imports = '';
	var destFileName = getFileName(destFilePath);
	var newFile = createFile(destFilePath);
	var currentFilePath = '';
	var currentSection = '';
	var importArr = [];
	var commentsArr = [];
	var creds = typeof creds === 'object' ? creds : {};

	function getSpacer(len, spacer, minWidth){
		var spaceArr = [];
		var mw = minWidth || 0;
		var len = len + mw;
		for(var i = 0; i < len; i++){
			spaceArr.push(spacer);
		}

		return spaceArr.join('');
	}

	function getLongest(propList){
		var longest = 0;
		for (var prop in propList){
			if (propList.hasOwnProperty(prop)) {
				var propLength = prop.length
				if(propLength > longest) {
					longest = propLength;
				}
			}
		}
		return longest;
	}

	function createCreds(credsObj){

		var credStr = ['/* ============================================================ *\\\n'];
		credStr.push('  #MAIN\n')
		var count = 0;
		var credLongest = getLongest(credsObj);

		for (var cred in credsObj){
			if (credsObj.hasOwnProperty(cred)) {

				var val = credsObj[cred];
				var credLength = cred.length;
				var diff = credLongest - credLength;
				var spacer = getSpacer(diff, ' ');
				credStr.push('  ' + cred + ': ' + spacer + '' + val);

			}
		}
		credStr.push('\n/* ============================================================ *\\\n\n');

		return credStr;
	}

	function updateFile(newFile, imports, comments){
		// get the contents of the imports array
		if(importArr.indexOf(imports) < 0){
			//if the import doesn't exist add a new one
			importArr.push(imports);

		}

		var section = getSection(currentFilePath);
		if(section !== currentSection){
			currentSection = section;
			commentsArr.push('* \n* '+ currentSection.toUpperCase());
		}

		//get the contents of the comments array
		if(commentsArr.indexOf(comments) < 0){
			//if the comments don't exist add new ones
			commentsArr.push(comments);
		}

		// build site credentials iff passed in
		var credsArr = createCreds(creds);

		//Hack - quick array splitter
		var startArr = ['/**\n* CONTENTS'];
		var splitterArr = ['*\n*/\n\n\n\n'];
		var newContents = credsArr.concat(startArr, commentsArr, splitterArr, importArr).join('\n');

		newFile.contents = new Buffer(newContents);

		return;
	}

	function getSection(filePath){
		var fileDirArray = path.parse(filePath).dir.split(path.sep);

		return fileDirArray[fileDirArray.length - 1];
	}

	function getFileName(filePath) {
		return path.basename(filePath);
	}

	function createFile(destFilePath){
		var newFile = new gutil.File({
			cwd: '',
			base: '',
			path: destFileName,
			contents: new Buffer('')
		});

		return newFile;
	}

	function throwWarning(fileName){
		gutil.log(PLUGIN_NAME + ' Comments missing or malformed in file: ' + fileName + ' - File not included\n');
	}

	/* main function */

	function buildString(file, enc, cb){

		currentFilePath = file.path;

		var fileName = getFileName(currentFilePath);

		//don't read the destination path (if in same folder)
		if (fileName === destFileName) {
			cb();
			return;
		}

		if (file.isNull()) {
			cb();
			return;
		}

		if (file.isStream()) {
			cb(new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
			return;
		}

		var content = file.contents.toString('utf8');

		comments = content.split('\n')[0];
		var firstChars = comments.charAt(0) + comments.charAt(1);
		if(String(firstChars) !== '//' && opts.forceComments){
			throwWarning(fileName);
			return cb();
		}

		if(String(firstChars) !== '//' && !opts.forceComments){
			comments = '* ';
		}

		comments = comments.replace('//', '* ');

		imports = '@import "' + currentFilePath + '";';

		updateFile(newFile, imports, comments);

		this.push(newFile);
		return cb();
	};

	return through.obj(buildString);
}

module.exports = sassGenerateContents;
<commit_msg>fix: Use / for import paths to avoid escape char errors<commit_after>var through = require('through2');
var path = require('path');
var gulp = require('gulp');
var fs = require('fs');
var gutil = require('gulp-util');
var objectAssign = require('object-assign');
var PluginError = gutil.PluginError;
var File = gutil.File;

// Consts
const PLUGIN_NAME = 'sass-generate-contents';

function sassGenerateContents(destFilePath, creds, options){

	var defaults = {
		forceComments: true
	};
	var opts = objectAssign(defaults, options);
	var comments = '';
	var imports = '';
	var destFileName = getFileName(destFilePath);
	var newFile = createFile(destFilePath);
	var currentFilePath = '';
	var currentSection = '';
	var importArr = [];
	var commentsArr = [];
	var creds = typeof creds === 'object' ? creds : {};

	function getSpacer(len, spacer, minWidth){
		var spaceArr = [];
		var mw = minWidth || 0;
		var len = len + mw;
		for(var i = 0; i < len; i++){
			spaceArr.push(spacer);
		}

		return spaceArr.join('');
	}

	function getLongest(propList){
		var longest = 0;
		for (var prop in propList){
			if (propList.hasOwnProperty(prop)) {
				var propLength = prop.length
				if(propLength > longest) {
					longest = propLength;
				}
			}
		}
		return longest;
	}

	function createCreds(credsObj){

		var credStr = ['/* ============================================================ *\\\n'];
		credStr.push('  #MAIN\n')
		var count = 0;
		var credLongest = getLongest(credsObj);

		for (var cred in credsObj){
			if (credsObj.hasOwnProperty(cred)) {

				var val = credsObj[cred];
				var credLength = cred.length;
				var diff = credLongest - credLength;
				var spacer = getSpacer(diff, ' ');
				credStr.push('  ' + cred + ': ' + spacer + '' + val);

			}
		}
		credStr.push('\n/* ============================================================ *\\\n\n');

		return credStr;
	}

	function updateFile(newFile, imports, comments){
		// get the contents of the imports array
		if(importArr.indexOf(imports) < 0){
			//if the import doesn't exist add a new one
			importArr.push(imports);

		}

		var section = getSection(currentFilePath);
		if(section !== currentSection){
			currentSection = section;
			commentsArr.push('* \n* '+ currentSection.toUpperCase());
		}

		//get the contents of the comments array
		if(commentsArr.indexOf(comments) < 0){
			//if the comments don't exist add new ones
			commentsArr.push(comments);
		}

		// build site credentials iff passed in
		var credsArr = createCreds(creds);

		//Hack - quick array splitter
		var startArr = ['/**\n* CONTENTS'];
		var splitterArr = ['*\n*/\n\n\n\n'];
		var newContents = credsArr.concat(startArr, commentsArr, splitterArr, importArr).join('\n');

		newFile.contents = new Buffer(newContents);

		return;
	}

	function getSection(filePath){
		var fileDirArray = path.parse(filePath).dir.split(path.sep);

		return fileDirArray[fileDirArray.length - 1];
	}

	function getFileName(filePath) {
		return path.basename(filePath);
	}

	function createFile(destFilePath){
		var newFile = new gutil.File({
			cwd: '',
			base: '',
			path: destFileName,
			contents: new Buffer('')
		});

		return newFile;
	}

	function throwWarning(fileName){
		gutil.log(PLUGIN_NAME + ' Comments missing or malformed in file: ' + fileName + ' - File not included\n');
	}

	function generateImportString(filePath) {
		var pathArray = path.normalize(filePath).split(path.sep);

		return '@import "' + pathArray.join('/') + '";';
	}

	/* main function */

	function buildString(file, enc, cb){

		currentFilePath = file.path;

		var fileName = getFileName(currentFilePath);

		//don't read the destination path (if in same folder)
		if (fileName === destFileName) {
			cb();
			return;
		}

		if (file.isNull()) {
			cb();
			return;
		}

		if (file.isStream()) {
			cb(new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
			return;
		}

		var content = file.contents.toString('utf8');

		comments = content.split('\n')[0];
		var firstChars = comments.charAt(0) + comments.charAt(1);
		if(String(firstChars) !== '//' && opts.forceComments){
			throwWarning(fileName);
			return cb();
		}

		if(String(firstChars) !== '//' && !opts.forceComments){
			comments = '* ';
		}

		comments = comments.replace('//', '* ');

		imports = generateImportString(currentFilePath);

		updateFile(newFile, imports, comments);

		this.push(newFile);
		return cb();
	};

	return through.obj(buildString);
}

module.exports = sassGenerateContents;
<|endoftext|>


<commit_before>/*
 * fis
 * http://fis.baidu.com/
 */

function process(content){
    var reg = /\b(?:_\.Module\.|F)\.use\s*\(\s*("(?:[^\\"\r\n\f]|\\[\s\S])*"|'(?:[^\\'\n\r\f]|\\[\s\S])*'|(?:\[[^\[\]]+?\]))\s*|\brequires\s*:\s*\[([^\]]+)]|"(?:[^\\"\r\n\f]|\\[\s\S])*"|'(?:[^\\'\n\r\f]|\\[\s\S])*'|\/\/[^\r\n\f]+|\/\*[\s\S]*?(?:\*\/|$)/g;
    var lang = fis.compile.lang.require;
    return content.replace(reg, function(m, $1, $2){
        if($1 || $2){
            m = m.replace(/"(?:[^\\"\r\n\f]|\\[\s\S])*"|'(?:[^\\'\n\r\f]|\\[\s\S])*'/g, function(mm){
                return lang.ld + mm + lang.rd;
            });
        }
        return m;
    });
}

'use strict';
module.exports = function(content, file){
    if(file.isHtmlLike){
        var reg = /(<script(?:\s+[\s\S]*?["'\s\w\/]>|\s*>))([\s\S]*?)(?=<\/script>|$)/ig;
        return content.replace(reg, function(m, $1, $2){
            return $1 + process($2);
        });
    } else if(file.isJsLike){
        return process(content);
    }
};<commit_msg>hotfix<commit_after>/*
 * fis
 * http://fis.baidu.com/
 */

'use strict';

function process(content){
    var reg = /\b(?:_\.Module|F)\.use\s*\(\s*("(?:[^\\"\r\n\f]|\\[\s\S])*"|'(?:[^\\'\n\r\f]|\\[\s\S])*'|(?:\[[^\[\]]+?\]))\s*|\brequires\s*:\s*\[([^\]]+)]|"(?:[^\\"\r\n\f]|\\[\s\S])*"|'(?:[^\\'\n\r\f]|\\[\s\S])*'|\/\/[^\r\n\f]+|\/\*[\s\S]*?(?:\*\/|$)/g;
    var lang = fis.compile.lang.require;
    return content.replace(reg, function(m, $1, $2){
        if($1 || $2){
            m = m.replace(/"(?:[^\\"\r\n\f]|\\[\s\S])*"|'(?:[^\\'\n\r\f]|\\[\s\S])*'/g, function(mm){
                return lang.ld + mm + lang.rd;
            });
        }
        return m;
    });
}

module.exports = function(content, file){
    if(file.isHtmlLike){
        var reg = /(<script(?:\s+[\s\S]*?["'\s\w\/]>|\s*>))([\s\S]*?)(?=<\/script>|$)/ig;
        return content.replace(reg, function(m, $1, $2){
            return $1 + process($2);
        });
    } else if(file.isJsLike){
        return process(content);
    }
};<|endoftext|>


<commit_before>'use strict';

var fs = require('fs'),
  compass = require('./lib/compass'),
  through = require('through2'),
  gutil = require('gulp-util'),
  path = require('path');

// Consts
var PLUGIN_NAME = 'gulp-compass';

module.exports = function(opt) {
  var compile = function(file, enc, cb) {
    if (file.isNull()) {
      this.push(file);
      return cb();
    }

    if (file.isStream()) {
      this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
      return cb();
    }

    if (path.basename(file.path)[0] === '_') {
      return cb();
    }

    compass(file.path, opt, function(code, stdout, stderr, path) {
      if (code === 127) {
        this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'You need to have Ruby and Compass installed ' +
          'and in your system PATH for this task to work.'));
        return cb();
      }

      // support error callback
      if (code !== 0) {
        this.emit('error', new gutil.PluginError(PLUGIN_NAME, stdout || 'Compass failed', {fileName: file.path}));
        return cb();
      }

      // excute callback
      var pathToCss = gutil.replaceExtension(path, '.css'),
        contents = fs.readFileSync(pathToCss);

      // Fix garbled output.
      if (!(contents instanceof Buffer)) {
        contents = new Buffer(contents);
      }

      file.path = gutil.replaceExtension(file.path, '.css');
      file.contents = contents;
      this.push(file);
      cb();
    }.bind(this));
  };

  return through.obj(compile);
};
<commit_msg>tweaks<commit_after>'use strict';

var fs = require('fs'),
  compass = require('./lib/compass'),
  through = require('through2'),
  gutil = require('gulp-util'),
  path = require('path');

// Consts
var PLUGIN_NAME = 'gulp-compass';

module.exports = function(opt) {
  var compile = function(file, enc, cb) {
    if (file.isNull()) {
      cb(null, file);
      return;
    }

    if (file.isStream()) {
      cb(new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
      return;
    }

    if (path.basename(file.path)[0] === '_') {
      cb(null, file);
      return;
    }

    compass(file.path, opt, function(code, stdout, stderr, path) {
      if (code === 127) {
        cb(new gutil.PluginError(PLUGIN_NAME, 'You need to have Ruby and Compass installed ' +
          'and in your system PATH for this task to work.'));
        return;
      }

      // support error callback
      if (code !== 0) {
        cb(new gutil.PluginError(PLUGIN_NAME, stdout || 'Compass failed', {fileName: file.path}));
        return;
      }

      // excute callback
      var pathToCss = gutil.replaceExtension(path, '.css'),
        contents = fs.readFileSync(pathToCss);

      // Fix garbled output.
      if (!(contents instanceof Buffer)) {
        contents = new Buffer(contents);
      }

      file.path = gutil.replaceExtension(file.path, '.css');
      file.contents = contents;
      cb(null, file);
    });
  };

  return through.obj(compile);
};
<|endoftext|>


<commit_before>;(function (root, factory) {

  if (typeof define === 'function' && define.amd) {
    define(['ractive'], factory);
  } else if (typeof exports === 'object') {
    module.exports = factory(require('ractive'));
  } else {
    factory(root.Ractive);
  }

}(this, function (Ractive) {

  var Adaptor = Ractive.adaptors.Ractive = {
    filter: filter,
    wrap: wrap
  };

  /*
   * Advanced options:
   * You can adjust these settings via `Ractive.adaptors.Ractive.maxKeyLength`
   * and so on. There's usually no need to do that, but it may be good for
   * optimizing tests.
   */

  Adaptor.fireWrapEvents = true;
  Adaptor.maxKeyLength = 2048;

  /*
   * Ractive instance accessor methods that will be proxied by Ractive-Ractive.
   */

  var ractiveMethods = {
    add: {
      modifiesData: true,
      mapAllowed: false
    },
    animate: {
      modifiesData: true,
      mapAllowed: true
    },
    get: {
      modifiesData: false,
      mapAllowed: false
    },
    merge: {
      modifiesData: true,
      mapAllowed: false
    },
    observe: {
      modifiesData: false,
      mapAllowed: true
    },
    observeOnce: {
      modifiesData: false,
      mapAllowed: false
    },
    pop: {
      modifiesData: true,
      mapAllowed: false
    },
    push: {
      modifiesData: true,
      mapAllowed: false
    },
    set: {
      modifiesData: true,
      mapAllowed: true
    },
    shift: {
      modifiesData: true,
      mapAllowed: false
    },
    splice: {
      modifiesData: true,
      mapAllowed: false
    },
    subtract: {
      modifiesData: true,
      mapAllowed: false
    },
    toggle: {
      modifiesData: true,
      mapAllowed: false
    },
    unshift: {
      modifiesData: true,
      mapAllowed: false
    },
    update: {
      modifiesData: false,
      mapAllowed: false
    },
    updateModel: {
      modifiesData: false,
      mapAllowed: false
    }
  };

  /*
   * Check if the child is an Ractive instance.
   *
   * Also, if this key has been wrapped before, don't rewrap it. (Happens on
   * deeply-nested values, and .reset() for some reason.)
   */

  function filter (child, keypath, parent) {
    if (!(child instanceof Ractive))
      return false;

    if (parent &&
        parent._ractiveWraps &&
        parent._ractiveWraps[keypath])
      return false;

    return true;
  }

  /*
   * Global write lock.
   * This prevents infinite loops from happening where a parent will set a
   * value on the child, and the child will attempt to write back to the
   * parent, and so on.
   */

  var locked = Adaptor.locked = {};

  function lock (key, fn) {
    if (locked[key]) return;
    try {
      locked[key] = true;
      return fn();
    } finally {
      delete locked[key];
    }
  }

  /*
   * Returns a wrapped Adaptor for Ractive.
   * See: http://docs.ractivejs.org/latest/writing-adaptor-plugins
   */

  function wrap (parent, child, keypath, prefixer) {
    setup();

    return {
      get: get,
      set: set,
      reset: reset,
      teardown: teardown
    };

    /*
     * Initializes the adaptor.
     */

    function setup () {
      hookAccessors();
      checkForRecursion();
      markAsWrapped();
      child.on('change', onChange);

      if (Adaptor.fireWrapEvents) {
        child.fire('wrap', parent, keypath);
        parent.fire('wrapchild', child, keypath);
      }
    }

    function teardown () {
      delete parent._ractiveWraps[keypath];
      updateChildrenPattern();
      unhookAccessors();
      child.off('change', onChange);

      if (Adaptor.fireWrapEvents) {
        child.fire('unwrap', parent, keypath);
        parent.fire('unwrapchild', child, keypath);
      }
    }

    /*
     * Propagate changes from child to parent.
     * We well break it apart into key/vals and set those individually because
     * some values may be locked.
     */

    function onChange (updates) {
      each(updates, function (value, key) {
        lock(child._guid + key, function () {
          parent.set(keypath + '.' + key, value);
        });
      });
    }

    /*
     * Returns all attributes of the child, including computed properties.
     * See: https://github.com/ractivejs/ractive/issues/1250
     */

    function get () {
      // Optimization: if there are no computed properties, returning all
      // non-computed data should suffice.
      if (!child.computed) return child.get();

      var re = {};

      each(child.get(), function (val, key) {
        re[key] = val;
      });

      each(child.computed, function (_, key) {
        if (typeof re[key] === 'undefined')
          re[key] = child.get(key);
      });

      return re;
    }

    function set (key, value) {
      lock(child._guid + key, function () {
        child.set(key, value);
      });
    }

    /*
     * Allow setting values by passing a POJO to .set(), for instance,
     * `.set('child', { ... })`. If anything else is passed onto .set()
     * (like another Ractive instance, or another adaptor'able), destroy
     * this wrapper.
     */

    function reset (object) {
      if (object && object.constructor === Object) {
        child.set(object);
      } else {
        return false;
      }
    }

    /*
     * Update the parent's child key RegEx pattern used by accessors
     */

    function updateChildrenPattern () {
      if (!parent._ractiveWraps) {
        delete parent._childrenPattern;
        return;
      }

      // Collect the current `_ractiveWraps` keys
      parent._childKeys = [];
      each(parent._ractiveWraps, function (value, key) {
        parent._childKeys.push(key);
      });

      if (parent._childKeys.length === 0) {
        delete parent._childrenPattern;
        return;
      }

      parent._childrenPattern = new RegExp("^(" + parent._childKeys.join(")\\..+?|(") + ")\\..+?$");
    }

    /*
     * Generates a Ractive accessor proxy for the given method and configuration.
     */

    function generateAccessor(method, config) {
      config = config || {};

      return function (keypath) {
        var child;
        var childKey;
        var result;

        // Exit early if there aren't any children or we're not targeting a keypath
        if (parent._childrenPattern == null || keypath == null) {
          return parent["_" + method].apply(parent, arguments);
        }

        // Handle a `key, value` set
        if (isString(keypath) === true) {
           childKey = parseAccessorKey(keypath);
           child = parent._ractiveWraps[childKey];

          // The key isn't a child of parent
          if (child == null) {
            return parent["_" + method].apply(parent, arguments);
          }

          // Remove the root of the key before marshalling it to the child
          arguments[0] = arguments[0].replace(childKey + ".", "");
          result = child[method].apply(child, arguments);

          if (config.modifiesData === true) {
            parent._update(childKey + "." + arguments[0]);
          }

          return result;
        }

        // Handle when only a value object is passed to the Ractive instance
        if (config.mapAllowed === true) {
          // Filter out and marshall keys which apply to children
          each(keypath, function (value, key) {
            childKey = parseAccessorKey(keypath);
            child = parent._ractiveWraps[childKey];

            if (child == null) {
              return;
            }

            delete keypath[key];

            // Remove the root of the key before marshalling it to the child
            key = key.replace(childKey + ".", "");
            child[method].call(child, key, value);

            if (config.modifiesData === true) {
              parent._update(childKey + "." + key);
            }
          });
        }

        // Default behavior
        return parent["_" + method].apply(parent, arguments);
      };
    }

    /*
     * Check all children to see if there are any matches and return the result.
     */

    function parseAccessorKey(keypath) {
      if (parent._childrenPattern == null) {
        return;
      }

      var childKeys = parent._childrenPattern.exec(keypath);

      if (childKeys == null) {
        return;
      }

      return childKeys[1];
    }

    /*
     * Overwrite the original Ractive methods with Ractive-Ractive accessor proxies.
     */

    function hookAccessors () {
      // Only hook the accessors once
      if (parent._accessorsHooked === true) {
        return;
      }

      parent._accessorsHooked = true;

      each(ractiveMethods, function (config, method) {
        parent["_" + method] = parent[method];
        parent[method] = generateAccessor(method, config);
      });
    }

    /*
     * Replace the Ractive-Ractive accessor proxies with the original implementations.
     */

    function unhookAccessors () {
      // Only hook the accessors once
      if (parent._accessorsHooked !== true) {
        return;
      }

      delete parent._accessorsHooked;

      each(ractiveMethods, function (config, method) {
        parent[method] = parent["_" + method];
        delete parent["_" + method];
      });
    }

    /*
     * Die on recursion.
     * Keypath will look like 'child.sub.parent.child.sub.parent' ad nauseum.
     */

    function checkForRecursion () {
      if (keypath && keypath.length > Adaptor.maxKeyLength)
        throw new Error("Keypath too long (possible circular dependency)");
    }

    /*
     * Let future wrappers know what we have wrapped Ractive instances.
     * This value is used on `filter()`.
     */

    function markAsWrapped () {
      if (!parent._ractiveWraps) parent._ractiveWraps = {};
      parent._ractiveWraps[keypath] = child;
      updateChildrenPattern();
    }
  }

  /*
   * Cross-browser forEach helper
   */

  function each (obj, fn) {
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) fn(obj[key], key);
    }
  }

  /*
   * isString helper
   */

   function isString (string) {
    return typeof string == 'string' || (!!string && typeof string == 'object' && Object.prototype.toString.call(string) == '[object String]');
   }
}));
<commit_msg>fix: Only call unhookAccessors() if there are no more children registered to the parent<commit_after>;(function (root, factory) {

  if (typeof define === 'function' && define.amd) {
    define(['ractive'], factory);
  } else if (typeof exports === 'object') {
    module.exports = factory(require('ractive'));
  } else {
    factory(root.Ractive);
  }

}(this, function (Ractive) {

  var Adaptor = Ractive.adaptors.Ractive = {
    filter: filter,
    wrap: wrap
  };

  /*
   * Advanced options:
   * You can adjust these settings via `Ractive.adaptors.Ractive.maxKeyLength`
   * and so on. There's usually no need to do that, but it may be good for
   * optimizing tests.
   */

  Adaptor.fireWrapEvents = true;
  Adaptor.maxKeyLength = 2048;

  /*
   * Ractive instance accessor methods that will be proxied by Ractive-Ractive.
   */

  var ractiveMethods = {
    add: {
      modifiesData: true,
      mapAllowed: false
    },
    animate: {
      modifiesData: true,
      mapAllowed: true
    },
    get: {
      modifiesData: false,
      mapAllowed: false
    },
    merge: {
      modifiesData: true,
      mapAllowed: false
    },
    observe: {
      modifiesData: false,
      mapAllowed: true
    },
    observeOnce: {
      modifiesData: false,
      mapAllowed: false
    },
    pop: {
      modifiesData: true,
      mapAllowed: false
    },
    push: {
      modifiesData: true,
      mapAllowed: false
    },
    set: {
      modifiesData: true,
      mapAllowed: true
    },
    shift: {
      modifiesData: true,
      mapAllowed: false
    },
    splice: {
      modifiesData: true,
      mapAllowed: false
    },
    subtract: {
      modifiesData: true,
      mapAllowed: false
    },
    toggle: {
      modifiesData: true,
      mapAllowed: false
    },
    unshift: {
      modifiesData: true,
      mapAllowed: false
    },
    update: {
      modifiesData: false,
      mapAllowed: false
    },
    updateModel: {
      modifiesData: false,
      mapAllowed: false
    }
  };

  /*
   * Check if the child is an Ractive instance.
   *
   * Also, if this key has been wrapped before, don't rewrap it. (Happens on
   * deeply-nested values, and .reset() for some reason.)
   */

  function filter (child, keypath, parent) {
    if (!(child instanceof Ractive))
      return false;

    if (parent &&
        parent._ractiveWraps &&
        parent._ractiveWraps[keypath])
      return false;

    return true;
  }

  /*
   * Global write lock.
   * This prevents infinite loops from happening where a parent will set a
   * value on the child, and the child will attempt to write back to the
   * parent, and so on.
   */

  var locked = Adaptor.locked = {};

  function lock (key, fn) {
    if (locked[key]) return;
    try {
      locked[key] = true;
      return fn();
    } finally {
      delete locked[key];
    }
  }

  /*
   * Returns a wrapped Adaptor for Ractive.
   * See: http://docs.ractivejs.org/latest/writing-adaptor-plugins
   */

  function wrap (parent, child, keypath, prefixer) {
    setup();

    return {
      get: get,
      set: set,
      reset: reset,
      teardown: teardown
    };

    /*
     * Initializes the adaptor.
     */

    function setup () {
      hookAccessors();
      checkForRecursion();
      markAsWrapped();
      child.on('change', onChange);

      if (Adaptor.fireWrapEvents) {
        child.fire('wrap', parent, keypath);
        parent.fire('wrapchild', child, keypath);
      }
    }

    function teardown () {
      delete parent._ractiveWraps[keypath];
      updateChildrenPattern();

      if (parent._childKeys.length === 0) {
        unhookAccessors();
      }

      child.off('change', onChange);

      if (Adaptor.fireWrapEvents) {
        child.fire('unwrap', parent, keypath);
        parent.fire('unwrapchild', child, keypath);
      }
    }

    /*
     * Propagate changes from child to parent.
     * We well break it apart into key/vals and set those individually because
     * some values may be locked.
     */

    function onChange (updates) {
      each(updates, function (value, key) {
        lock(child._guid + key, function () {
          parent.set(keypath + '.' + key, value);
        });
      });
    }

    /*
     * Returns all attributes of the child, including computed properties.
     * See: https://github.com/ractivejs/ractive/issues/1250
     */

    function get () {
      // Optimization: if there are no computed properties, returning all
      // non-computed data should suffice.
      if (!child.computed) return child.get();

      var re = {};

      each(child.get(), function (val, key) {
        re[key] = val;
      });

      each(child.computed, function (_, key) {
        if (typeof re[key] === 'undefined')
          re[key] = child.get(key);
      });

      return re;
    }

    function set (key, value) {
      lock(child._guid + key, function () {
        child.set(key, value);
      });
    }

    /*
     * Allow setting values by passing a POJO to .set(), for instance,
     * `.set('child', { ... })`. If anything else is passed onto .set()
     * (like another Ractive instance, or another adaptor'able), destroy
     * this wrapper.
     */

    function reset (object) {
      if (object && object.constructor === Object) {
        child.set(object);
      } else {
        return false;
      }
    }

    /*
     * Update the parent's child key RegEx pattern used by accessors
     */

    function updateChildrenPattern () {
      if (!parent._ractiveWraps) {
        delete parent._childrenPattern;
        return;
      }

      // Collect the current `_ractiveWraps` keys
      parent._childKeys = [];
      each(parent._ractiveWraps, function (value, key) {
        parent._childKeys.push(key);
      });

      if (parent._childKeys.length === 0) {
        delete parent._childrenPattern;
        return;
      }

      parent._childrenPattern = new RegExp("^(" + parent._childKeys.join(")\\..+?|(") + ")\\..+?$");
    }

    /*
     * Generates a Ractive accessor proxy for the given method and configuration.
     */

    function generateAccessor(method, config) {
      config = config || {};

      return function (keypath) {
        var child;
        var childKey;
        var result;

        // Exit early if there aren't any children or we're not targeting a keypath
        if (parent._childrenPattern == null || keypath == null) {
          return parent["_" + method].apply(parent, arguments);
        }

        // Handle a `key, value` set
        if (isString(keypath) === true) {
           childKey = parseAccessorKey(keypath);
           child = parent._ractiveWraps[childKey];

          // The key isn't a child of parent
          if (child == null) {
            return parent["_" + method].apply(parent, arguments);
          }

          // Remove the root of the key before marshalling it to the child
          arguments[0] = arguments[0].replace(childKey + ".", "");
          result = child[method].apply(child, arguments);

          if (config.modifiesData === true) {
            parent._update(childKey + "." + arguments[0]);
          }

          return result;
        }

        // Handle when only a value object is passed to the Ractive instance
        if (config.mapAllowed === true) {
          // Filter out and marshall keys which apply to children
          each(keypath, function (value, key) {
            childKey = parseAccessorKey(keypath);
            child = parent._ractiveWraps[childKey];

            if (child == null) {
              return;
            }

            delete keypath[key];

            // Remove the root of the key before marshalling it to the child
            key = key.replace(childKey + ".", "");
            child[method].call(child, key, value);

            if (config.modifiesData === true) {
              parent._update(childKey + "." + key);
            }
          });
        }

        // Default behavior
        return parent["_" + method].apply(parent, arguments);
      };
    }

    /*
     * Check all children to see if there are any matches and return the result.
     */

    function parseAccessorKey(keypath) {
      if (parent._childrenPattern == null) {
        return;
      }

      var childKeys = parent._childrenPattern.exec(keypath);

      if (childKeys == null) {
        return;
      }

      return childKeys[1];
    }

    /*
     * Overwrite the original Ractive methods with Ractive-Ractive accessor proxies.
     */

    function hookAccessors () {
      // Only hook the accessors once
      if (parent._accessorsHooked === true) {
        return;
      }

      parent._accessorsHooked = true;

      each(ractiveMethods, function (config, method) {
        parent["_" + method] = parent[method];
        parent[method] = generateAccessor(method, config);
      });
    }

    /*
     * Replace the Ractive-Ractive accessor proxies with the original implementations.
     */

    function unhookAccessors () {
      // Only hook the accessors once
      if (parent._accessorsHooked !== true) {
        return;
      }

      delete parent._accessorsHooked;

      each(ractiveMethods, function (config, method) {
        parent[method] = parent["_" + method];
        delete parent["_" + method];
      });
    }

    /*
     * Die on recursion.
     * Keypath will look like 'child.sub.parent.child.sub.parent' ad nauseum.
     */

    function checkForRecursion () {
      if (keypath && keypath.length > Adaptor.maxKeyLength)
        throw new Error("Keypath too long (possible circular dependency)");
    }

    /*
     * Let future wrappers know what we have wrapped Ractive instances.
     * This value is used on `filter()`.
     */

    function markAsWrapped () {
      if (!parent._ractiveWraps) parent._ractiveWraps = {};
      parent._ractiveWraps[keypath] = child;
      updateChildrenPattern();
    }
  }

  /*
   * Cross-browser forEach helper
   */

  function each (obj, fn) {
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) fn(obj[key], key);
    }
  }

  /*
   * isString helper
   */

   function isString (string) {
    return typeof string == 'string' || (!!string && typeof string == 'object' && Object.prototype.toString.call(string) == '[object String]');
   }
}));
<|endoftext|>


<commit_before>var ls = require('ls-stream'),
    path = require('path'),
    through = require('through');

function lsHtml(dir) {
  var stream = through();

  process.nextTick(go);
  return stream;

  function go() {
  stream.queue('
\n');
  ls(dir)
    .on('data', function (data) {
      // if we receive a null or if we have recursed into a new dir, just terminate the stream
      if (data == null || path.dirname(data.path) !== dir) {
        done();
        return;
      }
      var objectName = path.basename(data.path),
          objectString = '
' + objectName + (data.stat.isDirectory() ? '/' : '') + '
\n';
      stream.queue(objectString);
    });
  }
  function done() {
    stream.queue('
\n');
    stream.queue(null);
  }
}

module.exports = lsHtml;
<commit_msg>add trailing slashes to directory links<commit_after>var ls = require('ls-stream'),
    path = require('path'),
    through = require('through');

function lsHtml(dir) {
  var stream = through();

  process.nextTick(go);
  return stream;

  function go() {
  stream.queue('
\n');
  ls(dir)
    .on('data', function (data) {
      // if we receive a null or if we have recursed into a new dir, just terminate the stream
      if (data == null || path.dirname(data.path) !== dir) {
        done();
        return;
      }
      var objectName = path.basename(data.path) + (data.stat.isDirectory() ? '/' : ''),
          objectString = '
' + objectName + '
\n';
      stream.queue(objectString);
    });
  }
  function done() {
    stream.queue('
\n');
    stream.queue(null);
  }
}

module.exports = lsHtml;
<|endoftext|>


<commit_before>var isBrowser = typeof window !== 'undefined',
    request = isBrowser ? require('./request') : require('request').defaults({ jar: true }),
    he = require('he'),
    after = require('after');

module.exports = suggest;

var urlBase = 'http://clients1.google.com/complete/search'
var resRegex = /^window\.google\.ac\.h\((.*)\)$/;
var userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36';
var reqId = 0;

function suggest(keyword, opts, cb) {
  if (typeof cb === 'undefined' && typeof opts === 'function') {
    cb = opts;
    opts = {};
  }

  if (typeof opts.client === 'undefined') {
    opts.client = 'heirloom-hp';
  }

  if (typeof opts.hl === 'undefined') {
    opts.hl = 'en';
  }

  if (typeof opts.cp === 'undefined') {
    opts.cp = keyword.length;
  }

  opts.levels = opts.levels || 0;
  if (opts.levels === 0) {
    doSuggest(keyword, opts, cb);
  } else if (opts.levels === 1) {
    var nA = 'a'.charCodeAt(0);
    var next = after(26, done);
    var results = [];

    for (var i = 0; i < 26; i++) {
      c = String.fromCharCode(nA + i);
      doSuggest(keyword + ' ' + c, opts, function (err, suggestions) {
        if (err) return next(err);
        results = results.concat(suggestions);
        next();
      });
    }
    function done () {
      cb(null, results);
    }
  } else {
    doSuggest(keyword, opts, cb);
  }
}

function doSuggest(keyword, opts, cb) {
  var qs = {
    client: opts.client,
    hl: opts.hl,
    gs_rn: 0,
    gs_ri: opts.client,
    cp: opts.cp,
    gs_id: (reqId++),
    q: keyword
  };

  if (opts.client === 'youtube') {
    qs.ds = 'yt'
  }
  request({
    url: urlBase,
    qs: qs,
    headers: { 'User-Agent': userAgent }
  }, function (err, res, body) {
    if (err) return cb(err);
    if (typeof body === 'string') {
      var m = resRegex.exec(body);
      try {
        body = m ? JSON.parse(m[1]) : [];
      } catch (err) {
        return cb(err);
      }
    }

    if (Array.isArray(body) && body.length) {
      var suggestions = body[1].map(function (item) {
        return he.decode(stripTags(item[0]));
      });
      return cb(null, suggestions);
    }

    cb(null, []);
  });
}

var stripTagsRegex = /\<\/?[^\>]+\>/g;
function stripTags(s) {
  return s.replace(stripTagsRegex, '');
}
<commit_msg>secure by default<commit_after>var isBrowser = typeof window !== 'undefined',
    request = isBrowser ? require('./request') : require('request').defaults({ jar: true }),
    he = require('he'),
    after = require('after');

module.exports = suggest;

var urlBase = 'https://clients1.google.com/complete/search'
var resRegex = /^window\.google\.ac\.h\((.*)\)$/;
var userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36';
var reqId = 0;

function suggest(keyword, opts, cb) {
  if (typeof cb === 'undefined' && typeof opts === 'function') {
    cb = opts;
    opts = {};
  }

  if (typeof opts.client === 'undefined') {
    opts.client = 'heirloom-hp';
  }

  if (typeof opts.hl === 'undefined') {
    opts.hl = 'en';
  }

  if (typeof opts.cp === 'undefined') {
    opts.cp = keyword.length;
  }

  opts.levels = opts.levels || 0;
  if (opts.levels === 0) {
    doSuggest(keyword, opts, cb);
  } else if (opts.levels === 1) {
    var nA = 'a'.charCodeAt(0);
    var next = after(26, done);
    var results = [];

    for (var i = 0; i < 26; i++) {
      c = String.fromCharCode(nA + i);
      doSuggest(keyword + ' ' + c, opts, function (err, suggestions) {
        if (err) return next(err);
        results = results.concat(suggestions);
        next();
      });
    }
    function done () {
      cb(null, results);
    }
  } else {
    doSuggest(keyword, opts, cb);
  }
}

function doSuggest(keyword, opts, cb) {
  var qs = {
    client: opts.client,
    hl: opts.hl,
    gs_rn: 0,
    gs_ri: opts.client,
    cp: opts.cp,
    gs_id: (reqId++),
    q: keyword
  };

  if (opts.client === 'youtube') {
    qs.ds = 'yt'
  }
  request({
    url: urlBase,
    qs: qs,
    headers: { 'User-Agent': userAgent }
  }, function (err, res, body) {
    if (err) return cb(err);
    if (typeof body === 'string') {
      var m = resRegex.exec(body);
      try {
        body = m ? JSON.parse(m[1]) : [];
      } catch (err) {
        return cb(err);
      }
    }

    if (Array.isArray(body) && body.length) {
      var suggestions = body[1].map(function (item) {
        return he.decode(stripTags(item[0]));
      });
      return cb(null, suggestions);
    }

    cb(null, []);
  });
}

var stripTagsRegex = /\<\/?[^\>]+\>/g;
function stripTags(s) {
  return s.replace(stripTagsRegex, '');
}
<|endoftext|>


<commit_before>/*!
 * helper-lookup <https://github.com/jonschlinkert/helper-lookup>
 *
 * Copyright (c) 2014-2015, Jon Schlinkert.
 * Licensed under the MIT license.
 */

'use strict';

var Lookup = require('lookup-deps');
var deps = new Lookup();

module.exports = function (options) {
  var helpers = {};

  for (var key in deps) {
    var fn = deps[key];

    if (typeof fn === 'function') {
      helpers[key] = function () {
        return fn.apply(deps, arguments);
      };
    }
  }

  return helpers;
};
<commit_msg>adds relevant methods from lookup-deps<commit_after>/*!
 * helper-lookup <https://github.com/jonschlinkert/helper-lookup>
 *
 * Copyright (c) 2014-2015, Jon Schlinkert.
 * Licensed under the MIT license.
 */

'use strict';

var Lookup = require('lookup-deps');
var deps = new Lookup();

exports.depsKeys = function(patterns) {
  return deps.depsKeys(patterns || '*');
};

exports.findPkg = function(patterns) {
  return deps.findPkg(patterns || '*');
};

exports.parent = function(patterns) {
  return deps.parent(patterns || '*');
};

exports.filter = function(patterns) {
  return deps.filter(patterns || '*');
};

exports.getParents = function(patterns) {
  return deps.getParents(patterns || '*');
};

exports.names = function(patterns) {
  return deps.names(patterns || '*');
};

exports.find = function(patterns) {
  return deps.find(patterns || '*');
};

exports.lookup = function(patterns) {
  return deps.lookup(patterns || '*');
};

exports.pkg = function(patterns) {
  return deps.pkg(patterns || '*');
};

exports.dependencies = function(patterns) {
  return deps.dependencies(patterns || '*');
};

exports.keywords = function(patterns) {
  return deps.keywords(patterns || '*');
};

exports.homepage = function(patterns) {
  return deps.homepage(patterns || '*');
};

exports.links = function(patterns) {
  return deps.links(patterns || '*');
};

exports.reflinks = function(patterns) {
  return deps.reflinks(patterns || '*');
};
<|endoftext|>


<commit_before>var express = require('express');
var Connection = require('./lib/droonga-protocol/connection').Connection;
var httpAdapter = require('./lib/adapter/http');
var socketIoAdapter = require('./lib/adapter/socket.io');
var dashboardUI = require('./lib/ui/dashboard');

function droonga(application, params) {
  params = params || {};

  params.connection = params.connection || new Connection(params);
  var connection = params.connection;

  params.prefix = params.prefix || '';
  params.prefix = params.prefix.replace(/\/$/, '');

  httpAdapter.register(application, params);

  if (params.server) {
    socketIoAdapter.register(application, params.server, params);
    params.server.on('close', function() {
      // The connection can be mocked/stubbed. We don't need to close
      // such a fake connection.
      if (typeof connection.close == 'function')
        connection.close();
    });
  }

  dashboardUI.register(application, params);

  application.connection = connection;
  application.emitMessage = connection.emitMessage.bind(connection); // shorthand
}

exports.initialize = droonga;
express.application.droonga = function(params) {
  droonga(this, params);
};

require('./lib/adapter/api').exportTo(exports);

exports.command = require('./lib/adapter/command');
exports.Cache = require('./lib/cache');
exports.middleware = {
  cacheStatistics: require('./lib/middleware/cache-statistics'),
  cache: require('./lib/middleware/cache')
};
<commit_msg>Close connection on server error<commit_after>var express = require('express');
var Connection = require('./lib/droonga-protocol/connection').Connection;
var httpAdapter = require('./lib/adapter/http');
var socketIoAdapter = require('./lib/adapter/socket.io');
var dashboardUI = require('./lib/ui/dashboard');

function droonga(application, params) {
  params = params || {};

  params.connection = params.connection || new Connection(params);
  var connection = params.connection;

  params.prefix = params.prefix || '';
  params.prefix = params.prefix.replace(/\/$/, '');

  httpAdapter.register(application, params);

  if (params.server) {
    socketIoAdapter.register(application, params.server, params);
    params.server.on('error', function(error) {
      connection.close();
    });
    params.server.on('close', function() {
      // The connection can be mocked/stubbed. We don't need to close
      // such a fake connection.
      if (typeof connection.close == 'function')
        connection.close();
    });
  }

  dashboardUI.register(application, params);

  application.connection = connection;
  application.emitMessage = connection.emitMessage.bind(connection); // shorthand
}

exports.initialize = droonga;
express.application.droonga = function(params) {
  droonga(this, params);
};

require('./lib/adapter/api').exportTo(exports);

exports.command = require('./lib/adapter/command');
exports.Cache = require('./lib/cache');
exports.middleware = {
  cacheStatistics: require('./lib/middleware/cache-statistics'),
  cache: require('./lib/middleware/cache')
};
<|endoftext|>


<commit_before>var traverse = module.exports = function (obj) {
    return new Traverse(obj);
};

function Traverse (obj) {
    this.value = obj;
}

Traverse.prototype.get = function (ps) {
    var node = this.value;
    for (var i = 0; i < ps.length; i ++) {
        var key = ps[i];
        if (!Object.hasOwnProperty.call(node, key)) {
            node = undefined;
            break;
        }
        node = node[key];
    }
    return node;
};

Traverse.prototype.has = function (ps) {
    var node = this.value;
    for (var i = 0; i < ps.length; i ++) {
        var key = ps[i];
        if (!Object.hasOwnProperty.call(node, key)) {
            return false;
        }
        node = node[key];
    }
    return true;
};

Traverse.prototype.set = function (ps, value) {
    var node = this.value;
    for (var i = 0; i < ps.length - 1; i ++) {
        var key = ps[i];
        if (!Object.hasOwnProperty.call(node, key)) node[key] = {};
        node = node[key];
    }
    node[ps[i]] = value;
    return value;
};

Traverse.prototype.map = function (cb) {
    return walk(this.value, cb, true);
};

Traverse.prototype.forEach = function (cb) {
    this.value = walk(this.value, cb, false);
    return this.value;
};

Traverse.prototype.reduce = function (cb, init) {
    var skip = arguments.length === 1;
    var acc = skip ? this.value : init;
    this.forEach(function (x) {
        if (!this.isRoot || !skip) {
            acc = cb.call(this, acc, x);
        }
    });
    return acc;
};

Traverse.prototype.paths = function () {
    var acc = [];
    this.forEach(function (x) {
        acc.push(this.path);
    });
    return acc;
};

Traverse.prototype.nodes = function () {
    var acc = [];
    this.forEach(function (x) {
        acc.push(this.node);
    });
    return acc;
};

Traverse.prototype.clone = function () {
    var parents = [], nodes = [];

    return (function clone (src) {
        for (var i = 0; i < parents.length; i++) {
            if (parents[i] === src) {
                return nodes[i];
            }
        }

        if (typeof src === 'object' && src !== null) {
            var dst = copy(src);

            parents.push(src);
            nodes.push(dst);

            forEach(Object_keys(src), function (key) {
                dst[key] = clone(src[key]);
            });

            parents.pop();
            nodes.pop();
            return dst;
        }
        else {
            return src;
        }
    })(this.value);
};

function walk (root, cb, immutable) {
    var path = [];
    var parents = [];
    var alive = true;

    return (function walker (node_) {
        var node = immutable ? copy(node_) : node_;
        var modifiers = {};

        var keepGoing = true;

        var state = {
            node : node,
            node_ : node_,
            path : [].concat(path),
            parent : parents[parents.length - 1],
            parents : parents,
            key : path.slice(-1)[0],
            isRoot : path.length === 0,
            level : path.length,
            circular : null,
            update : function (x, stopHere) {
                if (!state.isRoot) {
                    state.parent.node[state.key] = x;
                }
                state.node = x;
                if (stopHere) keepGoing = false;
            },
            'delete' : function (stopHere) {
                delete state.parent.node[state.key];
                if (stopHere) keepGoing = false;
            },
            remove : function (stopHere) {
                if (Array_isArray(state.parent.node)) {
                    state.parent.node.splice(state.key, 1);
                }
                else {
                    delete state.parent.node[state.key];
                }
                if (stopHere) keepGoing = false;
            },
            keys : null,
            before : function (f) { modifiers.before = f },
            after : function (f) { modifiers.after = f },
            pre : function (f) { modifiers.pre = f },
            post : function (f) { modifiers.post = f },
            stop : function () { alive = false },
            block : function () { keepGoing = false }
        };

        if (!alive) return state;

        if (typeof node === 'object' && node !== null) {
            state.keys = Object_keys(node);

            state.isLeaf = state.keys.length == 0;

            for (var i = 0; i < parents.length; i++) {
                if (parents[i].node_ === node_) {
                    state.circular = parents[i];
                    break;
                }
            }
        }
        else {
            state.isLeaf = true;
        }

        state.notLeaf = !state.isLeaf;
        state.notRoot = !state.isRoot;

        // use return values to update if defined
        var ret = cb.call(state, state.node);
        if (ret !== undefined && state.update) state.update(ret);

        if (modifiers.before) modifiers.before.call(state, state.node);

        if (!keepGoing) return state;

        if (typeof state.node == 'object'
        && state.node !== null && !state.circular) {
            parents.push(state);

            forEach(state.keys, function (key, i) {
                path.push(key);

                if (modifiers.pre) modifiers.pre.call(state, state.node[key], key);

                var child = walker(state.node[key]);
                if (immutable && Object.hasOwnProperty.call(state.node, key)) {
                    state.node[key] = child.node;
                }

                child.isLast = i == state.keys.length - 1;
                child.isFirst = i == 0;

                if (modifiers.post) modifiers.post.call(state, child);

                path.pop();
            });
            parents.pop();
        }

        if (modifiers.after) modifiers.after.call(state, state.node);

        return state;
    })(root).node;
}

function copy (src) {
    if (typeof src === 'object' && src !== null) {
        var dst;

        if (Array_isArray(src)) {
            dst = [];
        }
        else if (src instanceof Date) {
            dst = new Date(src);
        }
        else if (src instanceof Error) {
            dst = { message: src.message };
        }
        else if (src instanceof Boolean) {
            dst = new Boolean(src);
        }
        else if (src instanceof Number) {
            dst = new Number(src);
        }
        else if (src instanceof String) {
            dst = new String(src);
        }
        else if (Object.create && Object.getPrototypeOf) {
            dst = Object.create(Object.getPrototypeOf(src));
        }
        else if (src.__proto__ || src.constructor.prototype) {
            var proto = src.__proto__ || src.constructor.prototype || {};
            var T = function () {};
            T.prototype = proto;
            dst = new T;
            if (!dst.__proto__) dst.__proto__ = proto;
        }

        forEach(Object_keys(src), function (key) {
            dst[key] = src[key];
        });
        return dst;
    }
    else return src;
}

var Object_keys = Object.keys || function keys (obj) {
    var res = [];
    for (var key in obj) res.push(key)
    return res;
};

var Array_isArray = Array.isArray || function isArray (xs) {
    return Object.prototype.toString.call(xs) === '[object Array]';
};

var forEach = function (xs, fn) {
    if (xs.forEach) return xs.forEach(fn)
    else for (var i = 0; i < xs.length; i++) {
        fn(xs[i], i, xs);
    }
};

forEach(Object_keys(Traverse.prototype), function (key) {
    traverse[key] = function (obj) {
        var args = [].slice.call(arguments, 1);
        var t = new Traverse(obj);
        return t[key].apply(t, args);
    };
});
<commit_msg>check builtins using the toString.call trick<commit_after>var traverse = module.exports = function (obj) {
    return new Traverse(obj);
};

function Traverse (obj) {
    this.value = obj;
}

Traverse.prototype.get = function (ps) {
    var node = this.value;
    for (var i = 0; i < ps.length; i ++) {
        var key = ps[i];
        if (!Object.hasOwnProperty.call(node, key)) {
            node = undefined;
            break;
        }
        node = node[key];
    }
    return node;
};

Traverse.prototype.has = function (ps) {
    var node = this.value;
    for (var i = 0; i < ps.length; i ++) {
        var key = ps[i];
        if (!Object.hasOwnProperty.call(node, key)) {
            return false;
        }
        node = node[key];
    }
    return true;
};

Traverse.prototype.set = function (ps, value) {
    var node = this.value;
    for (var i = 0; i < ps.length - 1; i ++) {
        var key = ps[i];
        if (!Object.hasOwnProperty.call(node, key)) node[key] = {};
        node = node[key];
    }
    node[ps[i]] = value;
    return value;
};

Traverse.prototype.map = function (cb) {
    return walk(this.value, cb, true);
};

Traverse.prototype.forEach = function (cb) {
    this.value = walk(this.value, cb, false);
    return this.value;
};

Traverse.prototype.reduce = function (cb, init) {
    var skip = arguments.length === 1;
    var acc = skip ? this.value : init;
    this.forEach(function (x) {
        if (!this.isRoot || !skip) {
            acc = cb.call(this, acc, x);
        }
    });
    return acc;
};

Traverse.prototype.paths = function () {
    var acc = [];
    this.forEach(function (x) {
        acc.push(this.path);
    });
    return acc;
};

Traverse.prototype.nodes = function () {
    var acc = [];
    this.forEach(function (x) {
        acc.push(this.node);
    });
    return acc;
};

Traverse.prototype.clone = function () {
    var parents = [], nodes = [];

    return (function clone (src) {
        for (var i = 0; i < parents.length; i++) {
            if (parents[i] === src) {
                return nodes[i];
            }
        }

        if (typeof src === 'object' && src !== null) {
            var dst = copy(src);

            parents.push(src);
            nodes.push(dst);

            forEach(Object_keys(src), function (key) {
                dst[key] = clone(src[key]);
            });

            parents.pop();
            nodes.pop();
            return dst;
        }
        else {
            return src;
        }
    })(this.value);
};

function walk (root, cb, immutable) {
    var path = [];
    var parents = [];
    var alive = true;

    return (function walker (node_) {
        var node = immutable ? copy(node_) : node_;
        var modifiers = {};

        var keepGoing = true;

        var state = {
            node : node,
            node_ : node_,
            path : [].concat(path),
            parent : parents[parents.length - 1],
            parents : parents,
            key : path.slice(-1)[0],
            isRoot : path.length === 0,
            level : path.length,
            circular : null,
            update : function (x, stopHere) {
                if (!state.isRoot) {
                    state.parent.node[state.key] = x;
                }
                state.node = x;
                if (stopHere) keepGoing = false;
            },
            'delete' : function (stopHere) {
                delete state.parent.node[state.key];
                if (stopHere) keepGoing = false;
            },
            remove : function (stopHere) {
                if (Array_isArray(state.parent.node)) {
                    state.parent.node.splice(state.key, 1);
                }
                else {
                    delete state.parent.node[state.key];
                }
                if (stopHere) keepGoing = false;
            },
            keys : null,
            before : function (f) { modifiers.before = f },
            after : function (f) { modifiers.after = f },
            pre : function (f) { modifiers.pre = f },
            post : function (f) { modifiers.post = f },
            stop : function () { alive = false },
            block : function () { keepGoing = false }
        };

        if (!alive) return state;

        if (typeof node === 'object' && node !== null) {
            state.keys = Object_keys(node);

            state.isLeaf = state.keys.length == 0;

            for (var i = 0; i < parents.length; i++) {
                if (parents[i].node_ === node_) {
                    state.circular = parents[i];
                    break;
                }
            }
        }
        else {
            state.isLeaf = true;
        }

        state.notLeaf = !state.isLeaf;
        state.notRoot = !state.isRoot;

        // use return values to update if defined
        var ret = cb.call(state, state.node);
        if (ret !== undefined && state.update) state.update(ret);

        if (modifiers.before) modifiers.before.call(state, state.node);

        if (!keepGoing) return state;

        if (typeof state.node == 'object'
        && state.node !== null && !state.circular) {
            parents.push(state);

            forEach(state.keys, function (key, i) {
                path.push(key);

                if (modifiers.pre) modifiers.pre.call(state, state.node[key], key);

                var child = walker(state.node[key]);
                if (immutable && Object.hasOwnProperty.call(state.node, key)) {
                    state.node[key] = child.node;
                }

                child.isLast = i == state.keys.length - 1;
                child.isFirst = i == 0;

                if (modifiers.post) modifiers.post.call(state, child);

                path.pop();
            });
            parents.pop();
        }

        if (modifiers.after) modifiers.after.call(state, state.node);

        return state;
    })(root).node;
}

function copy (src) {
    if (typeof src === 'object' && src !== null) {
        var dst;

        if (Array_isArray(src)) {
            dst = [];
        }
        else if (isDate(src)) {
            dst = new Date(src);
        }
        else if (isRegExp(src)) {
            dst = new RegExp(src);
        }
        else if (isError(src)) {
            dst = { message: src.message };
        }
        else if (isBoolean(src)) {
            dst = new Boolean(src);
        }
        else if (isNumber(src)) {
            dst = new Number(src);
        }
        else if (isString(src)) {
            dst = new String(src);
        }
        else if (Object.create && Object.getPrototypeOf) {
            dst = Object.create(Object.getPrototypeOf(src));
        }
        else if (src.__proto__ || src.constructor.prototype) {
            var proto = src.__proto__ || src.constructor.prototype || {};
            var T = function () {};
            T.prototype = proto;
            dst = new T;
            if (!dst.__proto__) dst.__proto__ = proto;
        }

        forEach(Object_keys(src), function (key) {
            dst[key] = src[key];
        });
        return dst;
    }
    else return src;
}

var Object_keys = Object.keys || function keys (obj) {
    var res = [];
    for (var key in obj) res.push(key)
    return res;
};

function toS (obj) { return Object.prototype.toString.call(obj) }
function isDate (obj) { return toS(obj) === '[object Date]' }
function isRegExp (obj) { return toS(obj) === '[object RegExp]' }
function isError (obj) { return toS(obj) === '[object Error]' }
function isBoolean (obj) { return toS(obj) === '[object Boolean]' }
function isNumber (obj) { return toS(obj) === '[object Number]' }
function isString (obj) { return toS(obj) === '[object String]' }

var Array_isArray = Array.isArray || function isArray (xs) {
    return Object.prototype.toString.call(xs) === '[object Array]';
};

var forEach = function (xs, fn) {
    if (xs.forEach) return xs.forEach(fn)
    else for (var i = 0; i < xs.length; i++) {
        fn(xs[i], i, xs);
    }
};

forEach(Object_keys(Traverse.prototype), function (key) {
    traverse[key] = function (obj) {
        var args = [].slice.call(arguments, 1);
        var t = new Traverse(obj);
        return t[key].apply(t, args);
    };
});
<|endoftext|>


<commit_before>/**
 * Reddit as a commenting system backend.
 * @module reddit-comments
 */

/**
 * Module dependencies.
 */
var Reddit = require('reddit-api'),
    Emitter = require('emitter'),
    events = require('event'),
    $ = require('helix'),
    render = require('./templates/comment'),
    cache = require('ls-cache'),
    extend = require('extend'),
    vagueTime = require('vague-time');

exports = module.exports = init;

var api = new Reddit();

/**
 * Module initialization function.
 *
 * @borrows RedditComments as init
 * @alias module:reddit-comments
 * @public
 */
function init(frame, options) {
    try {
        var rc = new RedditComments(frame, options);
    } catch (e) {
        console.log(e.toString());
        return;
    }
    rc.init();
    return rc;
}

/**
 * Generate a hash code from a string.
 *
 * @link http://stackoverflow.com/a/7616484
 * @return {number}
 */
String.prototype.hashCode = function(){
    var hash = 0, i, char;
    if (this.length == 0) return hash;
    for (i = 0, l = this.length; i < l; i++) {
        char  = this.charCodeAt(i);
        hash  = ((hash<<5)-hash)+char;
        hash |= 0; // Convert to 32bit integer
    }
    return hash;
};

Object.defineProperty($().constructor.prototype, "addEventListener", {
    value: function (event, callback, useCapture) {
        useCapture = ( !! useCapture) | false;
        for (var i = 0; i < this.length; ++i) {
            if (this[i] instanceof Node) {
                this[i].addEventListener(event, callback, useCapture);
            }
        }
        return this;
    }
});

/**
 * Main module object.
 *
 * @param {String} frame - A CSS selector of the element to be populated by comments.
 * @param {Object} options - Module configuration.
 * @param {String} options.subreddit - The subreddit name.
 * @param {String} [options.url=document.URL] - The URL to retrieve comments for.
 * @param {number} [options.commentsCacheExpiration=5] - Expiration time for
 *     retrieved comments in the `localStorage` cache.
 * @constructor
 * @private
 */
function RedditComments(frame, options) {
    var defaultOptions = {
        url: document.URL,
        commentsCacheExpiration: 5
    };
    if (!('subreddit' in (options || {}))) {
        throw new TypeError('Must specify a "subreddit"');
    }
    api.subreddit = options.subreddit;
    this.options = extend(defaultOptions, options);
    this.frame = $(frame);
    return this;
};

/**
 * Object initialization function.
 *
 * Displays retrieved comments.
 */
RedditComments.prototype.init = function() {
    var rc = this;

    rc.getUrlId(rc.options.url).then(function(urlId) {
        return rc.getComments(urlId);
    }).then(function(comments) {
        rc.renderComments(comments);

        // Setup click handlers
        function toggleComment(e) {
            e.preventDefault();
            rc.toggleComment(e.target.parentElement);
        }
        events.bind($('.rc-collapse'), 'click', toggleComment);

        // Prepend Reddit's URL to links beginning with '/r/' and '/u/'
        var specialLinks = rc.frame.find('a[href^="/r/"], a[href^="/u/"]');
        for (var i = 0; i < specialLinks.length; ++i) {
            var t = $(specialLinks[i]);
            t.attr('href', 'http://www.reddit.com' + t.attr('href'));
        }
    });
};

/**
 * Logs in a Reddit user.
 *
 * @param {String} username
 * @param {String} password
 */
RedditComments.prototype.login = function(username, password) {
};

/**
 * Logs out a Reddit user.
 */
RedditComments.prototype.logout = function() {
};

/**
 * Posts a comment on the Reddit post.
 *
 * @param {String} body - The comment body.
 */
RedditComments.prototype.comment = function(body) {
};

/**
 * Get the comments associated with a URL.
 *
 * @param {String} urlId - Reddit's ID36 of a URL.
 */
RedditComments.prototype.getComments = function(urlId) {
    var rc = this,
        hash = urlId.hashCode().toString(),
        comments = cache.get(hash);

    if (comments != null) {
        // Fake Promise to match the API
        return {
            then: function(resolve, reject) {return resolve(comments);}
        }
    }

    return api.getComments(urlId).then(function(res) {
        var data = JSON.parse(res || {}),
            comments = rc.extractComments(data);
        cache.set(hash, comments, rc.options.commentsCacheExpiration);
        return comments;
    });
};

/**
 * Extract the comment data from Reddit's response and process it for
 * rendering.
 *
 * @param {Object} data - The data as returned by the Reddit API.
 */
RedditComments.prototype.extractComments = function(data) {
    var rc = this,
        cData = [];

    function cleanCommentBody(body) {
        // Unescape the HTML
        var el = document.createElement('div');
        el.innerHTML = c.body_html;
        var unescapedHTML = el.childNodes.length === 0 ?
                                '' : el.childNodes[0].nodeValue;

        // Reddit's API returns the comment's HTML body wrapped in a
        // `<div class="md"></div>` element. We unwrap it here.
        var el = document.createElement('div');
        el.innerHTML = unescapedHTML;
        var unwrappedHTML = el.childNodes.length === 0 ?
                                '' : el.childNodes[0].innerHTML;
        return unwrappedHTML;
    }

    data = (data[1] || data);
    if (!data.data.children) return cData;
    data = data.data.children;
    for (var i = 0; i < data.length; ++i) {
        if (data[i].kind != "t1") continue;
        var replies = [],
            c = data[i].data,
            date = new Date(0),
            cleanBody = cleanCommentBody(c.body_html),
            vt;
        if (c.replies) {
            replies = rc.extractComments(c.replies);
        }
        date.setUTCSeconds(c.created_utc);
        vt = vagueTime.get({to: date});
        cData.push({author: c.author,
                    created_vague: vt,
                    created_timestamp: date,
                    replies: replies,
                    score: c.ups - c.downs, // XXX: Where is c.score?
                    body: cleanBody});
    }
    return cData;
};

/**
 * Given a URL, get its ID36.
 *
 * ID36 is the unique ID used by Reddit.
 * @see http://www.reddit.com/dev/api#fullnames
 *
 * @param {String} url
 */
RedditComments.prototype.getUrlId = function(url) {
    var rc = this,
        hash = url.hashCode().toString(),
        urlId = cache.get(hash);

    if (urlId != null) {
        // Fake Promise to match the API
        return {
            then: function(resolve, reject) {return resolve(urlId);}
        }
    }

    return api.getInfo({url: url}).then(function(res) {
        var data = JSON.parse(res || {}).data,
            urlId = rc.extractUrlId(data);
        cache.set(hash, urlId);
        return urlId;
    });
};

/**
 * Extract the URL's ID36 from Reddit's response.
 *
 * @param {Object} data - The data as returned by the Reddit API.
 */
RedditComments.prototype.extractUrlId = function(data) {
    var rc = this;

    if (data && data.children.length) {
        var linkData = data.children[0].data;
        if (!(linkData.subreddit == rc.options.subreddit)) {
            console.log("Post doesn't belong to this subreddit");
        } else {
            return linkData.id;
        }
    }
};

/**
 * Render a list of comments.
 *
 * @param {Array} comments - A collection of comments as returned by
 *     `extractComments()`.
 */
RedditComments.prototype.renderComments = function(comments) {
    var rc = this,
        frame = rc.frame,
        out = '';
    for (var i = 0; i < comments.length; ++i) {
        out += rc.renderComment(comments[i]);
    };
    frame.html(out);
};

/**
 * Render a single comment.
 *
 * If there are nested comments, this function will call itself recursively.
 *
 * @param {Object} c - A comment object.
 */
RedditComments.prototype.renderComment = function(c) {
    var rc = this, replies = '';
    for (var i = 0; i < c.replies.length; ++i) {
        replies += rc.renderComment(c.replies[i]);
    };
    c.replies = replies;
    return render(c);
};

/**
 * Display or hide a comment.
 *
 * @param {Object} c - A comment object.
 */
RedditComments.prototype.toggleComment = function(c) {
    var $c = $(c);
    // XXX: This acts like find(). See https://github.com/imiric/helix/issues/1
    $c.children('.rc-comment, .rc-vote').toggle();
    $c.children('.rc-collapse').toggleClass('rc-icon-vert');
    $c.find('.reddit-comment').toggle();
};
<commit_msg>Only set cache and fetch comments if the previous call succeeded<commit_after>/**
 * Reddit as a commenting system backend.
 * @module reddit-comments
 */

/**
 * Module dependencies.
 */
var Reddit = require('reddit-api'),
    Emitter = require('emitter'),
    events = require('event'),
    $ = require('helix'),
    render = require('./templates/comment'),
    cache = require('ls-cache'),
    extend = require('extend'),
    vagueTime = require('vague-time');

exports = module.exports = init;

var api = new Reddit();

/**
 * Module initialization function.
 *
 * @borrows RedditComments as init
 * @alias module:reddit-comments
 * @public
 */
function init(frame, options) {
    try {
        var rc = new RedditComments(frame, options);
    } catch (e) {
        console.log(e.toString());
        return;
    }
    rc.init();
    return rc;
}

/**
 * Generate a hash code from a string.
 *
 * @link http://stackoverflow.com/a/7616484
 * @return {number}
 */
String.prototype.hashCode = function(){
    var hash = 0, i, char;
    if (this.length == 0) return hash;
    for (i = 0, l = this.length; i < l; i++) {
        char  = this.charCodeAt(i);
        hash  = ((hash<<5)-hash)+char;
        hash |= 0; // Convert to 32bit integer
    }
    return hash;
};

Object.defineProperty($().constructor.prototype, "addEventListener", {
    value: function (event, callback, useCapture) {
        useCapture = ( !! useCapture) | false;
        for (var i = 0; i < this.length; ++i) {
            if (this[i] instanceof Node) {
                this[i].addEventListener(event, callback, useCapture);
            }
        }
        return this;
    }
});

/**
 * Main module object.
 *
 * @param {String} frame - A CSS selector of the element to be populated by comments.
 * @param {Object} options - Module configuration.
 * @param {String} options.subreddit - The subreddit name.
 * @param {String} [options.url=document.URL] - The URL to retrieve comments for.
 * @param {number} [options.commentsCacheExpiration=5] - Expiration time for
 *     retrieved comments in the `localStorage` cache.
 * @constructor
 * @private
 */
function RedditComments(frame, options) {
    var defaultOptions = {
        url: document.URL,
        commentsCacheExpiration: 5
    };
    if (!('subreddit' in (options || {}))) {
        throw new TypeError('Must specify a "subreddit"');
    }
    api.subreddit = options.subreddit;
    this.options = extend(defaultOptions, options);
    this.frame = $(frame);
    return this;
};

/**
 * Object initialization function.
 *
 * Displays retrieved comments.
 */
RedditComments.prototype.init = function() {
    var rc = this;

    rc.getUrlId(rc.options.url).then(function(urlId) {
        if (urlId) return rc.getComments(urlId);
    }).then(function(comments) {
        if (!comments) return;

        rc.renderComments(comments);

        // Setup click handlers
        function toggleComment(e) {
            e.preventDefault();
            rc.toggleComment(e.target.parentElement);
        }
        events.bind($('.rc-collapse'), 'click', toggleComment);

        // Prepend Reddit's URL to links beginning with '/r/' and '/u/'
        var specialLinks = rc.frame.find('a[href^="/r/"], a[href^="/u/"]');
        for (var i = 0; i < specialLinks.length; ++i) {
            var t = $(specialLinks[i]);
            t.attr('href', 'http://www.reddit.com' + t.attr('href'));
        }
    });
};

/**
 * Logs in a Reddit user.
 *
 * @param {String} username
 * @param {String} password
 */
RedditComments.prototype.login = function(username, password) {
};

/**
 * Logs out a Reddit user.
 */
RedditComments.prototype.logout = function() {
};

/**
 * Posts a comment on the Reddit post.
 *
 * @param {String} body - The comment body.
 */
RedditComments.prototype.comment = function(body) {
};

/**
 * Get the comments associated with a URL.
 *
 * @param {String} urlId - Reddit's ID36 of a URL.
 */
RedditComments.prototype.getComments = function(urlId) {
    var rc = this,
        hash = urlId.hashCode().toString(),
        comments = cache.get(hash);

    if (comments != null) {
        // Fake Promise to match the API
        return {
            then: function(resolve, reject) {return resolve(comments);}
        }
    }

    return api.getComments(urlId).then(function(res) {
        var data = JSON.parse(res || {}),
            comments = rc.extractComments(data);
        if (comments) cache.set(hash, comments, rc.options.commentsCacheExpiration);
        return comments;
    });
};

/**
 * Extract the comment data from Reddit's response and process it for
 * rendering.
 *
 * @param {Object} data - The data as returned by the Reddit API.
 */
RedditComments.prototype.extractComments = function(data) {
    var rc = this,
        cData = [];

    function cleanCommentBody(body) {
        // Unescape the HTML
        var el = document.createElement('div');
        el.innerHTML = c.body_html;
        var unescapedHTML = el.childNodes.length === 0 ?
                                '' : el.childNodes[0].nodeValue;

        // Reddit's API returns the comment's HTML body wrapped in a
        // `<div class="md"></div>` element. We unwrap it here.
        var el = document.createElement('div');
        el.innerHTML = unescapedHTML;
        var unwrappedHTML = el.childNodes.length === 0 ?
                                '' : el.childNodes[0].innerHTML;
        return unwrappedHTML;
    }

    data = (data[1] || data);
    if (!data.data.children) return cData;
    data = data.data.children;
    for (var i = 0; i < data.length; ++i) {
        if (data[i].kind != "t1") continue;
        var replies = [],
            c = data[i].data,
            date = new Date(0),
            cleanBody = cleanCommentBody(c.body_html),
            vt;
        if (c.replies) {
            replies = rc.extractComments(c.replies);
        }
        date.setUTCSeconds(c.created_utc);
        vt = vagueTime.get({to: date});
        cData.push({author: c.author,
                    created_vague: vt,
                    created_timestamp: date,
                    replies: replies,
                    score: c.ups - c.downs, // XXX: Where is c.score?
                    body: cleanBody});
    }
    return cData;
};

/**
 * Given a URL, get its ID36.
 *
 * ID36 is the unique ID used by Reddit.
 * @see http://www.reddit.com/dev/api#fullnames
 *
 * @param {String} url
 */
RedditComments.prototype.getUrlId = function(url) {
    var rc = this,
        hash = url.hashCode().toString(),
        urlId = cache.get(hash);

    if (urlId != null) {
        // Fake Promise to match the API
        return {
            then: function(resolve, reject) {return resolve(urlId);}
        }
    }

    return api.getInfo({url: url}).then(function(res) {
        var data = JSON.parse(res || {}).data,
            urlId = rc.extractUrlId(data);
        if (urlId) cache.set(hash, urlId);
        return urlId;
    });
};

/**
 * Extract the URL's ID36 from Reddit's response.
 *
 * @param {Object} data - The data as returned by the Reddit API.
 */
RedditComments.prototype.extractUrlId = function(data) {
    var rc = this;

    if (data && data.children.length) {
        var linkData = data.children[0].data;
        if (!(linkData.subreddit == rc.options.subreddit)) {
            console.log("Post doesn't belong to this subreddit");
        } else {
            return linkData.id;
        }
    }
};

/**
 * Render a list of comments.
 *
 * @param {Array} comments - A collection of comments as returned by
 *     `extractComments()`.
 */
RedditComments.prototype.renderComments = function(comments) {
    var rc = this,
        frame = rc.frame,
        out = '';
    for (var i = 0; i < comments.length; ++i) {
        out += rc.renderComment(comments[i]);
    };
    frame.html(out);
};

/**
 * Render a single comment.
 *
 * If there are nested comments, this function will call itself recursively.
 *
 * @param {Object} c - A comment object.
 */
RedditComments.prototype.renderComment = function(c) {
    var rc = this, replies = '';
    for (var i = 0; i < c.replies.length; ++i) {
        replies += rc.renderComment(c.replies[i]);
    };
    c.replies = replies;
    return render(c);
};

/**
 * Display or hide a comment.
 *
 * @param {Object} c - A comment object.
 */
RedditComments.prototype.toggleComment = function(c) {
    var $c = $(c);
    // XXX: This acts like find(). See https://github.com/imiric/helix/issues/1
    $c.children('.rc-comment, .rc-vote').toggle();
    $c.children('.rc-collapse').toggleClass('rc-icon-vert');
    $c.find('.reddit-comment').toggle();
};
<|endoftext|>


<commit_before>
var path = require('path');
var fs = require('fs');

// clean up paths for convenient loading
function normalize(filepath) {

    // resolve to an absolute ppath
    if (!path.isAbsolute(filepath))
        filepath = path.resolve(path.dirname(module.parent.filename), filepath);

    // tack .json on the end if need be
    if (!/.json$/.test(filepath))
        filepath = filepath + '.json';

    return filepath;
}

// process line-delimited files
function parse(contents, retained) {
    var errors = [], data = [], lines = 0;

    // process each line of the file
    contents.toString().split('\n').forEach(function(line) {
        if (!line) return;
        lines++;
        try {
            data.push(JSON.parse(line));
        } catch (e) {
            e.line = line;
            errors.push(e);
        }
    });

    // if no errors/data, don't return an empty array
    var ret = {};
    if (errors.length) ret.errors = errors;
    if (data.length) ret.data = data;

    // if every line failed, probably not line-delimited
    if (errors.length == lines) ret.errors = retained;

    return ret;
}

function load(path, cb) {
    path = normalize(path);

    // simple style
    var err;
    try { return cb(null, require(path)); } catch (e) { err = e; }

    // line-delimited
    fs.readFile(path, function(e, contents) {
        if (e) return cb(e);
        var res = parse(contents, err);
        cb(res.errors, res.data);
    });
}

function sync(path) {
    path = normalize(path);

    // simple
    var err;
    try { return require(path); } catch (e) { err = e; }

    // line-delimited
    var contents = fs.readFileSync(path);
    var res = parse(contents, err);
    if (res.errors) throw res.errors;
    return res.data;
}

load.sync = sync;
module.exports = load;
<commit_msg>fixing a problem with the filepath detector<commit_after>
var path = require('path');
var fs = require('fs');

// clean up paths for convenient loading
function normalize(filepath) {

    // resolve to an absolute ppath
    if (!path.isAbsolute(filepath))
        filepath = path.resolve(path.dirname(module.parent.filename), filepath);

    // tack .json on the end if need be
    if (!/\.json$/.test(filepath))
        filepath = filepath + '.json';

    return filepath;
}

// process line-delimited files
function parse(contents, retained) {
    var errors = [], data = [], lines = 0;

    // process each line of the file
    contents.toString().split('\n').forEach(function(line) {
        if (!line) return;
        lines++;
        try {
            data.push(JSON.parse(line));
        } catch (e) {
            e.line = line;
            errors.push(e);
        }
    });

    // if no errors/data, don't return an empty array
    var ret = {};
    if (errors.length) ret.errors = errors;
    if (data.length) ret.data = data;

    // if every line failed, probably not line-delimited
    if (errors.length == lines) ret.errors = retained;

    return ret;
}

function load(path, cb) {
    path = normalize(path);

    // simple style
    var err;
    try { return cb(null, require(path)); } catch (e) { err = e; }

    // line-delimited
    fs.readFile(path, function(e, contents) {
        if (e) return cb(e);
        var res = parse(contents, err);
        cb(res.errors, res.data);
    });
}

function sync(path) {
    path = normalize(path);

    // simple
    var err;
    try { return require(path); } catch (e) { err = e; }

    // line-delimited
    var contents = fs.readFileSync(path);
    var res = parse(contents, err);
    if (res.errors) throw res.errors;
    return res.data;
}

load.sync = sync;
module.exports = load;
<|endoftext|>


<commit_before>class LinearSystem {
  constructor(matrix) {
    //input should be a array of array of ints
    if ( ! Array.isArray(matrix)) {
      throw 'not array type error';
    }
    const hight = matrix.length;
    matrix.forEach(function(row){
      if ( ! Array.isArray(row)) {
        throw 'not array type error';
      }
      //checks if input matrix is ( column.length + 1 == rows.length )
      if ( hight + 1 != row.length ) {
        throw 'not in required shape (width == hight + 1)';
      }
      row.forEach(function(entry){
        if ( ! Number.isInteger(entry)) {
          throw 'not a integer error';
        }
      });
    });
    this._systemState = matrix;
    this._pivotColumn = undefined;
    this._pivot = {
      row: undefined,
      column: undefined
    };
    this._isEchelonForm = undefined;
    this._isReducedEchelonForm = undefined;
  }
  solve(){
    // 1. the left most non-zero column is the _pivotColumn
    //try first column, iterate until a column has a non-zero int in it
    let isNonZero = false;
    for (var i = 0; i < this._systemState.length; i++) {
      let thisColumn = this._systemState.map(function(value) {
        return value[i];
      });
      isNonZero = thisColumn.some(function(entry){
        return Math.abs(entry) > 0
      });
      if (isNonZero) {
        this._pivotColumn = i;
        break;
      }
    }
    //if there isn't a non-zero column then the set is empty and has no solutions
    if ( undefined === this._pivotColumn) {
      throw 'empty sets have no solutions';
    }
    // 2. the top row/column postion of the _pivotColumn is the _pivot location
    this._pivot.row = 0;
    _largestAbsoluteMovedToTopOfColumn = this._pivotColumn;
    // foreach row:
    this._systemState.forEach(function(row, index){
    // a. _largestAbsoluteMovedToTopOfColumn on the _pivotColumn - largest to top
      this._largestAbsoluteMovedToTopOfColumn(this._piviot.column, this._piviot.row);
    });
    // b. _zeroAllRowsUnderThePevot() - row replacement operations to "zero" all entry under the pivot
    // c. _pivot.row++, _pivot.column++
    // 3. foreach row:
    // a. _zeroAllRowsAboveThePivot(), _scalePivotToOne
    // b. _pivot.row--, _pivot--
  }
  _largestAbsoluteMovedToTopOfColumn(columnNumber, rowsOffSetNumber){
    let largestValue = 0;
    let indexOfLargestValue = undefined;
    let columnArray = this._systemState.map(function(value) {
      return value[columnNumber];
    });
    columnArray.forEach(function(value, index){
      if (index >= rowsOffSetNumber) {
        if (Math.abs(value) > largestValue) {
          largestValue = Math.abs(value);
          indexOfLargestValue = index;
        }
      }
    });
    //this._switch(this._piviot.row, indexOfLargestValue)
  }
}

const initObject = [
  [2,3,0,5],
  [0,0,1,20],
  [0,-2,0,5]
];

const theSystem = new LinearSystem(initObject);
theSystem.solve();
<commit_msg>update<commit_after>class LinearSystem {
  constructor(matrix) {
    //input should be a array of array of ints
    if ( ! Array.isArray(matrix)) {
      throw 'not array type error';
    }
    const hight = matrix.length;
    matrix.forEach(function(row){
      if ( ! Array.isArray(row)) {
        throw 'not array type error';
      }
      //checks if input matrix is ( column.length + 1 == rows.length )
      if ( hight + 1 != row.length ) {
        throw 'not in required shape (width == hight + 1)';
      }
      row.forEach(function(entry){
        if ( ! Number.isInteger(entry)) {
          throw 'not a integer error';
        }
      });
    });
    this._systemState = matrix;
    this._pivotColumn = undefined;
    this._pivot = {
      row: undefined,
      column: undefined
    };
    this._isEchelonForm = undefined;
    this._isReducedEchelonForm = undefined;
  }
  solve(){
    // 1. the left most non-zero column is the _pivotColumn
    //try first column, iterate until a column has a non-zero int in it
    let isNonZero = false;
    for (var i = 0; i < this._systemState.length; i++) {
      let thisColumn = this._systemState.map(function(value) {
        return value[i];
      });
      isNonZero = thisColumn.some(function(entry){
        return Math.abs(entry) > 0
      });
      if (isNonZero) {
        this._pivotColumn = i;
        break;
      }
    }
    //if there isn't a non-zero column then the set is empty and has no solutions
    if ( undefined === this._pivotColumn) {
      throw 'empty sets have no solutions';
    }
    // 2. the top row/column postion of the _pivotColumn is the _pivot location
    this._pivot.row = 0;
    this._pivot.column = this._pivotColumn;
    // foreach row:
    this._systemState.forEach(function(row, index){
    // a. _largestAbsoluteMovedToTopOfColumn on the _pivotColumn - largest to top
      this._largestAbsoluteMovedToTopOfColumn(this._pivot.column, this._pivot.row);
    });
    console.log(this._systemState);
    // b. _zeroAllRowsUnderThePevot() - row replacement operations to "zero" all entry under the pivot
    // c. _pivot.row++, _pivot.column++
    // 3. foreach row:
    // a. _zeroAllRowsAboveThePivot(), _scalePivotToOne
    // b. _pivot.row--, _pivot--
  }
  _largestAbsoluteMovedToTopOfColumn(columnNumber, rowsOffSetNumber){
    let largestValue = 0;
    let indexOfLargestValue = undefined;
    let columnArray = this._systemState.map(function(value) {
      return value[columnNumber];
    });
    columnArray.forEach(function(value, index){
      if (index >= rowsOffSetNumber) {
        if (Math.abs(value) > largestValue) {
          largestValue = Math.abs(value);
          indexOfLargestValue = index;
        }
      }
    });
    this._switch(this._pivot.row, indexOfLargestValue)
  }
  _switch(aRowNumber, differentRowNumber){
    let holder = this._systemState[differentRowNumber];
    this._systemState[differentRowNumber] = this._systemState[aRowNumber];
    this._systemState[aRowNumber] = holder;
  }
}

const initObject = [
  [2,3,0,5],
  [0,0,1,20],
  [0,-2,0,5]
];

const theSystem = new LinearSystem(initObject);
theSystem.solve();
<|endoftext|>


<commit_before>require('babel/register');

var React = require('react');
var ReactDOMServer = require('react-dom/server');
var ContributionsGrid = require('./src/ui/grid');
var CommitsFetcher = require('./src/jobs/commits-fetcher');
var TimelineGenerator = require('./src/data/timeline-generator');

module.exports = {
    getStaticMarkup: function() {ReactDOMServer.renderToStaticMarkup(React.createElement(ContributionsGrid));},
    fetchContributions: CommitsFetcher.run,
    getContributionsTimeline: TimelineGenerator.generateCommitsTimeline
};
<commit_msg>load contributions from json file and returns html markup<commit_after>require('babel/register');

var React = require('react');
var ReactDOMServer = require('react-dom/server');
var ContributionsGrid = require('./src/ui/grid');
var CommitsFetcher = require('./src/jobs/commits-fetcher');
var TimelineGenerator = require('./src/data/timeline-generator');
require('dotenv').load({path: process.cwd() + '/.env'});

module.exports = {
    getStaticMarkup: function() {
        var _contributions = require(process.cwd() + '/' + process.env.JSON_FILENAME + '.json');
        return ReactDOMServer.renderToStaticMarkup(React.createElement(ContributionsGrid, {contributions: _contributions}));
    },
    fetchContributions: CommitsFetcher.run,
    getContributionsTimeline: TimelineGenerator.generateCommitsTimeline
};
<|endoftext|>


<commit_before>/*!
 * Jade - Compiler
 * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var oldCompiler = require('jade').Compiler;
var transformers = require('transformers');

/**
 * Initialize `Compiler` with the given `node`.
 *
 * @param {Node} node
 * @param {Object} options
 * @api public
 */

var Compiler = function Compiler(node, options) {
  oldCompiler.apply(this, arguments);
};

/**
 * Compiler prototype.
 */

Compiler.prototype = Object.create(oldCompiler.prototype);
Compiler.prototype.constructor = Compiler;

  /**
   * Compile parse tree to JavaScript.
   *
   * @api public
   */

Compiler.prototype.compile = function(){
  this.buf = ['var interp;'];
  if (this.pp) this.buf.push("var __indent = [];");
  this.lastBufferedIdx = -1;
  this.buf.push('var filter_mixin = (' + filter.toString() + '())');
  this.visit(this.node);
  return this.buf.join('\n');
};

function filter() {
  var nested = 0;
  return function (type, options) {
    if (0 === nested++)
      if (locals.transformers[type].outputFormat === 'css')
        buf.push('<style>')
      else if (locals.transformers[type].outputFormat === 'js')
        buf.push('<script>')
    var oldBuf = buf; buf = [];
    this.block()
    oldBuf.push(locals.transformers[type].renderSync(buf.join(''), options || this.attributes));
    buf = oldBuf;
    if (0 === --nested)
      if (locals.transformers[type].outputFormat === 'css')
        buf.push('</style>')
      else if (locals.transformers[type].outputFormat === 'js')
        buf.push('</script>')
  }
}

module.exports = function (obj) {
  obj = obj || {};
  obj.compiler = Compiler;
  obj.transformers = transformers;
  return obj;
};<commit_msg>Provide some additional exports<commit_after>/*!
 * Jade - Compiler
 * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var oldCompiler = require('jade').Compiler;
var transformers = require('transformers');

/**
 * Initialize `Compiler` with the given `node`.
 *
 * @param {Node} node
 * @param {Object} options
 * @api public
 */

var Compiler = function Compiler(node, options) {
  oldCompiler.apply(this, arguments);
};

/**
 * Compiler prototype.
 */

Compiler.prototype = Object.create(oldCompiler.prototype);
Compiler.prototype.constructor = Compiler;

  /**
   * Compile parse tree to JavaScript.
   *
   * @api public
   */

Compiler.prototype.compile = function(){
  this.buf = ['var interp;'];
  if (this.pp) this.buf.push("var __indent = [];");
  this.lastBufferedIdx = -1;
  this.buf.push('var filter_mixin = (' + filter.toString() + '())');
  this.visit(this.node);
  return this.buf.join('\n');
};

function filter() {
  var nested = 0;
  return function (type, options) {
    if (0 === nested++) {
      if (helpers.transformers[type].outputFormat === 'css') {
        buf.push('<style type="text/css">')
      } else if (helpers.transformers[type].outputFormat === 'js') {
        buf.push('<script>')
      }
    }
    var oldBuf = buf, oldIndent = __indent; buf = [];__indent = [];
    this.block()
    oldBuf.push(helpers.transformers[type].renderSync(buf.join(''), options || this.attributes));
    buf = oldBuf; __indent = oldIndent;
    if (0 === --nested) {
      if (helpers.transformers[type].outputFormat === 'css') {
        buf.push('</style>')
      } else if (helpers.transformers[type].outputFormat === 'js') {
        buf.push('</script>')
      }
    }
  }
}

module.exports = function (obj) {
  obj = obj || {};
  obj.compiler = Compiler;
  obj.transformers = transformers;
  return obj;
};

module.exports.include = ('-var filter_mixin = (' + filter.toString() + '())').replace(/\n/g,'');
module.exports.helpers = { transformers: transformers; };<|endoftext|>