<commit_before>/*
 * command line tools for nico
 *
 * @author: Hsiaoming Yang <lepture@me.com>
 *
 *
 * Documentation on storage:
 *
 * storage.config = {
 *   // anything in compose.json
 *   source:
 *   output:
 *   theme:
 *   permalink:
 *   writers:
 * }
 *
 * storage.resource = {
 *   files:
 *   pages:
 *   publicPosts:
 *   secretPosts:
 * }
 *
 * storage.swigConfig = {
 *   root: [],
 *   filters: [],
 *   tzOffset: 0
 *   ...
 * }
 */

var fs = require('fs');
var path = require('path');
var _ = require('underscore');
var utils = require('./utils');
var pathlib = require('./utils/path');
var filters = require('./filters');
var reader = require('./reader');
var logging = utils.logging;

exports.getConfig = function(prog) {
  var configfile, storage = {};
  if (!prog.config) {
    if (fs.existsSync('nico.js')) {
      logging.debug("use config file nico.js");
      configfile = path.join(process.cwd(), 'nico.js');
    } else if (fs.existsSync('nico.json')) {
      logging.debug("use config file nico.json");
      configfile = path.join(process.cwd(), 'nico.json');
    }
  } else {
    if (pathlib.isroot(prog.config)) {
      configfile = prog.config;
    } else {
      configfile = path.join(process.cwd(), prog.config);
    }
  }
  if (!configfile) {
    logging.warn('No config file is assigned, use default settings.');
    storage.config = {};
    storage.config.writers = [
      path.join(__dirname, 'writer') + '.PostWriter'
    ];
  } else {
    logging.info('Reading config file: %s', configfile);
    storage.config = parseConfig(configfile);
  }

  // merge config from config file and process args
  storage.config.theme = prog.theme || storage.config.theme;
  storage.config.permalink = prog.permalink || storage.config.permalink;
  storage.config.source = prog.source || storage.config.source || 'content';
  storage.config.output = prog.output || storage.config.output || '_site';
  storage.config.args = prog.args;

  var config = storage.config;
  if (config.theme && !pathlib.isroot(config.theme)) {
    storage.config.theme = path.join(process.cwd(), config.theme);
  }
  if (!pathlib.isroot(config.source)) {
    storage.config.source = path.join(process.cwd(), config.source);
  }
  if (!pathlib.isroot(config.output)) {
    storage.config.output= path.join(process.cwd(), config.output);
  }
  return storage;
};

exports.getSwigConfig = function(config) {
  var swigConfig = {};
  swigConfig.filters = config.filters || {};

  _.extend(swigConfig.filters, filters.filters);
  swigConfig.contextfilters = config.contextfilters || {};
  _.extend(swigConfig.contextfilters, filters.contextfilters);
  swigConfig.functions = config.functions || {};
  _.extend(swigConfig.functions, filters.functions);
  swigConfig.contextfunctions = config.contextfunctions || {};
  _.extend(swigConfig.contextfunctions, filters.contextfunctions);

  swigConfig.globals = swigConfig.globals || {};
  swigConfig.globals.system = require('../package.json');
  var theme;
  try {
    theme = require(path.join(config.theme, 'theme.js'));
  } catch (e) {
    logging.warn('There is no theme config file');
  }
  if (theme) swigConfig.globals.theme = theme;
  return swigConfig;
};

exports.callReader = function(storage) {
  // need storage.config.source
  storage.config.PostRender = storage.config.PostRender || reader.Post;

  storage.resource = storage.resource || {};
  storage.resource.files = [];
  storage.resource.publicPosts = [];
  storage.resource.secretPosts = [];
  storage.resource.pages = [];

  var postInfo = function(post) {
    // must have information
    var ret = {
      filepath: post.filepath,
      title: post.title,
      meta: post.meta,
      pubdate: post.pubdate,
      updated: post.updated,
      tags: post.tags,
      filename: post.filename,
      directory: post.directory,
      template: post.template
    };
    // post can define it by itself
    var metadata = post.constructor.metadata || [];
    metadata.forEach(function(key) {
      if (!ret.hasOwnProperty(key)) {
        ret[key] = post[key];
      }
    });
    return ret;
  };

  var abspath = storage.config.source;
  var files = pathlib.walkdir(abspath, storage.config.ignore).files;
  files.forEach(function(filepath) {
    var extname = path.extname(filepath);
    if (_.any(['.md', '.mkd', '.markdown'], function(ext) {
      return extname === ext;
    })) {
      var post = new storage.config.PostRender({
        filepath: filepath,
        root: abspath
      });
      if (!post.pubdate) {
        storage.resource.pages.push(postInfo(post));
      } else if (post.status === 'secret') {
        storage.resource.secretPosts.push(postInfo(post));
      } else if (post.status !== 'draft') {
        storage.resource.publicPosts.push(postInfo(post));
      }
    } else {
      storage.resource.files.push(filepath);
    }
  });
  return storage;
};

exports.callWriters = function(storage) {
  // need storage.config.writers
  storage.config.writers.forEach(function(item) {
    var Writer = utils.require(item);
    var writer = new Writer(storage);
    writer.start();
    writer.end();
  });
  return storage;
};

function parseConfig(configfile) {
  if (_.isString(configfile)) {
    return require(configfile);
  } else if (_.isObject(configfile)) {
    return configfile;
  }
  return {};
}
exports.parseConfig = parseConfig;
<commit_msg>add default format<commit_after>/*
 * command line tools for nico
 *
 * @author: Hsiaoming Yang <lepture@me.com>
 *
 *
 * Documentation on storage:
 *
 * storage.config = {
 *   // anything in compose.json
 *   source:
 *   output:
 *   theme:
 *   permalink:
 *   writers:
 * }
 *
 * storage.resource = {
 *   files:
 *   pages:
 *   publicPosts:
 *   secretPosts:
 * }
 *
 * storage.swigConfig = {
 *   root: [],
 *   filters: [],
 *   tzOffset: 0
 *   ...
 * }
 */

var fs = require('fs');
var path = require('path');
var _ = require('underscore');
var utils = require('./utils');
var pathlib = require('./utils/path');
var filters = require('./filters');
var reader = require('./reader');
var logging = utils.logging;

exports.getConfig = function(prog) {
  var configfile, storage = {};
  if (!prog.config) {
    if (fs.existsSync('nico.js')) {
      logging.debug("use config file nico.js");
      configfile = path.join(process.cwd(), 'nico.js');
    } else if (fs.existsSync('nico.json')) {
      logging.debug("use config file nico.json");
      configfile = path.join(process.cwd(), 'nico.json');
    }
  } else {
    if (pathlib.isroot(prog.config)) {
      configfile = prog.config;
    } else {
      configfile = path.join(process.cwd(), prog.config);
    }
  }
  if (!configfile) {
    logging.warn('No config file is assigned, use default settings.');
    storage.config = {};
    storage.config.writers = [
      path.join(__dirname, 'writer') + '.PostWriter'
    ];
  } else {
    logging.info('Reading config file: %s', configfile);
    storage.config = parseConfig(configfile);
  }

  // merge config from config file and process args
  storage.config.theme = prog.theme || storage.config.theme;
  storage.config.permalink = prog.permalink || storage.config.permalink || '{{directory}}/{{filename}}.html';
  storage.config.source = prog.source || storage.config.source || 'content';
  storage.config.output = prog.output || storage.config.output || '_site';
  storage.config.args = prog.args;

  var config = storage.config;
  if (config.theme && !pathlib.isroot(config.theme)) {
    storage.config.theme = path.join(process.cwd(), config.theme);
  }
  if (!pathlib.isroot(config.source)) {
    storage.config.source = path.join(process.cwd(), config.source);
  }
  if (!pathlib.isroot(config.output)) {
    storage.config.output= path.join(process.cwd(), config.output);
  }
  return storage;
};

exports.getSwigConfig = function(config) {
  var swigConfig = {};
  swigConfig.filters = config.filters || {};

  _.extend(swigConfig.filters, filters.filters);
  swigConfig.contextfilters = config.contextfilters || {};
  _.extend(swigConfig.contextfilters, filters.contextfilters);
  swigConfig.functions = config.functions || {};
  _.extend(swigConfig.functions, filters.functions);
  swigConfig.contextfunctions = config.contextfunctions || {};
  _.extend(swigConfig.contextfunctions, filters.contextfunctions);

  swigConfig.globals = swigConfig.globals || {};
  swigConfig.globals.system = require('../package.json');
  var theme;
  try {
    theme = require(path.join(config.theme, 'theme.js'));
  } catch (e) {
    logging.warn('There is no theme config file');
  }
  if (theme) swigConfig.globals.theme = theme;
  return swigConfig;
};

exports.callReader = function(storage) {
  // need storage.config.source
  storage.config.PostRender = storage.config.PostRender || reader.Post;

  storage.resource = storage.resource || {};
  storage.resource.files = [];
  storage.resource.publicPosts = [];
  storage.resource.secretPosts = [];
  storage.resource.pages = [];

  var postInfo = function(post) {
    // must have information
    var ret = {
      filepath: post.filepath,
      title: post.title,
      meta: post.meta,
      pubdate: post.pubdate,
      updated: post.updated,
      tags: post.tags,
      filename: post.filename,
      directory: post.directory,
      template: post.template
    };
    // post can define it by itself
    var metadata = post.constructor.metadata || [];
    metadata.forEach(function(key) {
      if (!ret.hasOwnProperty(key)) {
        ret[key] = post[key];
      }
    });
    return ret;
  };

  var abspath = storage.config.source;
  var files = pathlib.walkdir(abspath, storage.config.ignore).files;
  files.forEach(function(filepath) {
    var extname = path.extname(filepath);
    if (_.any(['.md', '.mkd', '.markdown'], function(ext) {
      return extname === ext;
    })) {
      var post = new storage.config.PostRender({
        filepath: filepath,
        root: abspath
      });
      if (!post.pubdate) {
        storage.resource.pages.push(postInfo(post));
      } else if (post.status === 'secret') {
        storage.resource.secretPosts.push(postInfo(post));
      } else if (post.status !== 'draft') {
        storage.resource.publicPosts.push(postInfo(post));
      }
    } else {
      storage.resource.files.push(filepath);
    }
  });
  return storage;
};

exports.callWriters = function(storage) {
  // need storage.config.writers
  storage.config.writers.forEach(function(item) {
    var Writer = utils.require(item);
    var writer = new Writer(storage);
    writer.start();
    writer.end();
  });
  return storage;
};

function parseConfig(configfile) {
  if (_.isString(configfile)) {
    return require(configfile);
  } else if (_.isObject(configfile)) {
    return configfile;
  }
  return {};
}
exports.parseConfig = parseConfig;
<|endoftext|>


<commit_before>#!/usr/bin/env node

import module from "./";
import pkg from "../package.json";
import path from "path";
import chalk from "chalk";
import tildify from "tildify";
import yargs from "yargs";

const {argv} =
  yargs
  .usage("Usage: $0 <dir>")
  .demand(0, 1, chalk.red("Too many directories specified."))
  .option("h", { alias: "help", describe: "Show help" })
  .option("v", { alias: "version", describe: "Show version" });

if (argv.help || argv.h) {
  yargs.showHelp();
  process.exit();
}

if (argv.version || argv.v) {
  console.log(pkg.version);
  process.exit();
}

Promise.resolve(
  path.resolve(process.cwd(), argv._.length > 0 ? String(argv._[0]) : ".")
).then(dir => {
  console.log(chalk.green("Creating module..."));
  return module(dir);
}).then(files => {
  files.map(tildify).forEach(file => console.log(chalk.green("+", file)));
  console.log(chalk.green("Module created!"));
  process.exit();
}).catch(() => {
  console.error(chalk.red("An error occurred."));
  process.exit(1);
});
<commit_msg>Make usage prettier<commit_after>#!/usr/bin/env node

import module from "./";
import pkg from "../package.json";
import path from "path";
import chalk from "chalk";
import tildify from "tildify";
import yargs from "yargs";

const {argv} =
  yargs
  .usage(`Usage: ${chalk.cyan("$0", chalk.underline("<dir>"))}`)
  .demand(0, 1, chalk.red("Too many directories specified."))
  .option("h", { alias: "help", describe: "Show help", type: "boolean" })
  .option("v", { alias: "version", describe: "Show version", type: "boolean" });

if (argv.help || argv.h) {
  yargs.showHelp();
  process.exit();
}

if (argv.version || argv.v) {
  console.log(pkg.version);
  process.exit();
}

Promise.resolve(
  path.resolve(process.cwd(), argv._.length > 0 ? String(argv._[0]) : ".")
).then(dir => {
  console.log(chalk.green("Creating module..."));
  return module(dir);
}).then(files => {
  files.map(tildify).forEach(file => console.log(chalk.green("+", file)));
  console.log(chalk.green("Module created!"));
  process.exit();
}).catch(() => {
  console.error(chalk.red("An error occurred."));
  process.exit(1);
});
<|endoftext|>


<commit_before>
module.exports = {
  isMain: true,
  imports: [
    'indexErase',
    'indexer',
    'spec.loader'
  ],
  extImports: [
    'commander',
    'exit',
    'path',
    'progress'
  ],
  init: init
};

function init(eggnog) {

  var program = eggnog.import('commander');
  var exit = eggnog.import('exit');
  var path = eggnog.import('path');
  var indexErase = eggnog.import('indexErase');
  var indexer = eggnog.import('indexer');
  var specLoader = eggnog.import('spec.loader');

  eggnog.exports = run;

  ////////////////////

  var rootDir = './';
  var configPath = undefined;

  var spec = undefined;
  var esClientConfig = undefined;

  function run(root) {
    rootDir = root;

    var commandExecuted = runCli(program);
    if (!commandExecuted) {
      program.outputHelp();
    }
  }

  function loadConfig(configPath) {
    if (spec) {
      return; // Already loaded the config
    }

    configPath = configPath || './config.js';
    var absCfgPath = path.resolve(rootDir, configPath);
    console.log('Using config.js: ', absCfgPath);

    var cfg = require(absCfgPath);
    esClientConfig = cfg.esClientConfig;

    spec = specLoader.load(cfg);
  }

  var startTime = new Date();
  function complete(status) {
    status = status || 0;
    var endTime = new Date();
    var diffMs = endTime.getTime() - startTime.getTime();
    var diffS = diffMs/1000.0;
    console.log('Finished at ', endTime);
    console.log('(Total time: [', diffS, '] seconds)');
    exit(status);
  }

  function onError(err) {
    console.log('error! ', err);
    complete(1);
  }

  function runCli(cli) {

    var commandExecuted = undefined;

    cli
      .description('Used to parse CSV or JSON files and insert them into Elasticsearh for querying')
      .option('-c, --config', 'Specifies a config file to use. Defaults defaults to ' + rootDir + '/config.js');

    cli
      .command('index')
        .description('Index the given config file and load the data into Elasticsearch.')
        .option('-e, --erase', 'Erase the index before indexing')
        .action(function(config, options) {
          commandExecuted = 'index';
          loadConfig(config);

          var clear = options.clear;
          if (clear) {
            indexErase(spec, esClientConfig)
              .then(function() {
                return indexer(spec, esClientConfig);
              })
              .catch(onError)
              .then(complete);
          } else {
            indexer(spec, esClientConfig)
              .catch(onError)
              .then(complete);
          }
        });

    cli
      .command('erase')
        .description('Erase the index for the given config file from Elasticsearch.')
        .action(function(config) {
          commandExecuted = 'erase';
          loadConfig(config);

          indexErase(spec, esClientConfig)
              .catch(onError)
              .then(complete);
        });

    cli.parse(process.argv);

    return commandExecuted;
  }

}
<commit_msg>better error messages<commit_after>
module.exports = {
  isMain: true,
  imports: [
    'indexErase',
    'indexer',
    'spec.loader'
  ],
  extImports: [
    'commander',
    'exit',
    'path',
    'progress'
  ],
  init: init
};

function init(eggnog) {

  var program = eggnog.import('commander');
  var exit = eggnog.import('exit');
  var path = eggnog.import('path');
  var indexErase = eggnog.import('indexErase');
  var indexer = eggnog.import('indexer');
  var specLoader = eggnog.import('spec.loader');

  eggnog.exports = run;

  ////////////////////

  var rootDir = './';
  var configPath = undefined;

  var spec = undefined;
  var esClientConfig = undefined;

  function run(root) {
    rootDir = root;

    var commandExecuted = runCli(program);
    if (!commandExecuted) {
      program.outputHelp();
    }
  }

  function loadConfig(configPath) {
    if (spec) {
      return; // Already loaded the config
    }

    configPath = configPath || './config.js';
    var absCfgPath = path.resolve(rootDir, configPath);
    console.log('Using config.js: ', absCfgPath);

    var cfg = require(absCfgPath);
    esClientConfig = cfg.esClientConfig;

    spec = specLoader.load(cfg);
  }

  var startTime = new Date();
  function complete(status) {
    status = status || 0;
    var endTime = new Date();
    var diffMs = endTime.getTime() - startTime.getTime();
    var diffS = diffMs/1000.0;
    console.log('Finished at ', endTime);
    console.log('(Total time: [', diffS, '] seconds)');
    exit(status);
  }

  function onError(err) {
    console.error('Error!');
    console.error(err.stack);
    complete(1);
  }

  function runCli(cli) {

    var commandExecuted = undefined;

    cli
      .description('Used to parse CSV or JSON files and insert them into Elasticsearh for querying')
      .option('-c, --config', 'Specifies a config file to use. Defaults defaults to ' + rootDir + '/config.js');

    cli
      .command('index')
        .description('Index the given config file and load the data into Elasticsearch.')
        .option('-e, --erase', 'Erase the index before indexing')
        .action(function(config, options) {
          commandExecuted = 'index';
          loadConfig(config);

          var clear = options.clear;
          if (clear) {
            indexErase(spec, esClientConfig)
              .then(function() {
                return indexer(spec, esClientConfig);
              })
              .catch(onError)
              .then(complete);
          } else {
            indexer(spec, esClientConfig)
              .catch(onError)
              .then(complete);
          }
        });

    cli
      .command('erase')
        .description('Erase the index for the given config file from Elasticsearch.')
        .action(function(config) {
          commandExecuted = 'erase';
          loadConfig(config);

          indexErase(spec, esClientConfig)
              .catch(onError)
              .then(complete);
        });

    cli.parse(process.argv);

    return commandExecuted;
  }

}
<|endoftext|>


<commit_before>const program = require('commander');
const debug = require('debug')('fbp-spec:cli');
const testsuite = require('./testsuite');
const runner = require('./runner');
const subprocess = require('./subprocess');

// # Main
function parse(args) {
  const actionHandler = (suites, opts) => {
    const o = opts;
    o.suites = suites;
  };

  program
    .storeOptionsAsProperties(false)
    .passCommandToAction(false)
    .arguments('<suites>')
    .action(actionHandler)
    .option('--address <URL>', 'Address of runtime to connect to', String, 'ws://localhost:3569')
    .option('--secret <secret>', 'Runtime secret', String, null)
    .option('--command <command>', 'Command to launch runtime under test', String, null)
    .option('--start-timeout <seconds>', 'Time to wait for runtime to start', Number, 10)
    .option('--command-timeout <seconds>', 'Max time for a FBP command', Number, 3)
    .parse(args);

  return program;
}

function startRuntime(options, callback) {
  if (!options.command) {
    // we're not responsible for starting it
    callback(null);
    return;
  }
  const subprocessOptions = {};
  subprocess.start(options.command, subprocessOptions, callback);
}

function hasErrors(suites) {
  let failures = 0;
  suites.forEach((s) => {
    s.cases.forEach((c) => {
      if (c.error) { failures += 1; }
    });
  });
  return failures > 0;
}

function runOptions(options, onUpdate, callback) {
  let child = null;
  let allSuites = [];

  function cleanReturn(err) {
    if (child) {
      child.kill();
    }
    callback(err, allSuites);
  }

  const def = {
    protocol: 'websocket',
    address: options.address,
    secret: options.secret || '',
  };

  debug('runtime info', def);

  const runnerOptions = {
    connectTimeout: options.startTimeout * 1000,
    commandTimeout: options.commandTimeout * 1000,
  };

  const ru = new runner.Runner(def, runnerOptions);
  child = startRuntime(options, (err) => {
    if (err) {
      cleanReturn(err);
      return;
    }

    ru.connect((connectErr) => {
      if (connectErr) {
        cleanReturn(connectErr);
        return;
      }

      testsuite.getSuites(options.suites, (getSuitesErr, suites) => {
        if (getSuitesErr) {
          cleanReturn(getSuitesErr);
          return;
        }
        allSuites = allSuites.concat(suites);

        // TODO: move this into runAll??
        runner.getComponentSuites(ru, (getComponentSuitesErr, componentSuites) => {
          if (getComponentSuitesErr) {
            cleanReturn(getComponentSuitesErr);
            return;
          }
          allSuites = allSuites.concat(componentSuites);

          runner.runAll(ru, allSuites, onUpdate, (runErr) => {
            if (runErr) {
              cleanReturn(runErr);
              return;
            }

            ru.disconnect((disconnectErr) => cleanReturn(disconnectErr));
          });
        });
      });
    });
  });
}

function testStatusText(suites) {
  const results = [];
  const ident = '  ';
  suites.forEach((s) => {
    s.cases.forEach((c) => {
      if ((c.passed == null) || c.shown) { return; }
      if (!s.titleshown) { results.push(`${s.name}`); }

      // bit hacky, mutates suites
      const suite = s;
      const testCase = c;
      suite.titleshown = true;
      testCase.shown = true;

      let res = c.passed ? '✓' : `✗ Error: ${c.error}`;
      if (c.skip) { res = `SKIP: ${c.skip}`; }
      results.push(`${ident}${c.name}\n${ident + ident}${c.assertion}: ${res}`);
    });
  });
  return results;
}

function main() {
  const cmd = parse(process.argv);
  const options = cmd.opts();

  function onUpdate(suites) {
    const r = testStatusText(suites);
    console.log(r.join('\n'));
  }

  runOptions(options, onUpdate, (err, suites) => {
    if (err) { throw err; }
    const exitStatus = hasErrors(suites) ? 2 : 0;
    process.exit(exitStatus);
  });
}

exports.main = main;
<commit_msg>Make loading component tests optional<commit_after>const program = require('commander');
const debug = require('debug')('fbp-spec:cli');
const testsuite = require('./testsuite');
const runner = require('./runner');
const subprocess = require('./subprocess');

// # Main
function parse(args) {
  const actionHandler = (suites, opts) => {
    const o = opts;
    o.suites = suites;
  };

  program
    .storeOptionsAsProperties(false)
    .passCommandToAction(false)
    .arguments('<suites>')
    .action(actionHandler)
    .option('--address <URL>', 'Address of runtime to connect to', String, 'ws://localhost:3569')
    .option('--secret <secret>', 'Runtime secret', String, null)
    .option('--command <command>', 'Command to launch runtime under test', String, null)
    .option('--start-timeout <seconds>', 'Time to wait for runtime to start', Number, 10)
    .option('--command-timeout <seconds>', 'Max time for a FBP command', Number, 3)
    .option('--component-tests', 'Whether to load component tests from runtime', Boolean, false)
    .parse(args);

  return program;
}

function startRuntime(options, callback) {
  if (!options.command) {
    // we're not responsible for starting it
    callback(null);
    return;
  }
  const subprocessOptions = {};
  subprocess.start(options.command, subprocessOptions, callback);
}

function hasErrors(suites) {
  let failures = 0;
  suites.forEach((s) => {
    s.cases.forEach((c) => {
      if (c.error) { failures += 1; }
    });
  });
  return failures > 0;
}

function runOptions(options, onUpdate, callback) {
  let child = null;
  let allSuites = [];

  function cleanReturn(err) {
    if (child) {
      child.kill();
    }
    callback(err, allSuites);
  }

  const def = {
    protocol: 'websocket',
    address: options.address,
    secret: options.secret || '',
  };

  debug('runtime info', def);

  const runnerOptions = {
    connectTimeout: options.startTimeout * 1000,
    commandTimeout: options.commandTimeout * 1000,
  };

  const ru = new runner.Runner(def, runnerOptions);
  child = startRuntime(options, (err) => {
    if (err) {
      cleanReturn(err);
      return;
    }

    ru.connect((connectErr) => {
      if (connectErr) {
        cleanReturn(connectErr);
        return;
      }

      testsuite.getSuites(options.suites, (getSuitesErr, suites) => {
        if (getSuitesErr) {
          cleanReturn(getSuitesErr);
          return;
        }
        allSuites = allSuites.concat(suites);

        if (options.componentTests) {
          // TODO: move this into runAll??
          runner.getComponentSuites(ru, (getComponentSuitesErr, componentSuites) => {
            if (getComponentSuitesErr) {
              cleanReturn(getComponentSuitesErr);
              return;
            }
            allSuites = allSuites.concat(componentSuites);
            runner.runAll(ru, allSuites, onUpdate, (runErr) => {
              if (runErr) {
                cleanReturn(runErr);
                return;
              }
              ru.disconnect((disconnectErr) => cleanReturn(disconnectErr));
            });
          });
          return;
        }
        runner.runAll(ru, allSuites, onUpdate, (runErr) => {
          if (runErr) {
            cleanReturn(runErr);
            return;
          }
          ru.disconnect((disconnectErr) => cleanReturn(disconnectErr));
        });
      });
    });
  });
}

function testStatusText(suites) {
  const results = [];
  const ident = '  ';
  suites.forEach((s) => {
    s.cases.forEach((c) => {
      if ((c.passed == null) || c.shown) { return; }
      if (!s.titleshown) { results.push(`${s.name}`); }

      // bit hacky, mutates suites
      const suite = s;
      const testCase = c;
      suite.titleshown = true;
      testCase.shown = true;

      let res = c.passed ? '✓' : `✗ Error: ${c.error}`;
      if (c.skip) { res = `SKIP: ${c.skip}`; }
      results.push(`${ident}${c.name}\n${ident + ident}${c.assertion}: ${res}`);
    });
  });
  return results;
}

function main() {
  const cmd = parse(process.argv);
  const options = cmd.opts();

  function onUpdate(suites) {
    const r = testStatusText(suites);
    console.log(r.join('\n'));
  }

  runOptions(options, onUpdate, (err, suites) => {
    if (err) { throw err; }
    const exitStatus = hasErrors(suites) ? 2 : 0;
    process.exit(exitStatus);
  });
}

exports.main = main;
<|endoftext|>


<commit_before>'use(strict)'

import {read, write} from '.'
import * as argsParser from './util/args'

export default async function () {
  var args = process.argv.slice(2)

  let argp = argsParser
    .option('--type', '-t', null)
    .option('--base', '-b', null)

    .option('--expand', '-e', false)
    // .option('--flatten', '-f', false)
    // .option('--compact', '-c', false)

    .option('--index', '-i', false)
    .option('--pattern', '-p', false)

    .option('--output', '-o', null)

    .option('--max-redirects', null, null)
    .option('--verbose', '-v', false)
    .option('--help', '-h', false)

  let opts = argp.parse(args)

  if (opts.help) {
    console.log('Usage: ldtr [options] [arguments]')
    console.log()
    console.log('Options:')
    argp.logOptions('')
    return
  }

  let data
  try {
    data = await read(opts.args[0], opts)
  } catch (e) {
    if (e.location) {
      let start = e.location.start
      console.error(e.name, 'at', 'line:', start.line, 'column:', start.column, e.message)
      return
    } else {
      throw e
    }
  }
  data = await postProcess(data, opts)

  if (opts.output === 'NONE') {
    return
  } else {
    await write(data, {type: opts.output})
  }
}

async function postProcess (data, opts) {
  if (opts.expand || opts.pattern) {
    const cx = await import('./jsonld/algorithm')
    data = cx.expand({}, data)
  }

  if (opts.index || opts.pattern) {
    const indexer = await import('./util/indexer')
    data = indexer.index(data, {
      reverses: opts.pattern === void 0,
      byType: true
    })
  }

  if (opts.pattern) {
    const {expandPatterns} = await import('./rdfa/copypattern')
    expandPatterns(data.byId)
    data = {
      '@context': data['@context'],
      '@graph': Object.values(data.byId)
    }
  }

  return data
}
<commit_msg>Always add reverses when using indexing from CLI<commit_after>'use(strict)'

import {read, write} from '.'
import * as argsParser from './util/args'

export default async function () {
  var args = process.argv.slice(2)

  let argp = argsParser
    .option('--type', '-t', null)
    .option('--base', '-b', null)

    .option('--expand', '-e', false)
    // .option('--flatten', '-f', false)
    // .option('--compact', '-c', false)

    .option('--index', '-i', false)
    .option('--pattern', '-p', false)

    .option('--output', '-o', null)

    .option('--max-redirects', null, null)
    .option('--verbose', '-v', false)
    .option('--help', '-h', false)

  let opts = argp.parse(args)

  if (opts.help) {
    console.log('Usage: ldtr [options] [arguments]')
    console.log()
    console.log('Options:')
    argp.logOptions('')
    return
  }

  let data
  try {
    data = await read(opts.args[0], opts)
  } catch (e) {
    if (e.location) {
      let start = e.location.start
      console.error(e.name, 'at', 'line:', start.line, 'column:', start.column, e.message)
      return
    } else {
      throw e
    }
  }
  data = await postProcess(data, opts)

  if (opts.output === 'NONE') {
    return
  } else {
    await write(data, {type: opts.output})
  }
}

async function postProcess (data, opts) {
  if (opts.expand || opts.pattern) {
    const cx = await import('./jsonld/algorithm')
    data = cx.expand({}, data)
  }

  if (opts.index || opts.pattern) {
    const indexer = await import('./util/indexer')
    data = indexer.index(data, {
      reverses: true,
      byType: true
    })
  }

  if (opts.pattern) {
    const {expandPatterns} = await import('./rdfa/copypattern')
    expandPatterns(data.byId)
    data = {
      '@context': data['@context'],
      '@graph': Object.values(data.byId)
    }
  }

  return data
}
<|endoftext|>


<commit_before>var path = require('path');
var Acetate = require('./index');
var gaze = require('gaze');

var argv = require('yargs')
      .alias('c', 'config')
      .alias('p', 'port')
      .default('host', 'localhost')
      .default('port', 8000)
      .default('findPort', false)
      .default('open', false)
      .default('clean', false)
      .default('log', 'info')
      .default('config', 'acetate.conf.js').argv;

var configPath = path.join(process.cwd(), argv.config);
var action = argv._[0];

function buildCallback(acetate){
  return function(error){
    if(action === 'build') {
      process.exit(!error);
    }

    if(action === 'server'){
      acetate.server.start(argv.host, argv.port, argv.findPort, argv.open);
    }

    if(action === 'watch' || action === 'server'){
      acetate.watcher.start();
    }
  }
}

function run() {
  var acetate = new Acetate(configPath);

  acetate.log.level = argv.log;

  acetate.log.time('start');
  acetate.log.time('load');

  acetate.load(function(){
    acetate.log.verbose('load', 'loading pages done in %s', acetate.log.timeEnd('load'));

    if(argv.clean){
      acetate.log.time('clean');
      acetate.clean(function(error){
        acetate.log.verbose('cleaning', 'cleaning build folder done in %s', acetate.log.timeEnd('clean'));
        acetate.build(buildCallback(acetate));
      });
    } else {
      acetate.build(buildCallback(acetate));
    }
  });
}

if(action === 'watch' || action === 'server'){
  // watch the passed config file
  gaze(argv.config, function(error, watcher){

    // whenever it chagnes
    watcher.on('changed', function() {

      // stop the server if we were running it
      if(action === 'server'){
        acetate.server.stop();
      }

      // stop the watcher if we were running it
      if(action === 'watch' || action === 'server'){
        acetate.watcher.stop();
      }

      // rerun everything
      run();

    });
  });
}

module.exports = {
  run: run
};<commit_msg>fix build from throwing error, document cli<commit_after>var path = require('path');
var Acetate = require('./index');
var gaze = require('gaze');
var pjson = require('../package.json');
var argv = require('yargs')
    .usage('Build and serve Acetate site. \nUsage: $0 [action] [options]')
    .example('$0 build --clean', 'build site')
    .demand(1)
    .version(pjson.version)
    .help('h')
    .alias('v', 'version')
    .alias('h', 'help')
    .alias('c', 'config')
    .alias('p', 'port')
    .default('host', 'localhost')
    .default('port', 8000)
    .default('findPort', false)
    .default('open', false)
    .default('clean', false)
    .default('log', 'info')
    .default('config', 'acetate.conf.js')
    .describe('config', 'path to config file')
    .describe('port', 'port number server should use')
    .describe('host', 'host server should use')
    .describe('findPort', 'find new port if port is in use')
    .describe('open', 'open browser when server starts up')
    .describe('clean', 'clean out files from build folder')
    .describe('log', 'log level options: \n(debug|verbose|info|success|warn|error|stack|silent)')
    .describe('version', 'acetate version number')
    .argv;

var configPath = path.join(process.cwd(), argv.config);
var action = argv._[0];

function buildCallback(acetate){
  return function(error){
    if(action === 'build') {
      if (error) {
        console.error(error)
        process.exit(1)
      }
      process.exit(0);
    }

    if(action === 'server'){
      acetate.server.start(argv.host, argv.port, argv.findPort, argv.open);
    }

    if(action === 'watch' || action === 'server'){
      acetate.watcher.start();
    }
  }
}

function run() {
  var acetate = new Acetate(configPath);

  acetate.log.level = argv.log;

  acetate.log.time('start');
  acetate.log.time('load');

  acetate.load(function(){
    acetate.log.verbose('load', 'loading pages done in %s', acetate.log.timeEnd('load'));

    if(argv.clean){
      acetate.log.time('clean');
      acetate.clean(function(error){
        acetate.log.verbose('cleaning', 'cleaning build folder done in %s', acetate.log.timeEnd('clean'));
        acetate.build(buildCallback(acetate));
      });
    } else {
      acetate.build(buildCallback(acetate));
    }
  });
}

if(action === 'watch' || action === 'server'){
  // watch the passed config file
  gaze(argv.config, function(error, watcher){

    // whenever it chagnes
    watcher.on('changed', function() {

      // stop the server if we were running it
      if(action === 'server'){
        acetate.server.stop();
      }

      // stop the watcher if we were running it
      if(action === 'watch' || action === 'server'){
        acetate.watcher.stop();
      }

      // rerun everything
      run();

    });
  });
}

module.exports = {
  run: run
};<|endoftext|>


<commit_before>var _ = require('lodash');
var path = require('path');
var rc = require('rc');

var util = require('slap-util');
var package = require('../package');
var baseDir = path.join(__dirname, '..');
var configFile = path.join(baseDir, package.name + '.ini');
var opts = util.parseOpts(rc(package.name, configFile));
opts = _.merge(opts, opts.slap);

var info = console._error || console.error;

// special invocation modes
if (opts.h || opts.help) {
  var command = process.argv[1];
  if (!process.env.PATH.split(path.delimiter).some(function (binPath) {
    var newCommand = path.relative(binPath, command);
    if (path.dirname(newCommand) === '.') {
      command = newCommand;
      return true;
    }
  })) {
    command = path.relative(process.cwd(), command);
    if (path.dirname(command) === '.') command = '.' + path.sep + command;
  }

  info([
    "Usage: " + command + " [options...] [<file1> [<file2> [...]]]",
    "",
    package.description,
    "",
    "To see what options are available, run `" + command + " " + configFile + "`.",
    "Example: `" + command + " --logger.level debug file.c`."
  ].join("\n"));

  return process.exit(0);
}

if (opts.v || opts.version) {
  var SORT_ORDER = ['slap', 'node', 'v8'].reverse();
  var versions = _.clone(process.versions);
  versions[package.name] = package.version;
  info(Object.keys(versions)
    .sort(function (a, b) { return SORT_ORDER.indexOf(b) - SORT_ORDER.indexOf(a); })
    .map(function (name) { return name+"@"+versions[name]; })
    .join(", "));
  return process.exit(0);
}

if (opts.perf.profile && process.execArgv.indexOf('--prof') === -1) {
  var cp = require('child_process').fork(process.argv[1], process.argv.slice(2), {
    stdio: 'inherit',
    execArgv: ['--prof'].concat(process.execArgv)
  });
  cp.on('exit', function (code) { process.exit(code); });
  cp.on('error', function (err) { process.exit(8); });
  return;
}

var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));

var blessed = require('base-widget').blessed;
var Slap = require('./ui/Slap');
var Pane = require('./ui/Pane');

module.exports = function (options) {
  opts = _.merge(opts, options);
  return Slap.getUserDir().catch(Promise.resolve()).then(function (userDir) {
    if (userDir) opts = _.merge({logger: {file: path.resolve(userDir, package.name+'.log')}}, opts);
    opts = _.merge({editor: {logger: opts.logger}}, opts);
    util.logger(opts.logger);

    util.logger.info("loading...");
    util.logger.verbose("configuration:", opts);

    if (!opts.screen) opts.screen = new blessed.Screen(opts.screenOpts);
    opts.screen.logger = opts.logger;
    var slap = new Slap(opts);

    Promise.all(opts._.map(function (path, i) {
      return slap.open(path.toString(), !i);
    })).done();

    if (!opts._.length) { // if no files are passed
      new Pane({parent: slap}).setCurrent(); // open a new empty file
      if (!opts.config) { // first run without a file passed
        slap.open(path.join(baseDir, 'README.md'), true)
          .tap(function (pane) { pane.editor.readOnly(true); })
          .done();
        fs.createReadStream(path.join(__dirname, '..', 'default-config.ini')).pipe(fs.createWriteStream(path.join(userDir, 'config')));
      }
    }

    require('update-notifier')({pkg: package}).notify();

    return slap.ready.disposer(function (slap) { slap.quit(); });
  });
};
<commit_msg>WIP feat(piping): pipe to a new buffer, like `netstat | slap`<commit_after>var _ = require('lodash');
var path = require('path');
var rc = require('rc');

var util = require('slap-util');
var package = require('../package');
var baseDir = path.join(__dirname, '..');
var configFile = path.join(baseDir, package.name + '.ini');
var opts = util.parseOpts(rc(package.name, configFile));
opts = _.merge(opts, opts.slap);

var info = console._error || console.error;

// special invocation modes
if (opts.h || opts.help) {
  var command = process.argv[1];
  if (!process.env.PATH.split(path.delimiter).some(function (binPath) {
    var newCommand = path.relative(binPath, command);
    if (path.dirname(newCommand) === '.') {
      command = newCommand;
      return true;
    }
  })) {
    command = path.relative(process.cwd(), command);
    if (path.dirname(command) === '.') command = '.' + path.sep + command;
  }

  info([
    "Usage: " + command + " [options...] [<file1> [<file2> [...]]]",
    "",
    package.description,
    "",
    "To see what options are available, run `" + command + " " + configFile + "`.",
    "Example: `" + command + " --logger.level debug file.c`."
  ].join("\n"));

  return process.exit(0);
}

if (opts.v || opts.version) {
  var SORT_ORDER = ['slap', 'node', 'v8'].reverse();
  var versions = _.clone(process.versions);
  versions[package.name] = package.version;
  info(Object.keys(versions)
    .sort(function (a, b) { return SORT_ORDER.indexOf(b) - SORT_ORDER.indexOf(a); })
    .map(function (name) { return name+"@"+versions[name]; })
    .join(", "));
  return process.exit(0);
}

if (opts.perf.profile && process.execArgv.indexOf('--prof') === -1) {
  var cp = require('child_process').fork(process.argv[1], process.argv.slice(2), {
    stdio: 'inherit',
    execArgv: ['--prof'].concat(process.execArgv)
  });
  cp.on('exit', function (code) { process.exit(code); });
  cp.on('error', function (err) { process.exit(8); });
  return;
}

function readAsync (stream) {
  return new Promise(function (resolve, reject) {
    var chunks = [];
    stream
      .on('error', reject)
      .on('data', chunks.push.bind(chunks))
      .on('end', function () { resolve(Buffer.concat(chunks)); });
  });
}

var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));

var blessed = require('base-widget').blessed;
var Slap = require('./ui/Slap');
var Pane = require('./ui/Pane');

module.exports = function (options) {
  opts = _.merge(opts, options);
  return Promise.all([
    Slap.getUserDir().catch(Promise.resolve()),
    readAsync(process.stdin)
  ]).spread(function (userDir, stdin) {
    if (userDir) opts = _.merge({logger: {file: path.resolve(userDir, package.name+'.log')}}, opts);
    opts = _.merge({editor: {logger: opts.logger}}, opts);
    util.logger(opts.logger);

    util.logger.info("loading...");
    util.logger.verbose("configuration:", opts);

    if (!opts.screen) opts.screen = new blessed.Screen(opts.screenOpts);
    opts.screen.logger = opts.logger;
    var slap = new Slap(opts);

    Promise.all(opts._.map(function (path, i) {
      return slap.open(path.toString(), !i);
    })).done();

    if (stdin) {
      var pane = new Pane({parent: self});
      pane.editor.textBuf.setText(stdin.toString());
      pane.setCurrent();
    } else if (!opts._.length) { // if no files are passed
      new Pane({parent: slap}).setCurrent(); // open a new empty file
      if (!opts.config) { // first run without a file passed
        slap.open(path.join(baseDir, 'README.md'), true)
          .tap(function (pane) { pane.editor.readOnly(true); })
          .done();
        fs.createReadStream(path.join(__dirname, '..', 'default-config.ini')).pipe(fs.createWriteStream(path.join(userDir, 'config')));
      }
    }

    require('update-notifier')({pkg: package}).notify();

    return slap.ready.disposer(function (slap) { slap.quit(); });
  });
};
<|endoftext|>


<commit_before>'use strict';

var pkgJson = require('../package.json');
var npmCheck = require('./npm-check');
var output = require('./output');
var update = require('./update');

var program = require('commander');
var _ = require('lodash');

process.title = pkgJson.name;

program
    .version(pkgJson.version)
    .usage('[options]') // <package[@version]>')
    .option('-u, --update', 'Interactive update.')
    .option('-g, --global', 'Look at global modules.')
    .option('-s, --skip-unused', 'Skip check for unused packages.')
    .option('-p, --production', 'Ignore devDependencies.')
    //.option('-v, --verbose', 'Verbose output')
    .option('-c, --color', 'Force color output')
    .option('--debug', 'Debug output')
    .parse(process.argv);

var options = {
    update: program.update,
    global: program.global,
    skipUnused: program.skipUnused,
    ignoreDev: program.production,
    debug: program.debug
    //verbose: program.verbose,
    //packages: program.args
};

npmCheck(options)
    .catch(function(err){
        console.log('[npm-check]', err.stack || err);
        process.exit(1);
    })
    .then(_.partialRight(options.update ? update : output, options))
    .catch(function(err){
        console.log('[npm-check]', err.stack || err);
        process.exit(1);
    })
    .done();
<commit_msg>add update notifier<commit_after>'use strict';

var pkgJson = require('../package.json');
var npmCheck = require('./index');
var output = require('./output');
var update = require('./update');

var program = require('commander');
var _ = require('lodash');

var updateNotifier = require('update-notifier');

updateNotifier({pkg: pkgJson}).notify();

process.title = pkgJson.name;

program
    .version(pkgJson.version)
    .usage('[options]') // <package[@version]>')
    .option('-u, --update', 'Interactive update.')
    .option('-g, --global', 'Look at global modules.')
    .option('-s, --skip-unused', 'Skip check for unused packages.')
    .option('-p, --production', 'Ignore devDependencies.')
    //.option('-v, --verbose', 'Verbose output')
    .option('-c, --color', 'Force color output')
    .option('--debug', 'Debug output')
    .parse(process.argv);

var options = {
    update: program.update,
    global: program.global,
    skipUnused: program.skipUnused,
    ignoreDev: program.production,
    debug: program.debug
    //verbose: program.verbose,
    //packages: program.args
};

npmCheck(options)
    .catch(function(err){
        console.log('[npm-check]', err.stack || err);
        process.exit(1);
    })
    .then(_.partialRight(options.update ? update : output, options))
    .catch(function(err){
        console.log('[npm-check]', err.stack || err);
        process.exit(1);
    })
    .done();
<|endoftext|>


<commit_before>"use strict";

const commands = {

	/* Run GNU Make from project directory */
	"user:make" (){
		const projectPath = atom.project.getPaths();
		exec(`cd '${projectPath[0]}' && make`);
	},

	/* Toggle bracket-matcher highlights */
	"body user:toggle-bracket-matcher" (){
		let el = getRootEditorElement();
		el && el.classList.toggle("show-bracket-matcher");
	},

	/* Reset editor's size to my preferred default, not Atom's */
	"user:reset-font-size" (){
		atom.config.set("editor.fontSize", 11);
	},

	/* File-Icons: Debugging commands */
	"file-icons:toggle-changed-only":_=> atom.config.set("file-icons.onChanges",   !(atom.config.get("file-icons.onChanges"))),
	"file-icons:toggle-tab-icons":_=>    atom.config.set("file-icons.tabPaneIcon", !(atom.config.get("file-icons.tabPaneIcon"))),
	"file-icons:open-settings":_=>       atom.workspace.open("atom://config/packages/file-icons"),
};

for(let name in commands){
	let cmd = name.split(/\s+/);
	if(cmd.length < 2) cmd.unshift("");
	atom.commands.add(cmd[0] || "atom-workspace", cmd[1], commands[name]);
}
<commit_msg>Fix missing function reference in Make command<commit_after>"use strict";

const {exec} = require("child_process");

const commands = {

	/* Run GNU Make from project directory */
	"user:make" (){
		const projectPath = atom.project.getPaths();
		exec(`cd '${projectPath[0]}' && make`);
	},

	/* Toggle bracket-matcher highlights */
	"body user:toggle-bracket-matcher" (){
		let el = getRootEditorElement();
		el && el.classList.toggle("show-bracket-matcher");
	},

	/* Reset editor's size to my preferred default, not Atom's */
	"user:reset-font-size" (){
		atom.config.set("editor.fontSize", 11);
	},

	/* File-Icons: Debugging commands */
	"file-icons:toggle-changed-only":_=> atom.config.set("file-icons.onChanges",   !(atom.config.get("file-icons.onChanges"))),
	"file-icons:toggle-tab-icons":_=>    atom.config.set("file-icons.tabPaneIcon", !(atom.config.get("file-icons.tabPaneIcon"))),
	"file-icons:open-settings":_=>       atom.workspace.open("atom://config/packages/file-icons"),
};

for(let name in commands){
	let cmd = name.split(/\s+/);
	if(cmd.length < 2) cmd.unshift("");
	atom.commands.add(cmd[0] || "atom-workspace", cmd[1], commands[name]);
}
<|endoftext|>


<commit_before>/**
 * @classdesc みりあがコマンド調べるよ(* ॑꒳ ॑* )
 * @constructor
 */
export class Cmd {

  /**
   * Constructor
   */
  constructor() {
  }

  /**
   * Trans text by codic
   * @param {String} cmd
   * @return {String} message
   */
  exec(cmd) {
    let message = ` ごめんなさい。。 \`${cmd}\` はわかんないです。:cry:`;

    const url = PropertiesService.getScriptProperties().getProperty('SPREADSHEET_URL');
    const spreadsheet = SpreadsheetApp.openByUrl(url);
    const sheet = spreadsheet.getSheetByName('command');

    const [rowId, colStartIndex, numcolumns] = [1, 1, 5];
    const data = sheet.getRange(rowId, colStartIndex, sheet.getLastRow(), numcolumns).getValues();
    const cmdArr = data.find((c) => c[0] == cmd);
    if (cmdArr) message = this.formatCmdMsg(cmdArr);

    return message;
  }

  /**
   * format result message
   * @param {Array} command
   * @return {String}
   */
  formatCmdMsg(command) {
    const [, explain, format, option,] = command;

    let resMsg = `${explain}:relieved:\n`;
    resMsg += `・書式\n\`\`\`${format}\`\`\`\n`;
    if (option) resMsg += `・オプション\n\`\`\`${option}\`\`\``;

    return resMsg;
  }
}
<commit_msg>add emoji manage method<commit_after>/**
 * @classdesc みりあがコマンド調べるよ(* ॑꒳ ॑* )
 */
export class Cmd {

  /**
   * @constructor
   * @param {Object} emoji
   */
  constructor(emoji) {
    this.emoji = emoji;
  }

  /**
   * Trans text by codic
   * @param {string} cmd
   * @return {string} message
   */
  exec(cmd) {
    let message = ` ごめんなさい。。 \`${cmd}\` はわかんないです。${this.emoji.fall}`;

    const url = PropertiesService.getScriptProperties().getProperty('SPREADSHEET_URL');
    const spreadsheet = SpreadsheetApp.openByUrl(url);
    const sheet = spreadsheet.getSheetByName('command');

    const [rowId, colStartIndex, numcolumns] = [1, 1, 5];
    const data = sheet.getRange(rowId, colStartIndex, sheet.getLastRow(), numcolumns).getValues();
    const cmdArr = data.find((c) => c[0] == cmd);
    if (cmdArr) message = this.formatCmdMsg(cmdArr);

    return message;
  }

  /**
   * format result message
   * @param {array} command
   * @return {string}
   */
  formatCmdMsg(command) {
    const [, explain, format, option,] = command;

    let resMsg = `${explain}${this.emoji.smile}\n`;
    resMsg += `・書式\n\`\`\`${format}\`\`\`\n`;
    if (option) resMsg += `・オプション\n\`\`\`${option}\`\`\``;

    return resMsg;
  }
}
<|endoftext|>


<commit_before>'use strict'

var _ = require('underscore');
var access = require('object-path').get;
var createVmstats = require('vmstat-s');

var cpuUsedArray = [];
var cpuStolenArray = [];
var lastRecord = null;

var config = require('./config');
var intervalInSeconds = access(config, ['cpuDetailedIntervalSeconds'], 10); // default 10 seconds.

createVmstats().then(function(vmstats) {
    lastRecord = vmstats.getLastData();
    setTimeout(hb, intervalInSeconds * 1000);
    function hb() {
        setTimeout(hb, intervalInSeconds * 1000);
        vmstats.next().then(function(data) {
            lastRecord = data;
            cpuUsedArray.push(data.summary.cpuUsed);
            cpuStolenArray.push(data.summary.cpuStolen || 0);
        });
    }
});

// return data object
function getCpuInfo() {
    var data = {};
    if (lastRecord) {
        data.memTotalMB = lastRecord.summary.memTotalMB;
        data.memPercent = lastRecord.summary.memUsagePercent;
        data.memMB = lastRecord.summary.memTotalMB - lastRecord.summary.memFreeMB - lastRecord.summary.memBufferMB;
    }
    if (cpuUsedArray.length > 0) {
        // cpuUsed
        var count = cpuUsedArray.length;
        var total = _.reduce(cpuUsedArray, function(memo, num) { return memo + num;}, 0);
        data.cpu = Math.round(total/count);
        data.cpuDetail = cpuUsedArray.join(',');

        // cpuStolen
        var totalStolen = _.reduce(cpuStolenArray, function(memo, num) { return memo + num;}, 0);
        if (totalStolen) {
            data.cpuStolen = Math.round(total/count);
            data.cpuStolenDetail = cpuUsedArray.join(',');
        }
        cpuUsedArray = [];
        totalStolen = [];
    }
    return data;
}

module.exports = getCpuInfo;<commit_msg>bug fix: cpuStolen<commit_after>'use strict'

var _ = require('underscore');
var access = require('object-path').get;
var createVmstats = require('vmstat-s');

var cpuUsedArray = [];
var cpuStolenArray = [];
var lastRecord = null;

var config = require('./config');
var intervalInSeconds = access(config, ['cpuDetailedIntervalSeconds'], 10); // default 10 seconds.

createVmstats().then(function(vmstats) {
    lastRecord = vmstats.getLastData();
    setTimeout(hb, intervalInSeconds * 1000);
    function hb() {
        setTimeout(hb, intervalInSeconds * 1000);
        vmstats.next().then(function(data) {
            lastRecord = data;
            cpuUsedArray.push(data.summary.cpuUsed);
            cpuStolenArray.push(data.summary.cpuStolen || 0);
        });
    }
});

// return data object
function getCpuInfo() {
    var data = {};
    if (lastRecord) {
        data.memTotalMB = lastRecord.summary.memTotalMB;
        data.memPercent = lastRecord.summary.memUsagePercent;
        data.memMB = lastRecord.summary.memTotalMB - lastRecord.summary.memFreeMB - lastRecord.summary.memBufferMB;
    }
    if (cpuUsedArray.length > 0) {
        // cpuUsed
        var count = cpuUsedArray.length;
        var total = _.reduce(cpuUsedArray, function(memo, num) { return memo + num;}, 0);
        data.cpu = Math.round(total/count);
        data.cpuDetail = cpuUsedArray.join(',');

        // cpuStolen
        var totalStolen = _.reduce(cpuStolenArray, function(memo, num) { return memo + num;}, 0);
        if (totalStolen) {
            data.cpuStolen = Math.round(totalStolen/count);
            data.cpuStolenDetail = cpuStolenArray.join(',');
        }
        cpuUsedArray = [];
        totalStolen = [];
    }
    return data;
}

module.exports = getCpuInfo;<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var assert = require('assert');
var debug = require('debug')('cpu');
var table = require('../support/opcodes.json');
var exec = require('./exec');

function Cpu(mmu) {

    assert(mmu !== null, 'Invalid MMU');

    // Docs
    //
    // - http://www.z80.info/gfx/z80block.gif
    // - http://www.z80.info/z80arki.htm
    // - http://imrannazar.com/GameBoy-Emulation-in-JavaScript:-The-CPU

    this.mmu = mmu;

    // Timers

    this.t = 0;

    // Main General-Purpose Register Set

    // Flags Register
    //
    // - Zero (0x80): Set if the last operation produced a result of 0;
    // - Operation (0x40): Set if the last operation was a subtraction;
    // - Half-carry (0x20): Set if, in the result of the last operation,
    // the lower half of the byte overflowed past 15;
    // - Carry (0x10): Set if the last operation produced a result over 255
    // (for additions) or under 0 (for subtractions).

    this.a = 0; // Accumulator, 8-bit
    this.f = 0; // Flags, 8-bit

    // General-Purpose Register Set

    this.b = 0; this.c = 0; // Pair BC, 8-bit + 8-bit
    this.d = 0; this.e = 0; // Pair DE, 8-bit + 8-bit
    this.h = 0; this.l = 0; // Pair HL, 8-bit + 8-bit

    // Special-Purpose Registers

    this.pc = 0; // Program Counter, 16-bit
    this.sp = 0; // Stack Pointer, 16-bit

    // Interrupts

    this.iff = 0;

    Object.seal(this);
}

// TODO(dmacosta) make 8-bit registers properties with proper range, I'm masking
// 16-bit paired register with wrong value!

// Paired registers

Object.defineProperty(Cpu.prototype, 'af', {
    get: function () {
        return (this.a & 0xFF) << 8 | this.f & 0xFF;
    },
    set: function (value) {
        this.a = (value >> 8) & 0xFF;
        this.f = value & 0xFF;
    }
});

Object.defineProperty(Cpu.prototype, 'bc', {
    get: function () {
        return (this.b & 0xFF) << 8 | this.c & 0xFF;
    },
    set: function (value) {
        this.b = (value >> 8) & 0xFF;
        this.c = value & 0xFF;
    }
});

Object.defineProperty(Cpu.prototype, 'de', {
    get: function () {
        return (this.d & 0xFF) << 8 | this.e & 0xFF;
    },
    set: function (value) {
        this.d = (value >> 8) & 0xFF;
        this.e = value & 0xFF;
    }
});

Object.defineProperty(Cpu.prototype, 'hl', {
    get: function () {
        return (this.h & 0xFF) << 8 | this.l & 0xFF;
    },
    set: function (value) {
        this.h = (value >> 8) & 0xFF;
        this.l = value & 0xFF;
    }
});

Cpu.prototype.powerOn = function () {

    debug('power on');

    var that = this;
    var next = function () {
        process.nextTick(runCycle.bind(that, next));
    };

    next();
};

var runCycle = function (next) {

    debug('run cycle PC=0x%s SP=0x%s', this.pc.toString(16),
        this.sp.toString(16));

    // Docs
    //
    // - http://www.z80.info/decoding.htm
    // - http://fms.komkon.org/GameBoy/Tech/Software.html

    // Instruction format
    //
    // [prefix byte,] opcode [,displacement byte] [,immediate data]

    var prefix = 0;
    var opcode = this.mmu.readByte(this.pc);

    // The "shadow" set of registers (BC',DE',HL',AF') and the index
    // registers (IX,IY) are missing and, consequently, there are no DD and
    // FD opcode tables.

    var spec = table.unprefixed[opcode];
    if (opcode === 0xCB) {
        prefix = 0xCB;
        opcode = this.mmu.readByte(this.pc + 1);
        spec = table.cbprefixed[opcode];
    }

    if (!spec) {
        debug('0x%s unknown opcode. stop', opcode.toString(16));
        process.exit(1);
    }

    debug('opcode is 0x%s', (prefix << 8 | opcode).toString(16));
    exec(spec)(this, next);
};

module.exports = Cpu;
<commit_msg>expose properties with range in cpu<commit_after>'use strict';

var fs = require('fs');
var assert = require('assert');
var debug = require('debug')('cpu');
var _ = require('lodash');
var table = require('../support/opcodes.json');
var exec = require('./exec');

function Cpu(mmu) {

    assert(mmu !== null, 'Invalid MMU');

    // Docs
    //
    // - http://www.z80.info/gfx/z80block.gif
    // - http://www.z80.info/z80arki.htm
    // - http://imrannazar.com/GameBoy-Emulation-in-JavaScript:-The-CPU

    this.mmu = mmu;

    // Timers

    this.t = 0;

    // Main General-Purpose Register Set

    // Flags Register
    //
    // - Zero (0x80): Set if the last operation produced a result of 0;
    // - Operation (0x40): Set if the last operation was a subtraction;
    // - Half-carry (0x20): Set if, in the result of the last operation,
    // the lower half of the byte overflowed past 15;
    // - Carry (0x10): Set if the last operation produced a result over 255
    // (for additions) or under 0 (for subtractions).

    this._a = 0; // Accumulator, 8-bit
    this._f = 0; // Flags, 8-bit

    // General-Purpose Register Set

    this._b = 0; this._c = 0; // Pair BC, 8-bit + 8-bit
    this._d = 0; this._e = 0; // Pair DE, 8-bit + 8-bit
    this._h = 0; this._l = 0; // Pair HL, 8-bit + 8-bit

    // Special-Purpose Registers

    this._pc = 0; // Program Counter, 16-bit
    this._sp = 0; // Stack Pointer, 16-bit

    // Interrupts

    this.iff = 0;

    // Properties

    var int8_registers = [
        'a', 'f',
        'b', 'c',
        'd', 'e',
        'h', 'l'
    ];

    // 8-bit Properties

    int8_registers.forEach(createProperty.bind(this, 0xFF));

    // 16-bit Paired Registers

    int8_registers
        .map(function (n, i) {
            return i % 2 == 0 ? [
                int8_registers[i],
                int8_registers[i + 1]
            ]
            : null;
        })
        .filter(function (n) { return n !== null; })
        .forEach(createPairedProperty, this);

    // 16-bit Properties

    [
        'pc',
        'sp'
    ]
    .forEach(createProperty.bind(this, 0xFFFF));

    Object.seal(this);
}

// Helpers

var createProperty = function (mask, name) {

    Object.defineProperty(this, name, {
        get: function () { return this['_' + name]; },
        set: function (value) { this['_' + name] = value & mask; }
    });
};

var createPairedProperty = function (pair) {

    Object.defineProperty(this, pair.join(''), {
        get: function () {
            return this['_' + pair[0]] << 8 | this['_' + pair[1]];
        },
        set: function (value) {
            this['_' + pair[0]] = value >> 8;
            this['_' + pair[1]] = value;
        }
    });
}

Cpu.prototype.powerOn = function () {

    debug('power on');

    var that = this;
    var next = function () {
        process.nextTick(runCycle.bind(that, next));
    };

    next();
};

var runCycle = function (next) {

    debug('run cycle PC=0x%s SP=0x%s', this._pc.toString(16),
        this._sp.toString(16));

    // Docs
    //
    // - http://www.z80.info/decoding.htm
    // - http://fms.komkon.org/GameBoy/Tech/Software.html

    // Instruction format
    //
    // [prefix byte,] opcode [,displacement byte] [,immediate data]

    var prefix = 0;
    var opcode = this.mmu.readByte(this._pc);

    // The "shadow" set of registers (BC',DE',HL',AF') and the index
    // registers (IX,IY) are missing and, consequently, there are no DD and
    // FD opcode tables.

    var spec = table.unprefixed[opcode];
    if (opcode === 0xCB) {
        prefix = 0xCB;
        opcode = this.mmu.readByte(this._pc + 1);
        spec = table.cbprefixed[opcode];
    }

    if (!spec) {
        debug('0x%s unknown opcode. stop', opcode.toString(16));
        process.exit(1);
    }

    debug('opcode is 0x%s', (prefix << 8 | opcode).toString(16));
    exec(spec)(this, next);
};

module.exports = Cpu;
<|endoftext|>


<commit_before>// ========================================================================
// bootstrap-server v1.0.0
// http://twitter.github.com/bootstrap
// ========================================================================
// Copyright 2012 Twitter, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================

"use strict"

var path  = require('path')
  , https = require('https')
  , less  = require('less')
  , CACHE = {}
  , BRANCH = "master"
  , CW    = "/*!\n * Bootstrap v2.0.2\n *\n * Copyright 2012 Twitter, Inc\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Designed and built with all the love in the world @twitter by @mdo and @fat.\n */\n"
  , ERROR = "A less error occured trying to build your bundle. Please paste the error below in an issue for us at http://github.com/twitter/bootsrap! thanks!\n\n"
  , FILES = [ "variables.less"
            , "mixins.less"
            , "reset.less"
            , "scaffolding.less"
            , "grid.less"
            , "layouts.less"
            , "type.less"
            , "code.less"
            , "labels-badges.less"
            , "tables.less"
            , "forms.less"
            , "buttons.less"
            , "sprites.less"
            , "button-groups.less"
            , "navs.less"
            , "navbar.less"
            , "breadcrumbs.less"
            , "pagination.less"
            , "pager.less"
            , "thumbnails.less"
            , "alerts.less"
            , "progress-bars.less"
            , "hero-unit.less"
            , "tooltip.less"
            , "popovers.less"
            , "modals.less"
            , "dropdowns.less"
            , "accordion.less"
            , "carousel.less"
            , "wells.less"
            , "close.less"
            , "utilities.less"
            , "component-animations.less"
            , "responsive-1200px-min.less"
            , "responsive-767px-max.less"
            , "responsive-768px-979px.less"
            , "responsive-navbar.less"
            , "responsive-utilities.less" ]

function cache(callback) {
  var complete = 0
    , _cache   = {}

  FILES.forEach(function (filename) {
    var req
      , res
      , content = []
      , options = {
          host: 'raw.github.com'
        , port: 443
        , path: path.join('/twitter/bootstrap/', BRANCH, '/less/', filename)
        , method: 'GET'
        }

    req = https.request(options, function(res) {

      res.setEncoding('utf8')

      res.on('data', function (chunk) {
        content.push(chunk)
      })

      res.on('end', function () {

        _cache[filename] = content.join(' ')

        if (++complete == FILES.length) {
          CACHE = _cache
          callback && callback(null, CACHE)
        }

      })
    })

    req.end()
  })
}

function css(params, callback) {

  var result = ''

  result += CACHE['variables.less']
  result += generateCustomCSS(params)
  result += CACHE['mixins.less']

  params.css.forEach(function (filename) {
    result += CACHE[filename]
  })

  result = result.replace(/@import[^\n]*/gi, '') //strip any imports

  try {
    var parser = new less.Parser({
        paths: ['variables.less', 'mixins.less']
      , optimization: 0
      , filename: 'bootstrap.css'
    }).parse(result, function (err, tree) {
      if (err) callback(null, {'css/error.txt': new Buffer(ERROR + '\n' + JSON.stringify(err), 'utf8')})
      callback(null, {
        'css/bootstrap.css'    : new Buffer(CW + tree.toCSS(), 'utf8')
      , 'css/bootstrap.min.css': new Buffer(CW + tree.toCSS({ compress: true }), 'utf8')
      })
    })
  } catch (err) {
    callback(null, {'css/error.txt': new Buffer(ERROR + '\n' + JSON.stringify(err), 'utf8')})
  }

}

function generateCustomCSS (params) {
  return params.vars ? Object.keys(params.vars)
  .map(function (key) {
    return params.vars[key] ? (key + ': ' + params.vars[key] + ';') : ''
  })
  .join('\n') + '\n\n' : ''
}

module.exports = css
module.exports.cache = cache
module.exports.FILES = FILES
<commit_msg>2.0.2 -> 2.0.3<commit_after>// ========================================================================
// bootstrap-server v1.0.0
// http://twitter.github.com/bootstrap
// ========================================================================
// Copyright 2012 Twitter, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================

"use strict"

var path  = require('path')
  , https = require('https')
  , less  = require('less')
  , CACHE = {}
  , BRANCH = "master"
  , CW    = "/*!\n * Bootstrap v2.0.3\n *\n * Copyright 2012 Twitter, Inc\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Designed and built with all the love in the world @twitter by @mdo and @fat.\n */\n"
  , ERROR = "A less error occured trying to build your bundle. Please paste the error below in an issue for us at http://github.com/twitter/bootsrap! thanks!\n\n"
  , FILES = [ "variables.less"
            , "mixins.less"
            , "reset.less"
            , "scaffolding.less"
            , "grid.less"
            , "layouts.less"
            , "type.less"
            , "code.less"
            , "labels-badges.less"
            , "tables.less"
            , "forms.less"
            , "buttons.less"
            , "sprites.less"
            , "button-groups.less"
            , "navs.less"
            , "navbar.less"
            , "breadcrumbs.less"
            , "pagination.less"
            , "pager.less"
            , "thumbnails.less"
            , "alerts.less"
            , "progress-bars.less"
            , "hero-unit.less"
            , "tooltip.less"
            , "popovers.less"
            , "modals.less"
            , "dropdowns.less"
            , "accordion.less"
            , "carousel.less"
            , "wells.less"
            , "close.less"
            , "utilities.less"
            , "component-animations.less"
            , "responsive-1200px-min.less"
            , "responsive-767px-max.less"
            , "responsive-768px-979px.less"
            , "responsive-navbar.less"
            , "responsive-utilities.less" ]

function cache(callback) {
  var complete = 0
    , _cache   = {}

  FILES.forEach(function (filename) {
    var req
      , res
      , content = []
      , options = {
          host: 'raw.github.com'
        , port: 443
        , path: path.join('/twitter/bootstrap/', BRANCH, '/less/', filename)
        , method: 'GET'
        }

    req = https.request(options, function(res) {

      res.setEncoding('utf8')

      res.on('data', function (chunk) {
        content.push(chunk)
      })

      res.on('end', function () {

        _cache[filename] = content.join(' ')

        if (++complete == FILES.length) {
          CACHE = _cache
          callback && callback(null, CACHE)
        }

      })
    })

    req.end()
  })
}

function css(params, callback) {

  var result = ''

  result += CACHE['variables.less']
  result += generateCustomCSS(params)
  result += CACHE['mixins.less']

  params.css.forEach(function (filename) {
    result += CACHE[filename]
  })

  result = result.replace(/@import[^\n]*/gi, '') //strip any imports

  try {
    var parser = new less.Parser({
        paths: ['variables.less', 'mixins.less']
      , optimization: 0
      , filename: 'bootstrap.css'
    }).parse(result, function (err, tree) {
      if (err) callback(null, {'css/error.txt': new Buffer(ERROR + '\n' + JSON.stringify(err), 'utf8')})
      callback(null, {
        'css/bootstrap.css'    : new Buffer(CW + tree.toCSS(), 'utf8')
      , 'css/bootstrap.min.css': new Buffer(CW + tree.toCSS({ compress: true }), 'utf8')
      })
    })
  } catch (err) {
    callback(null, {'css/error.txt': new Buffer(ERROR + '\n' + JSON.stringify(err), 'utf8')})
  }

}

function generateCustomCSS (params) {
  return params.vars ? Object.keys(params.vars)
  .map(function (key) {
    return params.vars[key] ? (key + ': ' + params.vars[key] + ';') : ''
  })
  .join('\n') + '\n\n' : ''
}

module.exports = css
module.exports.cache = cache
module.exports.FILES = FILES
<|endoftext|>


<commit_before>function Patch() {
    let pointList = [];

    this.node = document.createElementNS("http://www.w3.org/2000/svg", "polygon");

    this.state = "normal";

    function build(arg) {
        let res = [];
        for (let i = 0, l = arg.length; i < l; i++) {
            res.push(arg[i].join(","));
        }
        return res.join(" ");
    }

    this.attribute = function (key, val) {
        if (val === undefined) return node.getAttribute(key);
        this.node.setAttribute(key, val);
    };

    this.getPoint = function (i) {
        return pointList[i]
    };

    this.addPoint = function (x, y) {
        pointList.push([x, y]);
        this.attribute("points", build(pointList));
    };

    this.setPoints = function (points) {
        this.attribute("points", build(points));
    };

    this.setPoint = function (i, x, y) {
        pointList[i] = [x, y];
        this.attribute("points", build(pointList));
        // this.invalidate.apply(this);
    };

    this.onclick = function () {
        console.log("default onclick patch");
    };

    this.invalidate = function () {
        this.node.setAttribute("class", this.state);
    };

    this.points = function () {
        for (let i = 0, l = arguments.length; i < l; i += 2) {
            pointList.push([arguments[i], arguments[i + 1]]);
        }
        this.attribute("points", build(pointList));
    };

    // initialize "points":
    this.points.apply(this, arguments);
}

function Handle(x, y, type) {
    this.node = document.createElementNS("http://www.w3.org/2000/svg", "circle");

    this.radius = 5;

    this.x = x;
    this.y = y;

    this.type = type;

    this.id = -1;

    this.shouldDrag = false;

    this.invalidate = function () {
        this.node.setAttribute("cx", this.x);
        this.node.setAttribute("cy", this.y);
        this.node.setAttribute("r", this.radius);
        this.node.setAttribute("class", this.type);
    };

    this.setPoint = function (x, y) {
        this.x = x;
        this.y = y;
    };

    this.onMouseDown = function (evt) {
        this.shouldDrag = true;
        this.onHandlePressed(this);
    }

    this.onMouseUp = function (evt) {
        this.shouldDrag = false;
        this.onHandleReleased();
    }

    this.onHandlePressed = function (handle) {}

    this.onHandleReleased = function () {}

    this.dragHandle = function(dx, dy) {
        this.x = this.x + dx;
        this.y = this.y + dy;

        this.invalidate();
    }

    this.onHandleDrag = function (handle) {
        console.log("Dragging handle with id: " + handle.id);
    }

    this.onMouseMove = function (evt) {
        if (this.shouldDrag) {
            point = getPoint(evt);
            let dx = point.x - this.x;
            let dy = point.y - this.y;
            this.dragHandle(dx, dy);
            this.onHandleDrag(this);
        }
    }

    // Setup events for drag and resize
    this.setupEventListeners = function(selected) {
        if (selected) {
            this.node.addEventListener("mousedown", this.onMouseDownRef, true);
            this.node.addEventListener("mouseup", this.onMouseUpRef, true);
        } else {
            this.node.removeEventListener("mousedown", this.onMouseDownRef, true);
            this.node.removeEventListener("mouseup", this.onMouseUpRef, true);
            this.shouldDrag = false;
        }
    }

    this.invalidate.apply(this);

    // Ref Magic
    this.onMouseDownRef = this.onMouseDown.bind(this);
    this.onMouseUpRef = this.onMouseUp.bind(this);
}

function Path() {
    this.node = document.createElementNS("http://www.w3.org/2000/svg", "path");

    this.points = [];

    this.closePath = false;

    this.invalidate = function () {
        let d = this.build(this.points);
        this.node.setAttribute("d", d);
    };

    this.setPoints = function (points) {
        this.points = points;
        this.invalidate.apply(this);
    };

    this.clear = function () {
        this.points = [];
        this.closePath = false;

        this.node.setAttribute("d", "");
    };

    this.build = function (points) {

        let res = [];

        for (let i = 1, l = points.length; i < l; i++) {
            res.push(points[i].join(" "));
        }

        if (this.closePath) {
            return "M " + points[0].join(" ") + " L " + res.join(" L ") + " Z";
        } else {
            return "M " + points[0].join(" ") + " L " + res.join(" L ");
        }

    }

}

function Polygon(startX, startY, polygonId, type="poly") {
    this.pointsList = [[startX, startY]];

    this.handles = [];

    this.node = document.createElementNS("http://www.w3.org/2000/svg", "g");

    this.patch = new Patch();
    this.node.append(this.patch.node);

    this.path = new Path();
    this.node.append(this.path.node);

    this.polygonId = polygonId;
    this.polygonScale = 1;

    this.activeHandle = null;

    this.type = type;

    this.onPolygonClick = function (polygon) {
        console.log("default onclick polygon");
    };

    this.onPolygonModified = function (polygon) {
        console.log("default on polygon modified");
    };

    this.attribute = function (key, val) {
        if (val === undefined) return this.node.getAttribute(key); // FIXME: Does this node need to be changed to this.node?
        this.node.setAttribute(key, val);
    };

    this.addPoint = function (x, y) {
        this.pointsList.push([x, y]);
        this.setupHandle(x, y, "other", true);
        this.path.setPoints(this.pointsList);
    };

    this.setupHandle = function(x, y, tag, allowDrag) {
      let handle = new Handle(x, y, tag);

      handle.id = this.pointsList.length - 1;
      handle.onHandlePressed = this.onHPrRef;
      handle.onHandleReleased = this.onHRelRef;

      this.handles.push(handle);
      this.node.append(handle.node);

      if (allowDrag) {
          handle.setupEventListeners(true);
      }
    }

    this.removePoint = function (ind) {
        let point = (this.pointsList.splice(ind, 1))[0];

        let handle = this.handles[ind];
        this.node.removeChild(handle.node);

        this.handles.splice(ind, 1);

        if (this.pointsList.length > 1) {
            this.path.setPoints(this.pointsList);
        } else {
            this.path.clear();
        }

        return point;
    };

    this.onHandleDrag = function (handle, dx, dy) {
        this.pointsList[handle.id] = [handle.x + dx, handle.y + dy];
        this.path.setPoints(this.pointsList);

        if (this.path.closePath) {
          this.patch.setPoints(this.pointsList);
          this.patch.invalidate();
        }

        handle.x = this.pointsList[handle.id][0];
        handle.y = this.pointsList[handle.id][1];

        handle.invalidate.apply(handle);

        this.onPolygonModified(this);
    }

    this.onHandlePressed = function (handle) {
        this.activeHandle = handle;
        // console.log("Handle pressed: " + handle.id);
    }

    this.onHandleReleased = function () {
        this.activeHandle = null;
        // console.log("Handle released");
    }

    this.onDrag = function (evt) {
        point  = getPoint(evt);

        if (this.type === "poly" && this.activeHandle !== null) {
            this.activeHandle.x = point.x;
            this.activeHandle.y = point.y;

            this.onHandleDrag(this.activeHandle, point.x - this.activeHandle.x, point.y - this.activeHandle.y);
        } else if (type === "rect") {
            // this.setupHandle(point.x, point.y, "other", false);
        }
    }

    this.shouldClose = function (x, y) {
        let x0 = this.pointsList[0][0];
        let y0 = this.pointsList[0][1];

        let dist = Math.sqrt((x0 - x) * (x0 - x) + (y0 - y) * (y0 - y));

        return dist < 8;
    };

    this.onclick = function (event) {
        console.log("Polygon on click");
        event.stopPropagation();
        this.onPolygonClick(this);
    };

    this.close = function () {
        this.patch.setPoints(this.pointsList);
        this.patch.invalidate();

        this.path.closePath = true;
        this.path.invalidate();

        for (let i in this.handles) {
            this.handles[i].type = "normal";
            this.handles[i].invalidate();
        }
    };

    this.setSelected = function (selected) {

        let type = "normal";
        let svgParent = this.node.parentNode;

        if (selected) {
            type = "selected";
        }

        this.patch.state = type;
        this.patch.invalidate();

        for (let i in this.handles) {

            this.handles[i].id = i;
            this.handles[i].setupEventListeners(selected);

            this.handles[i].type = type;
            this.handles[i].invalidate();
        }
    };

    this.scale = function (scaleFactor) {

        this.polygonScale = this.polygonScale * scaleFactor;
        this.pointsList = this.scalePoints.apply(this, [scaleFactor]);

        for (let i = 0; i < this.pointsList.length; i++) {
            this.handles[i].setPoint(this.pointsList[i][0], this.pointsList[i][1]);
            this.handles[i].invalidate();

            this.path.setPoints(this.pointsList);

            if (this.path.closePath) {
                this.patch.setPoints(this.pointsList);
                this.patch.invalidate();
            }

        }
    };

    this.resetScale = function () {
        this.scale.apply(this, [1 / this.polygonScale])
    };

    this.scalePoints = function (scaleFactor) {
        // Create a deep copy of pointsList. If you know a better way, let me know
        let scaledPts = JSON.parse(JSON.stringify(this.pointsList));

        for (let i = 0; i < scaledPts.length; i++) {
            let pt = scaledPts[i];
            pt[0] = pt[0] * scaleFactor;
            pt[1] = pt[1] * scaleFactor;
        }

        return scaledPts;
    };

    this.unscaledPoints = function () {
        return this.scalePoints.apply(this, [1 / this.polygonScale]);
    };

    this.setDragEnabled = function (enabled) {
        let svgParent = this.node.parentNode;

        if (enabled) {
            svgParent.addEventListener("mousemove", this.onDragRef, true);
            svgParent.addEventListener("mouseup", this.onHRelRef, true);
        } else {
            svgParent.removeEventListener("mousemove", this.onDragRef);
            svgParent.removeEventListener("mouseup", this.onHRelRef);
        }
    }

    // Consume event if the click is near one of the points of the selected polygon
    // Any ideas how to do it better?
    this.shouldConsumeEvent = function (event) {

        evPoint = getPoint(event);

        let minDist = 99;

        for (pt in this.pointsList) {
          let x0 = this.pointsList[pt][0];
          let y0 = this.pointsList[pt][1];

          let dist = Math.sqrt((x0 - evPoint.x) * (x0 - evPoint.x) + (y0 - evPoint.y) * (y0 - evPoint.y));

          if (dist < minDist) {
              minDist = dist;
          }
        }
        return minDist < 2;
    }

    // Setup event listeners
    this.patch.node.addEventListener("click", this.onclick.bind(this), true);

    // Some magic:
    this.onDragRef = this.onDrag.bind(this);
    this.onHRelRef = this.onHandleReleased.bind(this);
    this.onHPrRef = this.onHandlePressed.bind(this);

    this.setupHandle(startX, startY, "first", false);

}
<commit_msg>Reformatted code in polygon_primitives.js<commit_after>function Patch() {
    let pointList = [];

    this.node = document.createElementNS("http://www.w3.org/2000/svg", "polygon");

    this.state = "normal";

    function build(arg) {
        let res = [];
        for (let i = 0, l = arg.length; i < l; i++) {
            res.push(arg[i].join(","));
        }
        return res.join(" ");
    }

    this.attribute = function (key, val) {
        if (val === undefined) return node.getAttribute(key);
        this.node.setAttribute(key, val);
    };

    this.getPoint = function (i) {
        return pointList[i]
    };

    this.addPoint = function (x, y) {
        pointList.push([x, y]);
        this.attribute("points", build(pointList));
    };

    this.setPoints = function (points) {
        this.attribute("points", build(points));
    };

    this.setPoint = function (i, x, y) {
        pointList[i] = [x, y];
        this.attribute("points", build(pointList));
        // this.invalidate.apply(this);
    };

    this.onclick = function () {
        console.log("default onclick patch");
    };

    this.invalidate = function () {
        this.node.setAttribute("class", this.state);
    };

    this.points = function () {
        for (let i = 0, l = arguments.length; i < l; i += 2) {
            pointList.push([arguments[i], arguments[i + 1]]);
        }
        this.attribute("points", build(pointList));
    };

    // initialize "points":
    this.points.apply(this, arguments);
}

function Handle(x, y, type) {
    this.node = document.createElementNS("http://www.w3.org/2000/svg", "circle");

    this.radius = 5;

    this.x = x;
    this.y = y;

    this.type = type;

    this.id = -1;

    this.shouldDrag = false;

    this.invalidate = function () {
        this.node.setAttribute("cx", this.x);
        this.node.setAttribute("cy", this.y);
        this.node.setAttribute("r", this.radius);
        this.node.setAttribute("class", this.type);
    };

    this.setPoint = function (x, y) {
        this.x = x;
        this.y = y;
    };

    this.onMouseDown = function (evt) {
        this.shouldDrag = true;
        this.onHandlePressed(this);
    };

    this.onMouseUp = function (evt) {
        this.shouldDrag = false;
        this.onHandleReleased();
    };

    this.onHandlePressed = function (handle) {
    };

    this.onHandleReleased = function () {
    };

    this.dragHandle = function (dx, dy) {
        this.x = this.x + dx;
        this.y = this.y + dy;

        this.invalidate();
    };

    this.onHandleDrag = function (handle) {
        console.log("Dragging handle with id: " + handle.id);
    };

    this.onMouseMove = function (evt) {
        if (this.shouldDrag) {
            point = getPoint(evt);
            let dx = point.x - this.x;
            let dy = point.y - this.y;
            this.dragHandle(dx, dy);
            this.onHandleDrag(this);
        }
    };

    // Setup events for drag and resize
    this.setupEventListeners = function (selected) {
        if (selected) {
            this.node.addEventListener("mousedown", this.onMouseDownRef, true);
            this.node.addEventListener("mouseup", this.onMouseUpRef, true);
        } else {
            this.node.removeEventListener("mousedown", this.onMouseDownRef, true);
            this.node.removeEventListener("mouseup", this.onMouseUpRef, true);
            this.shouldDrag = false;
        }
    };

    this.invalidate.apply(this);

    // Ref Magic
    this.onMouseDownRef = this.onMouseDown.bind(this);
    this.onMouseUpRef = this.onMouseUp.bind(this);
}

function Path() {
    this.node = document.createElementNS("http://www.w3.org/2000/svg", "path");

    this.points = [];

    this.closePath = false;

    this.invalidate = function () {
        let d = this.build(this.points);
        this.node.setAttribute("d", d);
    };

    this.setPoints = function (points) {
        this.points = points;
        this.invalidate.apply(this);
    };

    this.clear = function () {
        this.points = [];
        this.closePath = false;

        this.node.setAttribute("d", "");
    };

    this.build = function (points) {

        let res = [];

        for (let i = 1, l = points.length; i < l; i++) {
            res.push(points[i].join(" "));
        }

        if (this.closePath) {
            return "M " + points[0].join(" ") + " L " + res.join(" L ") + " Z";
        } else {
            return "M " + points[0].join(" ") + " L " + res.join(" L ");
        }

    }

}

function Polygon(startX, startY, polygonId, type = "poly") {
    this.pointsList = [[startX, startY]];

    this.handles = [];

    this.node = document.createElementNS("http://www.w3.org/2000/svg", "g");

    this.patch = new Patch();
    this.node.append(this.patch.node);

    this.path = new Path();
    this.node.append(this.path.node);

    this.polygonId = polygonId;
    this.polygonScale = 1;

    this.activeHandle = null;

    this.type = type;

    this.onPolygonClick = function (polygon) {
        console.log("default onclick polygon");
    };

    this.onPolygonModified = function (polygon) {
        console.log("default on polygon modified");
    };

    this.attribute = function (key, val) {
        if (val === undefined) return this.node.getAttribute(key); // FIXME: Does this node need to be changed to this.node?
        this.node.setAttribute(key, val);
    };

    this.addPoint = function (x, y) {
        this.pointsList.push([x, y]);
        this.setupHandle(x, y, "other", true);
        this.path.setPoints(this.pointsList);
    };

    this.setupHandle = function (x, y, tag, allowDrag) {
        let handle = new Handle(x, y, tag);

        handle.id = this.pointsList.length - 1;
        handle.onHandlePressed = this.onHPrRef;
        handle.onHandleReleased = this.onHRelRef;

        this.handles.push(handle);
        this.node.append(handle.node);

        if (allowDrag) {
            handle.setupEventListeners(true);
        }
    };

    this.removePoint = function (ind) {
        let point = (this.pointsList.splice(ind, 1))[0];

        let handle = this.handles[ind];
        this.node.removeChild(handle.node);

        this.handles.splice(ind, 1);

        if (this.pointsList.length > 1) {
            this.path.setPoints(this.pointsList);
        } else {
            this.path.clear();
        }

        return point;
    };

    this.onHandleDrag = function (handle, dx, dy) {
        this.pointsList[handle.id] = [handle.x + dx, handle.y + dy];
        this.path.setPoints(this.pointsList);

        if (this.path.closePath) {
            this.patch.setPoints(this.pointsList);
            this.patch.invalidate();
        }

        handle.x = this.pointsList[handle.id][0];
        handle.y = this.pointsList[handle.id][1];

        handle.invalidate.apply(handle);

        this.onPolygonModified(this);
    };

    this.onHandlePressed = function (handle) {
        this.activeHandle = handle;
        // console.log("Handle pressed: " + handle.id);
    };

    this.onHandleReleased = function () {
        this.activeHandle = null;
        // console.log("Handle released");
    };

    this.onDrag = function (evt) {
        point = getPoint(evt);

        if (this.type === "poly" && this.activeHandle !== null) {
            this.activeHandle.x = point.x;
            this.activeHandle.y = point.y;

            this.onHandleDrag(this.activeHandle, point.x - this.activeHandle.x, point.y - this.activeHandle.y);
        } else if (type === "rect") {
            // this.setupHandle(point.x, point.y, "other", false);
        }
    };

    this.shouldClose = function (x, y) {
        let x0 = this.pointsList[0][0];
        let y0 = this.pointsList[0][1];

        let dist = Math.sqrt((x0 - x) * (x0 - x) + (y0 - y) * (y0 - y));

        return dist < 8;
    };

    this.onclick = function (event) {
        console.log("Polygon on click");
        event.stopPropagation();
        this.onPolygonClick(this);
    };

    this.close = function () {
        this.patch.setPoints(this.pointsList);
        this.patch.invalidate();

        this.path.closePath = true;
        this.path.invalidate();

        for (let i in this.handles) {
            this.handles[i].type = "normal";
            this.handles[i].invalidate();
        }
    };

    this.setSelected = function (selected) {

        let type = "normal";
        let svgParent = this.node.parentNode;

        if (selected) {
            type = "selected";
        }

        this.patch.state = type;
        this.patch.invalidate();

        for (let i in this.handles) {

            this.handles[i].id = i;
            this.handles[i].setupEventListeners(selected);

            this.handles[i].type = type;
            this.handles[i].invalidate();
        }
    };

    this.scale = function (scaleFactor) {

        this.polygonScale = this.polygonScale * scaleFactor;
        this.pointsList = this.scalePoints.apply(this, [scaleFactor]);

        for (let i = 0; i < this.pointsList.length; i++) {
            this.handles[i].setPoint(this.pointsList[i][0], this.pointsList[i][1]);
            this.handles[i].invalidate();

            this.path.setPoints(this.pointsList);

            if (this.path.closePath) {
                this.patch.setPoints(this.pointsList);
                this.patch.invalidate();
            }

        }
    };

    this.resetScale = function () {
        this.scale.apply(this, [1 / this.polygonScale])
    };

    this.scalePoints = function (scaleFactor) {
        // Create a deep copy of pointsList. If you know a better way, let me know
        let scaledPts = JSON.parse(JSON.stringify(this.pointsList));

        for (let i = 0; i < scaledPts.length; i++) {
            let pt = scaledPts[i];
            pt[0] = pt[0] * scaleFactor;
            pt[1] = pt[1] * scaleFactor;
        }

        return scaledPts;
    };

    this.unscaledPoints = function () {
        return this.scalePoints.apply(this, [1 / this.polygonScale]);
    };

    this.setDragEnabled = function (enabled) {
        let svgParent = this.node.parentNode;

        if (enabled) {
            svgParent.addEventListener("mousemove", this.onDragRef, true);
            svgParent.addEventListener("mouseup", this.onHRelRef, true);
        } else {
            svgParent.removeEventListener("mousemove", this.onDragRef);
            svgParent.removeEventListener("mouseup", this.onHRelRef);
        }
    };

    // Consume event if the click is near one of the points of the selected polygon
    // Any ideas how to do it better?
    this.shouldConsumeEvent = function (event) {

        evPoint = getPoint(event);

        let minDist = 99;

        for (pt of this.pointsList) {
            let x0 = this.pointsList[pt][0];
            let y0 = this.pointsList[pt][1];

            let dist = Math.sqrt((x0 - evPoint.x) * (x0 - evPoint.x) + (y0 - evPoint.y) * (y0 - evPoint.y));

            if (dist < minDist) {
                minDist = dist;
            }
        }
        return minDist < 2;
    };

    // Setup event listeners
    this.patch.node.addEventListener("click", this.onclick.bind(this), true);

    // Some magic:
    this.onDragRef = this.onDrag.bind(this);
    this.onHRelRef = this.onHandleReleased.bind(this);
    this.onHPrRef = this.onHandlePressed.bind(this);

    this.setupHandle(startX, startY, "first", false);

}
<|endoftext|>


<commit_before>import Ember from 'ember';
import ENV from '../config/environment';
import ApplicationRouteMixin from 'simple-auth/mixins/application-route-mixin';

export default Ember.Route.extend(ApplicationRouteMixin, {
  actions: {
    logout() {
      this.get('session').invalidate()
        .then(() => {
          this.transitionTo('index');
        }, () => {
          Ember.Logger.debug('Session invalidation failed!');
        });
    },
    openModal(name, model) {
      this.render(name, {
        into: 'application',
        outlet: 'modal',
        model: model
      });
    },
    closeModal() {
      return this.disconnectOutlet({
        outlet: 'modal',
        parentView: 'application'
      });
    }
  },

  socketService: Ember.inject.service('websockets'),

  socket: null,

  connect({identification, password}) {
    let socket = this.get('socketService').socketFor(`ws://${identification}:${password}@${ENV.APP.WS_PATH}`);
    this.set('socket', socket);

    socket.on('open', this.openHandler, this);
    socket.on('message', this.messageHandler, this);
    socket.on('close', this.closeHandler, this);
  },

  disconnect() {
    let socket = this.get('socket');
    if (socket) {
      socket.close();
      this.set('socket', null);
    }
  },

  openHandler() {
    console.log('open');
  },

  messageHandler(data) {
    console.log('message: ' + JSON.stringify(data));
    // TODO: Fix getting store
    this.get('store').pushPayload(data);
  },

  closeHandler() {
    console.log('close');
  }
});
<commit_msg>websocket: fix duplicate frontend data<commit_after>import Ember from 'ember';
import ENV from '../config/environment';
import ApplicationRouteMixin from 'simple-auth/mixins/application-route-mixin';

export default Ember.Route.extend(ApplicationRouteMixin, {
  actions: {
    logout() {
      this.get('session').invalidate()
        .then(() => {
          this.transitionTo('index');
        }, () => {
          Ember.Logger.debug('Session invalidation failed!');
        });
    },
    openModal(name, model) {
      this.render(name, {
        into: 'application',
        outlet: 'modal',
        model: model
      });
    },
    closeModal() {
      return this.disconnectOutlet({
        outlet: 'modal',
        parentView: 'application'
      });
    }
  },

  socketService: Ember.inject.service('websockets'),

  socket: null,

  connect({identification, password}) {
    let socket = this.get('socketService').socketFor(`ws://${identification}:${password}@${ENV.APP.WS_PATH}`);
    this.set('socket', socket);

    socket.on('open', this.openHandler, this);
    socket.on('message', this.messageHandler, this);
    socket.on('close', this.closeHandler, this);
  },

  disconnect() {
    let socket = this.get('socket');
    if (socket) {
      socket.close();
      this.set('socket', null);
    }
  },

  openHandler() {
    console.log('open');
  },

  messageHandler(data) {
    let payload = JSON.stringify(data);
    console.log('message: ' + payload);
    this.notify.info('Push update: ' + payload);
  },

  closeHandler() {
    console.log('close');
  }
});
<|endoftext|>