<commit_before>import {
  name as LIB_NAME,
  version as LIB_VERSION
} from '../../package.json';

const {
  hasOwnProperty,
  toString
} = Object.prototype;

function _isBasicObject(val) {
  return typeof val === 'object' &&
    val !== null &&
    val.__proto__ === undefined;
}

function _argsStr(count, name = 'arg') {
  let names = [];

  for (let i = 0; i < count; i++) {
    names.push(`${name}${i + 1}`);
  }

  return names.join(', ');
}

function typeStr(val, k = undefined) {
  let t = (_isBasicObject(val)) ?
    'BasicObject' :
    toString.call(val).match(/^\[object ([^\]]*)\]$/)[1];

  if (val instanceof Object) {
    if (val.constructor) {
      if (val.constructor.name) {
        if (val.constructor.name !== t) {
          let name = val.constructor.name;

          if (t === 'Object') {
            t = name;
          } else if (name !== 'Object') {
            if (t.indexOf(name) >= 0) {
              //t = t;
            } else if (name.indexOf(t) >= 0) {
              t = name;
            } else {
              if (!t.endsWith('Prototype')) {
                t = `${t}(ctor:${name})`;
              }
            }
          }
        }
      } else {
        if (!t.endsWith('Prototype')) {
          t = `${t}(ctor:Anonymous)`;
        }
      }
    }
  }

  if (val instanceof Error) {
    // name might be a getter that throws
    try {
      let name = val.name;

      if (name && name !== t) {
        t = name;
      }
    } catch (err) {}
  }

  if (val instanceof Function) {
    if (val.name && val.name !== t && (
      val.name.match(/^[A-Z]/) ||
      (k &&
        ['__apivis__chain_link',
          'constructor',
          'prototype',
          '__proto__'
        ].includes(k)
      )
    )) {
      t = val.name;
    }

    t = `${t}(${_argsStr(val.length)})`;
  }

  if (val && (
    (val.hasOwnProperty && val.hasOwnProperty('constructor'))
  )) {
    if (!t.endsWith('Prototype') && (
      (t !== 'Object' || val === Object.prototype)
    )) {
      t = `${t}.prototype`;
    }
  }

  return t;
}

function valueStr(val) {
  switch (typeof val) {
  case 'boolean':
  case 'number':
    return `${val}`;
  case 'string':
    return JSON.stringify(val);
  case 'object':
    if (Array.isArray(val) && val !== Array.prototype) {
      return `${val.length}`;
    } else if (val instanceof Date) {
      return JSON.stringify(val);
    } else if (val instanceof Error) {
      // message might be a getter that throws
      try {
        let msg = val.message;

        if (msg) {
          return JSON.stringify(msg);
        }
      } catch (err) {
        return '';
      }
    }
  default:
    return '';
  }
}

function descStr(val, k) {
  if (val === undefined || val === null) {
    return 'n/a';
  }

  let desc = Object.getOwnPropertyDescriptor(val, k);
  let d1 = '';
  let d2 = '';

  if (desc === undefined) {
    return 'n/a';
  }

  if (desc.hasOwnProperty('value')) { d1 += 'v'; }
  if (desc.writable) { d1 += 'w'; }
  if (desc.get) { d1 += 'g'; }
  if (desc.set) { d1 += 's'; }
  if (desc.enumerable) { d2 += 'e'; }
  if (desc.configurable) { d2 += 'c'; }

  return (d2) ? `${d1} ${d2}` : d1;
}

const _getterTagDummy = {
  __proto__: {
    get [Symbol.toStringTag]() { return 'Getter'; }
  }
};

const _noop = () => {};
const _swallowPromiseRejection = v => (
  (typeof v === 'object' && v !== null &&
    v !== Promise.prototype && typeof v.catch === 'function' &&
      v.catch(_noop)),
  v
);

function memberStr(val, k, leaf = val) {
  let sk = String(k);
  let sd = descStr(val, k);
  let isGetter = sd.includes('g');
  // Do not attempt to resolve these
  let skip = [
    'arguments',
    'callee',
    'caller'
  ];
  // Only resolve these in the context of leaf
  let leafOnly = [
    '__proto__'
  ];
  let st;
  let v;
  let sv = '';

  // First resolve k in the context of leaf (like it would be normally)
  try {
    if (!skip.includes(k)) {
      v = _swallowPromiseRejection(leaf[k]);
    }
  } catch (err) {
    v = (isGetter) ? _getterTagDummy : err;
  }

  // Then try resolving k in the context of val (reached through
  // following __proto__) to eventually get a shadowed value (some
  // props only make sense when resolved in the context of leaf
  // and an exception will be thrown upon trying to access them through val)
  try {
    if ( !(val === leaf || leafOnly.includes(k) || skip.includes(k)) ) {
      let shadowed = _swallowPromiseRejection(val[k]);

      if (shadowed !== undefined && shadowed !== null) {
        v = shadowed;
      }
    }
  } catch (err) {
    // Leave v as set by trying to resolve k in the context of leaf
  }

  st = typeStr(v, k);
  sv = valueStr(v);

  return `${sk}{${sd}}: ${st}${(sv) ? `:${sv}` : ''}`;
}

function memberInfo(val, k, seen) {
  let sk = String(k);
  let sd = descStr(val, k);
  let isGetter = sd.includes('g');
  // Do not attempt to resolve these
  let skip = [
    'arguments',
    'callee',
    'caller'
  ];
  let iSeen = -1;
  let sSeen;
  let st;
  let v;
  let sv = '';

  try {
    if (!skip.includes(k)) {
      v = _swallowPromiseRejection(val[k]);
    }
  } catch (err) {
    v = (isGetter) ? _getterTagDummy : err;
  }

  iSeen = seen.findIndex(kv => v === kv[1]);
  sSeen = (iSeen >= 0) ? `->${seen[iSeen][0]}` : '';
  st = typeStr(v, k);
  sv = valueStr(v);

  return {
    v,
    s: `${sk}{${sd}}${sSeen}: ${st}${(sv) ? `:${sv}` : ''}`,
    seen: iSeen >= 0
  };
}

const _compare = (a, b) => {
  let sa = String(a);
  let sb = String(b);
  let na;
  let nb;

  if (Number.isNaN(na = Number(sa)) || Number.isNaN(nb = Number(sb))) {
    return (sa < sb) ? -1 : (sa > sb) ? 1 : 0;
  }

  return na - nb;
};

const _keys = (val, kind) =>
  (val === undefined || val === null) ?
    [] :
    Object[`getOwnProperty${kind}`](val).sort(_compare);

const _symbols = val => _keys(val, 'Symbols');
const _names = val => _keys(val, 'Names');

const members = val => _symbols(val).concat(_names(val));

function membersStr(val, indent = '  ', level = 0, leaf = val) {
  return members(val).
    map(k => `${indent.repeat(level)}${memberStr(val, k, leaf)}`).
    join('\n');
}

const _trackedReference = v =>
  (typeof v === 'object' && v !== null &&
    v !== _getterTagDummy) ||
  typeof v === 'function';
const _descendableObject = v =>
  typeof v === 'object' && v !== null &&
    v !== _getterTagDummy;
const _maybeConstructor = v =>
  // Assumes typeof v === 'function'
  hasOwnProperty.call(v, 'prototype') &&
    v.name && v.name.match(/^[A-Z]/);
const _descendableFunctionWhitelist = v =>
  // Assumes typeof v === 'function'
  v === Proxy ||
  (typeof _ === 'function' && v === _) ||
  (typeof $ === 'function' && v === $);
const _descendableFunction = v =>
  typeof v === 'function' &&
    (_maybeConstructor(v) || _descendableFunctionWhitelist(v));

const _shouldDescend = (k, v, level) =>
  (_descendableObject(v) || _descendableFunction(v));

function _inspectStr(val, k,
  indent = '  ', level = 1,
  seen = [['ROOT', val]], path = []
) {
  let mi = memberInfo(val, k, seen);
  let v = mi.v;
  let result = [`${indent.repeat(level)}${mi.s}`];

  if (!mi.seen && _trackedReference(v)) {
    path.push(String(k));
    seen.push([path.join('.'), v]);

    if (_shouldDescend(k, v, level)) {
      members(v).forEach(_k => result.push(
        _inspectStr(v, _k, indent, level + 1, seen, path)
      ));
    }

    path.pop();
  }

  return result.join('\n');
}

function inspectStr(val, indent = '  ') {
  let st = typeStr(val);
  let sv = valueStr(val);
  let result = [`${st}${(sv) ? `:${sv}` : ''}`];
  let seen = [['ROOT', val]];

  members(val).forEach(k => result.push(
    _inspectStr(val, k, indent, 1, seen)
  ));

  return result.join('\n');
}

function chain(val) {
  let links = [val];

  for (let link = Object.getPrototypeOf(val);
    link;
    link = Object.getPrototypeOf(link)
  ) {
    links.push(link);
  }

  return links;
}

function chainStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]`).
    join('\n');
}

function apiStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]\n${membersStr(v, indent, i + 1, val)}`).
    join('\n');
}

// peek42 plugin
function peek42(fnOutput, fnComment) {
  return {
    type(val, comment = undefined, opts = undefined) {
      fnOutput(
        typeStr(val),
        fnComment(comment, val, 'type'),
        opts
      );
    },
    desc(val, k, comment = undefined, opts = undefined) {
      fnOutput(
        descStr(val, k),
        fnComment(comment, `${String(k)} in ${typeStr(val)}`, 'desc'),
        opts
      );
    },
    member(val, k, comment = undefined, opts = undefined) {
      fnOutput(
        memberStr(val, k),
        fnComment(comment, `${String(k)} in ${typeStr(val)}`, 'member'),
        opts
      );
    },
    members(val, comment = undefined, opts = undefined) {
      fnOutput(
        membersStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined,
          (opts && typeof opts.indentLevel === 'number') ?
            opts.indentLevel :
            undefined
        ),
        fnComment(comment, typeStr(val), 'members'),
        opts
      );
    },
    inspect(val, comment = undefined, opts = undefined) {
      fnOutput(
        inspectStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'inspect'),
        opts
      );
    },
    chain(val, comment = undefined, opts = undefined) {
      fnOutput(
        chainStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'chain'),
        opts
      );
    },
    api(val, comment = undefined, opts = undefined) {
      fnOutput(
        apiStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'api'),
        opts
      );
    }
  };
}

const apivis = {
  get [Symbol.toStringTag]() {
    return LIB_NAME;
  },
  version: LIB_VERSION,
  typeStr,
  descStr,
  memberStr,
  members,
  membersStr,
  inspectStr,
  chain,
  chainStr,
  apiStr,
  peek42
};

export {
  typeStr,
  descStr,
  memberStr,
  members,
  membersStr,
  inspectStr,
  chain,
  chainStr,
  apiStr
};
export default apivis;
<commit_msg>Tweak the display of null proto objects<commit_after>import {
  name as LIB_NAME,
  version as LIB_VERSION
} from '../../package.json';

const {
  hasOwnProperty,
  toString
} = Object.prototype;

function _isNullProtoObject(val) {
  return typeof val === 'object' &&
    val !== null &&
    val.__proto__ === undefined;
}

function _argsStr(count, name = 'arg') {
  let names = [];

  for (let i = 0; i < count; i++) {
    names.push(`${name}${i + 1}`);
  }

  return names.join(', ');
}

function typeStr(val, k = undefined) {
  let t = (_isNullProtoObject(val)) ?
    'Object(proto:Null)' :
    toString.call(val).match(/^\[object ([^\]]*)\]$/)[1];

  if (val instanceof Object) {
    if (val.constructor) {
      if (val.constructor.name) {
        if (val.constructor.name !== t) {
          let name = val.constructor.name;

          if (t === 'Object') {
            t = name;
          } else if (name !== 'Object') {
            if (t.indexOf(name) >= 0) {
              //t = t;
            } else if (name.indexOf(t) >= 0) {
              t = name;
            } else {
              if (!t.endsWith('Prototype')) {
                t = `${t}(ctor:${name})`;
              }
            }
          }
        }
      } else {
        if (!t.endsWith('Prototype')) {
          t = `${t}(ctor:Anonymous)`;
        }
      }
    }
  }

  if (val instanceof Error) {
    // name might be a getter that throws
    try {
      let name = val.name;

      if (name && name !== t) {
        t = name;
      }
    } catch (err) {}
  }

  if (val instanceof Function) {
    if (val.name && val.name !== t && (
      val.name.match(/^[A-Z]/) ||
      (k &&
        ['__apivis__chain_link',
          'constructor',
          'prototype',
          '__proto__'
        ].includes(k)
      )
    )) {
      t = val.name;
    }

    t = `${t}(${_argsStr(val.length)})`;
  }

  if (val && (
    (val.hasOwnProperty && val.hasOwnProperty('constructor'))
  )) {
    if (!t.endsWith('Prototype') && (
      (t !== 'Object' || val === Object.prototype)
    )) {
      t = `${t}.prototype`;
    }
  }

  return t;
}

function valueStr(val) {
  switch (typeof val) {
  case 'boolean':
  case 'number':
    return `${val}`;
  case 'string':
    return JSON.stringify(val);
  case 'object':
    if (Array.isArray(val) && val !== Array.prototype) {
      return `${val.length}`;
    } else if (val instanceof Date) {
      return JSON.stringify(val);
    } else if (val instanceof Error) {
      // message might be a getter that throws
      try {
        let msg = val.message;

        if (msg) {
          return JSON.stringify(msg);
        }
      } catch (err) {
        return '';
      }
    }
  default:
    return '';
  }
}

function descStr(val, k) {
  if (val === undefined || val === null) {
    return 'n/a';
  }

  let desc = Object.getOwnPropertyDescriptor(val, k);
  let d1 = '';
  let d2 = '';

  if (desc === undefined) {
    return 'n/a';
  }

  if (desc.hasOwnProperty('value')) { d1 += 'v'; }
  if (desc.writable) { d1 += 'w'; }
  if (desc.get) { d1 += 'g'; }
  if (desc.set) { d1 += 's'; }
  if (desc.enumerable) { d2 += 'e'; }
  if (desc.configurable) { d2 += 'c'; }

  return (d2) ? `${d1} ${d2}` : d1;
}

const _getterTagDummy = {
  __proto__: {
    get [Symbol.toStringTag]() { return 'Getter'; }
  }
};

const _noop = () => {};
const _swallowPromiseRejection = v => (
  (typeof v === 'object' && v !== null &&
    v !== Promise.prototype && typeof v.catch === 'function' &&
      v.catch(_noop)),
  v
);

function memberStr(val, k, leaf = val) {
  let sk = String(k);
  let sd = descStr(val, k);
  let isGetter = sd.includes('g');
  // Do not attempt to resolve these
  let skip = [
    'arguments',
    'callee',
    'caller'
  ];
  // Only resolve these in the context of leaf
  let leafOnly = [
    '__proto__'
  ];
  let st;
  let v;
  let sv = '';

  // First resolve k in the context of leaf (like it would be normally)
  try {
    if (!skip.includes(k)) {
      v = _swallowPromiseRejection(leaf[k]);
    }
  } catch (err) {
    v = (isGetter) ? _getterTagDummy : err;
  }

  // Then try resolving k in the context of val (reached through
  // following __proto__) to eventually get a shadowed value (some
  // props only make sense when resolved in the context of leaf
  // and an exception will be thrown upon trying to access them through val)
  try {
    if ( !(val === leaf || leafOnly.includes(k) || skip.includes(k)) ) {
      let shadowed = _swallowPromiseRejection(val[k]);

      if (shadowed !== undefined && shadowed !== null) {
        v = shadowed;
      }
    }
  } catch (err) {
    // Leave v as set by trying to resolve k in the context of leaf
  }

  st = typeStr(v, k);
  sv = valueStr(v);

  return `${sk}{${sd}}: ${st}${(sv) ? `:${sv}` : ''}`;
}

function memberInfo(val, k, seen) {
  let sk = String(k);
  let sd = descStr(val, k);
  let isGetter = sd.includes('g');
  // Do not attempt to resolve these
  let skip = [
    'arguments',
    'callee',
    'caller'
  ];
  let iSeen = -1;
  let sSeen;
  let st;
  let v;
  let sv = '';

  try {
    if (!skip.includes(k)) {
      v = _swallowPromiseRejection(val[k]);
    }
  } catch (err) {
    v = (isGetter) ? _getterTagDummy : err;
  }

  iSeen = seen.findIndex(kv => v === kv[1]);
  sSeen = (iSeen >= 0) ? `->${seen[iSeen][0]}` : '';
  st = typeStr(v, k);
  sv = valueStr(v);

  return {
    v,
    s: `${sk}{${sd}}${sSeen}: ${st}${(sv) ? `:${sv}` : ''}`,
    seen: iSeen >= 0
  };
}

const _compare = (a, b) => {
  let sa = String(a);
  let sb = String(b);
  let na;
  let nb;

  if (Number.isNaN(na = Number(sa)) || Number.isNaN(nb = Number(sb))) {
    return (sa < sb) ? -1 : (sa > sb) ? 1 : 0;
  }

  return na - nb;
};

const _keys = (val, kind) =>
  (val === undefined || val === null) ?
    [] :
    Object[`getOwnProperty${kind}`](val).sort(_compare);

const _symbols = val => _keys(val, 'Symbols');
const _names = val => _keys(val, 'Names');

const members = val => _symbols(val).concat(_names(val));

function membersStr(val, indent = '  ', level = 0, leaf = val) {
  return members(val).
    map(k => `${indent.repeat(level)}${memberStr(val, k, leaf)}`).
    join('\n');
}

const _trackedReference = v =>
  (typeof v === 'object' && v !== null &&
    v !== _getterTagDummy) ||
  typeof v === 'function';
const _descendableObject = v =>
  typeof v === 'object' && v !== null &&
    v !== _getterTagDummy;
const _maybeConstructor = v =>
  // Assumes typeof v === 'function'
  hasOwnProperty.call(v, 'prototype') &&
    v.name && v.name.match(/^[A-Z]/);
const _descendableFunctionWhitelist = v =>
  // Assumes typeof v === 'function'
  v === Proxy ||
  (typeof _ === 'function' && v === _) ||
  (typeof $ === 'function' && v === $);
const _descendableFunction = v =>
  typeof v === 'function' &&
    (_maybeConstructor(v) || _descendableFunctionWhitelist(v));

const _shouldDescend = (k, v, level) =>
  (_descendableObject(v) || _descendableFunction(v));

function _inspectStr(val, k,
  indent = '  ', level = 1,
  seen = [['ROOT', val]], path = []
) {
  let mi = memberInfo(val, k, seen);
  let v = mi.v;
  let result = [`${indent.repeat(level)}${mi.s}`];

  if (!mi.seen && _trackedReference(v)) {
    path.push(String(k));
    seen.push([path.join('.'), v]);

    if (_shouldDescend(k, v, level)) {
      members(v).forEach(_k => result.push(
        _inspectStr(v, _k, indent, level + 1, seen, path)
      ));
    }

    path.pop();
  }

  return result.join('\n');
}

function inspectStr(val, indent = '  ') {
  let st = typeStr(val);
  let sv = valueStr(val);
  let result = [`${st}${(sv) ? `:${sv}` : ''}`];
  let seen = [['ROOT', val]];

  members(val).forEach(k => result.push(
    _inspectStr(val, k, indent, 1, seen)
  ));

  return result.join('\n');
}

function chain(val) {
  let links = [val];

  for (let link = Object.getPrototypeOf(val);
    link;
    link = Object.getPrototypeOf(link)
  ) {
    links.push(link);
  }

  return links;
}

function chainStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]`).
    join('\n');
}

function apiStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]\n${membersStr(v, indent, i + 1, val)}`).
    join('\n');
}

// peek42 plugin
function peek42(fnOutput, fnComment) {
  return {
    type(val, comment = undefined, opts = undefined) {
      fnOutput(
        typeStr(val),
        fnComment(comment, val, 'type'),
        opts
      );
    },
    desc(val, k, comment = undefined, opts = undefined) {
      fnOutput(
        descStr(val, k),
        fnComment(comment, `${String(k)} in ${typeStr(val)}`, 'desc'),
        opts
      );
    },
    member(val, k, comment = undefined, opts = undefined) {
      fnOutput(
        memberStr(val, k),
        fnComment(comment, `${String(k)} in ${typeStr(val)}`, 'member'),
        opts
      );
    },
    members(val, comment = undefined, opts = undefined) {
      fnOutput(
        membersStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined,
          (opts && typeof opts.indentLevel === 'number') ?
            opts.indentLevel :
            undefined
        ),
        fnComment(comment, typeStr(val), 'members'),
        opts
      );
    },
    inspect(val, comment = undefined, opts = undefined) {
      fnOutput(
        inspectStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'inspect'),
        opts
      );
    },
    chain(val, comment = undefined, opts = undefined) {
      fnOutput(
        chainStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'chain'),
        opts
      );
    },
    api(val, comment = undefined, opts = undefined) {
      fnOutput(
        apiStr(val,
          (opts && typeof opts.indent === 'string') ?
            opts.indent :
            undefined
        ),
        fnComment(comment, typeStr(val), 'api'),
        opts
      );
    }
  };
}

const apivis = {
  get [Symbol.toStringTag]() {
    return LIB_NAME;
  },
  version: LIB_VERSION,
  typeStr,
  descStr,
  memberStr,
  members,
  membersStr,
  inspectStr,
  chain,
  chainStr,
  apiStr,
  peek42
};

export {
  typeStr,
  descStr,
  memberStr,
  members,
  membersStr,
  inspectStr,
  chain,
  chainStr,
  apiStr
};
export default apivis;
<|endoftext|>


<commit_before>/**
 * ADMIN COMMANDS - MAP
 */
'use strict';

/**
 * Map Commands.
 *
 * @class
 */
module.exports.default = class {
  constructor (plugin) {
    this.plugin = plugin;
  }

  /**
   * Register all the commands.
   *
   * @param {object}   manager
   * @param {function} manager.on
   */
  register (manager) {
    this.server = this.plugin.server;

    /**
     * /admin skip
     * Skips current map.
     */
    manager.on('skip', {
      admin: true,
      level: 1,
      text: 'Skip current map, and directly go to the next one.'
    }, (player, params) => this._skip(player, params));

    /**
     * /admin restart
     * Restart current map.
     */
    manager.on('restart', {
      admin: true,
      level: 1,
      text: 'Restart current map.'
    }, (player, params) => this._restart(player, params));

    /**
     * /admin replay
     * Rejuke current map.
     */
    manager.on('replay', {
      admin: true,
      level: 1,
      text: 'Replay current map, add to the jukebox.'
    }, (player, params) => this._replay(player, params));

    /**
     * /admin savemaps
     * Save matchsettings list to disk!
     */
    manager.on('savemaps', {
      admin: true,
      level: 2,
      text: 'Save maplist to matchsettings configuration.'
    }, (player, params) => this._savemaplist(player, params));
  }

  _skip (player, params) {
    this.server.send().chat("$fffSkipping map...").exec();
    this.server.send().custom('NextMap').exec();
  }

  _restart (player, params) {
    this.server.send().chat("$fffRestarting map...").exec();
    this.server.send().custom('RestartMap').exec();
  }

  _replay (player, params) {
    // TODO: Add support for maniajs-jukebox
    if (this.plugin.maps.current.uid) {
      this.server.send().custom('SetNextMapIdent', [this.plugin.maps.current.uid]).exec();
      this.server.send().chat('$fffCurrent map will be replayed!').exec();
    }
  }

  _savemaplist (player, params) {
    // TODO.
  }
};
<commit_msg>Add endround command<commit_after>/**
 * ADMIN COMMANDS - MAP
 */
'use strict';

/**
 * Map Commands.
 *
 * @class
 */
module.exports.default = class {
  constructor (plugin) {
    this.plugin = plugin;
  }

  /**
   * Register all the commands.
   *
   * @param {object}   manager
   * @param {function} manager.on
   */
  register (manager) {
    this.server = this.plugin.server;

    /**
     * /admin skip
     * Skips current map.
     */
    manager.on('skip', {
      admin: true,
      level: 1,
      text: 'Skip current map, and directly go to the next one.'
    }, (player, params) => this._skip(player, params));

    /**
     * /admin restart
     * Restart current map.
     */
    manager.on('restart', {
      admin: true,
      level: 1,
      text: 'Restart current map.'
    }, (player, params) => this._restart(player, params));

    /**
     * /admin replay
     * Rejuke current map.
     */
    manager.on('replay', {
      admin: true,
      level: 1,
      text: 'Replay current map, add to the jukebox.'
    }, (player, params) => this._replay(player, params));

    /**
     * /admin endround
     * End Round.
     */
    manager.on('endround', {
      admin: true,
      level: 2,
      text: 'End current round.'
    }, (player, params) => this._endround(player, params));

    /**
     * /admin savemaps
     * Save matchsettings list to disk!
     */
    manager.on('savemaps', {
      admin: true,
      level: 2,
      text: 'Save maplist to matchsettings configuration.'
    }, (player, params) => this._savemaplist(player, params));
  }

  _skip (player, params) {
    this.server.send().chat("$fffSkipping map...").exec();
    this.server.send().custom('NextMap').exec();
  }

  _restart (player, params) {
    this.server.send().chat("$fffRestarting map...").exec();
    this.server.send().custom('RestartMap').exec();
  }

  _endround (player, params) {
    this.server.send().chat('$fffEnd round...').exec();
    this.server.send().custom('ForceEndRound').exec();
  }

  _replay (player, params) {
    // TODO: Add support for maniajs-jukebox
    if (this.plugin.maps.current.uid) {
      this.server.send().custom('SetNextMapIdent', [this.plugin.maps.current.uid]).exec();
      this.server.send().chat('$fffCurrent map will be replayed!').exec();
    }
  }

  _savemaplist (player, params) {
    // TODO.
  }
};
<|endoftext|>


<commit_before>import Promise from 'bluebird'
import Time from './time'
import UncaughtExceptionManager from './uncaught_exception_manager'
import util from 'util'

export default class UserCodeRunner {
  static async run ({argsArray, thisArg, fn, timeoutInMilliseconds}) {
    const callbackPromise = new Promise(function (resolve, reject) {
      argsArray.push(function(error, result) {
        if (error) {
          reject(error)
        } else {
          resolve(result)
        }
      })
    })

    let fnReturn
    try {
      fnReturn = fn.apply(thisArg, argsArray)
    } catch (e) {
      const error = (e instanceof Error) ? e : util.format(e)
      return {error}
    }

    const racingPromises = []
    const callbackInterface = fn.length === argsArray.length
    const promiseInterface = fnReturn && typeof fnReturn.then === 'function'

    if (callbackInterface && promiseInterface) {
      return {error: 'function uses multiple asynchronous interfaces: callback and promise'}
    } else if (callbackInterface) {
      racingPromises.push(callbackPromise)
    } else if (promiseInterface) {
      racingPromises.push(fnReturn)
    } else {
      return {result: fnReturn}
    }

    let exceptionHandler
    const uncaughtExceptionPromise = new Promise(function (resolve, reject) {
      exceptionHandler = reject
      UncaughtExceptionManager.registerHandler(exceptionHandler)
    })
    racingPromises.push(uncaughtExceptionPromise)

    const timeoutPromise = new Promise(function (resolve, reject) {
      Time.setTimeout(function() {
        const timeoutMessage = 'function timed out after ' + timeoutInMilliseconds + ' milliseconds'
        reject(new Error(timeoutMessage))
      }, timeoutInMilliseconds)
    })
    racingPromises.push(timeoutPromise)

    let error, result
    try {
      result = await Promise.race(racingPromises)
    } catch (e) {
      if ((e instanceof Error)) {
        error = e
      } else if (e) {
        error = util.format(e)
      } else {
        error = 'Promise rejected without a reason'
      }
    }

    UncaughtExceptionManager.unregisterHandler(exceptionHandler)

    return {error, result}
  }
}
<commit_msg>user code runner: clear timeouts<commit_after>import Promise from 'bluebird'
import Time from './time'
import UncaughtExceptionManager from './uncaught_exception_manager'
import util from 'util'

export default class UserCodeRunner {
  static async run ({argsArray, thisArg, fn, timeoutInMilliseconds}) {
    const callbackPromise = new Promise(function (resolve, reject) {
      argsArray.push(function(error, result) {
        if (error) {
          reject(error)
        } else {
          resolve(result)
        }
      })
    })

    let fnReturn
    try {
      fnReturn = fn.apply(thisArg, argsArray)
    } catch (e) {
      const error = (e instanceof Error) ? e : util.format(e)
      return {error}
    }

    const racingPromises = []
    const callbackInterface = fn.length === argsArray.length
    const promiseInterface = fnReturn && typeof fnReturn.then === 'function'

    if (callbackInterface && promiseInterface) {
      return {error: 'function uses multiple asynchronous interfaces: callback and promise'}
    } else if (callbackInterface) {
      racingPromises.push(callbackPromise)
    } else if (promiseInterface) {
      racingPromises.push(fnReturn)
    } else {
      return {result: fnReturn}
    }

    let exceptionHandler
    const uncaughtExceptionPromise = new Promise(function (resolve, reject) {
      exceptionHandler = reject
      UncaughtExceptionManager.registerHandler(exceptionHandler)
    })
    racingPromises.push(uncaughtExceptionPromise)

    let timeoutId
    const timeoutPromise = new Promise(function (resolve, reject) {
      timeoutId = Time.setTimeout(function() {
        const timeoutMessage = 'function timed out after ' + timeoutInMilliseconds + ' milliseconds'
        reject(new Error(timeoutMessage))
      }, timeoutInMilliseconds)
    })
    racingPromises.push(timeoutPromise)

    let error, result
    try {
      result = await Promise.race(racingPromises)
    } catch (e) {
      if ((e instanceof Error)) {
        error = e
      } else if (e) {
        error = util.format(e)
      } else {
        error = 'Promise rejected without a reason'
      }
    }

    Time.clearTimeout(timeoutId)
    UncaughtExceptionManager.unregisterHandler(exceptionHandler)

    return {error, result}
  }
}
<|endoftext|>


<commit_before>'use strict';

const path = require('path');
const fs = require('fs');
const url = require('url');

// Make sure any symlinks in the project folder are resolved:
// https://github.com/facebookincubator/create-react-app/issues/637
const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);

const envPublicUrl = process.env.PUBLIC_URL;

function ensureSlash(path, needsSlash) {
  const hasSlash = path.endsWith('/');
  if (hasSlash && !needsSlash) {
    return path.substr(path, path.length - 1);
  } else if (!hasSlash && needsSlash) {
    return `${path}/`;
  } else {
    return path;
  }
}

const getPublicUrl = appPackageJson =>
  envPublicUrl || require(appPackageJson).homepage;

function getServedPath(appPackageJson) {
  const publicUrl = getPublicUrl(appPackageJson);
  const servedUrl =
    envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/');
  return ensureSlash(servedUrl, true);
}

const resolveOwn = relativePath => path.resolve(__dirname, '..', relativePath);

// We support resolving modules according to `NODE_PATH`.
// This lets you use absolute paths in imports inside large monorepos:
// https://github.com/facebookincubator/create-react-app/issues/253.
// It works similar to `NODE_PATH` in Node itself:
// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
// We also resolve them to make sure all tools using them work consistently.
const nodePaths = (process.env.NODE_PATH || '')
  .split(path.delimiter)
  .filter(folder => folder && !path.isAbsolute(folder))
  .map(folder => path.resolve(appDirectory, folder))
  .join(path.delimiter);

module.exports = {
  dotenv: resolveApp('.env'),
  appPath: resolveApp('.'),
  appBuild: resolveApp('build'),
  appBuildPublic: resolveApp('build/public'),
  appAssetsManifest: resolveApp('build/assets.json'),
  appChunksManifest: resolveApp('build/chunks.json'),
  appBuildStaticExport: resolveApp('build/static_export.js'),
  appBuildStaticExportRoutes: resolveApp('build/public/static_routes.js'),
  appPublic: resolveApp('public'),
  appNodeModules: resolveApp('node_modules'),
  appSrc: resolveApp('src'),
  appHtml: resolveApp('public/index.html'), // client only
  appPackageJson: resolveApp('package.json'),
  appServerJs: resolveApp('src/server'),
  appServerIndexJs: resolveApp('src'),
  appClientIndexJs: resolveApp('src/client'),
  appStaticExportJs: resolveApp('src/static_export'),
  tsTestsSetup: resolveApp('src/setupTests.ts'),
  jsTestsSetup: resolveApp('src/setupTests.js'),
  appBabelRc: resolveApp('.babelrc'),
  appRazzleConfig: resolveApp('razzle.config.js'),
  nodePaths: nodePaths,
  ownPath: resolveOwn('.'),
  ownNodeModules: resolveOwn('node_modules'),
  publicUrl: getPublicUrl(resolveApp('package.json')),
  servedPath: getServedPath(resolveApp('package.json')),
  appJsConfig: resolveApp('jsconfig.json'),
  appTsConfig: resolveApp('tsconfig.json'),
};
<commit_msg>feat(razzle): make appDirectory configurable via ENV configuration<commit_after>'use strict';

const path = require('path');
const fs = require('fs');
const url = require('url');

// Make sure any symlinks in the project folder are resolved:
// https://github.com/facebookincubator/create-react-app/issues/637
const appDirectory = fs.realpathSync(process.env.RAZZLE_APP_PATH || process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);

const envPublicUrl = process.env.PUBLIC_URL;

function ensureSlash(path, needsSlash) {
  const hasSlash = path.endsWith('/');
  if (hasSlash && !needsSlash) {
    return path.substr(path, path.length - 1);
  } else if (!hasSlash && needsSlash) {
    return `${path}/`;
  } else {
    return path;
  }
}

const getPublicUrl = appPackageJson =>
  envPublicUrl || require(appPackageJson).homepage;

function getServedPath(appPackageJson) {
  const publicUrl = getPublicUrl(appPackageJson);
  const servedUrl =
    envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/');
  return ensureSlash(servedUrl, true);
}

const resolveOwn = relativePath => path.resolve(__dirname, '..', relativePath);

// We support resolving modules according to `NODE_PATH`.
// This lets you use absolute paths in imports inside large monorepos:
// https://github.com/facebookincubator/create-react-app/issues/253.
// It works similar to `NODE_PATH` in Node itself:
// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
// We also resolve them to make sure all tools using them work consistently.
const nodePaths = (process.env.NODE_PATH || '')
  .split(path.delimiter)
  .filter(folder => folder && !path.isAbsolute(folder))
  .map(folder => path.resolve(appDirectory, folder))
  .join(path.delimiter);

module.exports = {
  dotenv: resolveApp('.env'),
  appPath: resolveApp('.'),
  appBuild: resolveApp('build'),
  appBuildPublic: resolveApp('build/public'),
  appAssetsManifest: resolveApp('build/assets.json'),
  appChunksManifest: resolveApp('build/chunks.json'),
  appBuildStaticExport: resolveApp('build/static_export.js'),
  appBuildStaticExportRoutes: resolveApp('build/public/static_routes.js'),
  appPublic: resolveApp('public'),
  appNodeModules: resolveApp('node_modules'),
  appSrc: resolveApp('src'),
  appHtml: resolveApp('public/index.html'), // client only
  appPackageJson: resolveApp('package.json'),
  appServerJs: resolveApp('src/server'),
  appServerIndexJs: resolveApp('src'),
  appClientIndexJs: resolveApp('src/client'),
  appStaticExportJs: resolveApp('src/static_export'),
  tsTestsSetup: resolveApp('src/setupTests.ts'),
  jsTestsSetup: resolveApp('src/setupTests.js'),
  appBabelRc: resolveApp('.babelrc'),
  appRazzleConfig: resolveApp('razzle.config.js'),
  nodePaths: nodePaths,
  ownPath: resolveOwn('.'),
  ownNodeModules: resolveOwn('node_modules'),
  publicUrl: getPublicUrl(resolveApp('package.json')),
  servedPath: getServedPath(resolveApp('package.json')),
  appJsConfig: resolveApp('jsconfig.json'),
  appTsConfig: resolveApp('tsconfig.json'),
};
<|endoftext|>


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

import {readdirSync} from 'fs';
import {join, normalize} from 'path';
import {yellow, red} from 'chalk';
import figures from 'figures';
import findRoot from 'find-root';
import updateNotifier from 'update-notifier';
import program from '@shopify/commander';
import {hasDependency} from './utils';

/**
 * Find closest package.json to be at root of theme.
 *
 * @param {string} directory - A path.
 */
function getThemeRoot(directory) {
  try {
    return normalize(findRoot(directory));
  } catch (err) {
    return null;
  }
}

/**
 * Check package.json for slate-tools.
 *
 * @param {string} themeRoot - The path for the root of the theme.
 */
function checkForSlateTools(themeRoot) {
  const pkgPath = join(themeRoot, 'package.json');
  const pkg = require(pkgPath);

  return hasDependency('@shopify/slate-tools', pkg);
}

/**
 * Output information if/else slate theme directory.
 *
 * @param {boolean} isSlateTheme - Whether in slate theme or not.
 */
function outputSlateThemeCheck(isSlateTheme) {
  if (isSlateTheme) {
    return;
  }

  console.log('');
  console.log(yellow(`  ${figures.cross} You are not in a slate theme directory`));
  console.log('    For full list of commands generate a new theme or switch to an existing slate theme directory');
  console.log('');
}

const currentDirectory = __dirname;
const workingDirectory = process.cwd();
const pkg = require(join(currentDirectory, normalize('../package.json')));

updateNotifier({
  pkg,
  updateCheckInterval: 1000 * 60 * 60 * 24 * 7, // 1 week
}).notify();

// Global commands
require('./commands/theme').default(program);
require('./commands/version').default(program);

// Dynamically add in theme commands
const themeRoot = getThemeRoot(workingDirectory);
const isSlateTheme = (themeRoot && checkForSlateTools(themeRoot));

if (isSlateTheme) {
  const slateToolsCommands = join(themeRoot, normalize('/node_modules/@shopify/slate-tools/lib/commands'));

  readdirSync(slateToolsCommands)
    .filter((file) => ~file.search(/^[^\.].*\.js$/))
    .forEach((file) => require(join(slateToolsCommands, file)).default(program));
}

// output help if no commands or options passed
if (!process.argv.slice(2).length) {
  program.help();
}

// Custom help
program.on('--helpStart', () => {
  outputSlateThemeCheck(isSlateTheme);
});

program.on('--helpEnd', () => {
  console.log('  Docs:');
  console.log('');
  console.log('     https://shopify.github.io/slate/');
  console.log('');
});

// Unknown command
program.on('*', () => {
  console.log('');
  console.log(red(`  ${figures.cross} Unknown command: ${program.args.join(' ')}`));
  console.log('');
  program.help();
});

program.parse(process.argv);
<commit_msg>moved some stuff around<commit_after>#!/usr/bin/env node

import {readdirSync} from 'fs';
import {join, normalize} from 'path';
import {yellow, red} from 'chalk';
import figures from 'figures';
import findRoot from 'find-root';
import updateNotifier from 'update-notifier';
import program from '@shopify/commander';
import {hasDependency} from './utils';

/**
 * Find closest package.json to be at root of theme.
 *
 * @param {string} directory - A path.
 */
function getThemeRoot(directory) {
  try {
    return normalize(findRoot(directory));
  } catch (err) {
    return null;
  }
}

/**
 * Check package.json for slate-tools.
 *
 * @param {string} themeRoot - The path for the root of the theme.
 */
function checkForSlateTools(themeRoot) {
  const pkgPath = join(themeRoot, 'package.json');
  const pkg = require(pkgPath);

  return hasDependency('@shopify/slate-tools', pkg);
}

/**
 * Output information if/else slate theme directory.
 *
 * @param {boolean} isSlateTheme - Whether in slate theme or not.
 */
function outputSlateThemeCheck(isSlateTheme) {
  if (isSlateTheme) {
    return;
  }

  console.log('');
  console.log(yellow(`  ${figures.cross} You are not in a slate theme directory`));
  console.log('    For full list of commands generate a new theme or switch to an existing slate theme directory');
  console.log('');
}

const currentDirectory = __dirname;
const workingDirectory = process.cwd();
const pkg = require(join(currentDirectory, normalize('../package.json')));

updateNotifier({
  pkg,
  updateCheckInterval: 1000 * 60 * 60 * 24 * 7, // 1 week
}).notify();

// Global commands
require('./commands/theme').default(program);
require('./commands/version').default(program);

// Dynamically add in theme commands
const themeRoot = getThemeRoot(workingDirectory);
const isSlateTheme = (themeRoot && checkForSlateTools(themeRoot));

if (isSlateTheme) {
  const slateToolsCommands = join(themeRoot, normalize('/node_modules/@shopify/slate-tools/lib/commands'));

  readdirSync(slateToolsCommands)
    .filter((file) => ~file.search(/^[^\.].*\.js$/))
    .forEach((file) => require(join(slateToolsCommands, file)).default(program));
}

// Custom help
program.on('--helpStart', () => {
  outputSlateThemeCheck(isSlateTheme);
});

program.on('--helpEnd', () => {
  console.log('  Docs:');
  console.log('');
  console.log('     https://shopify.github.io/slate/');
  console.log('');
});

// Unknown command
program.on('*', () => {
  console.log('');
  console.log(red(`  ${figures.cross} Unknown command: ${program.args.join(' ')}`));
  console.log('');
  program.help();
});

program.parse(process.argv);

// output help if no commands or options passed
if (!process.argv.slice(2).length) {
  program.help();
}
<|endoftext|>


<commit_before>import { BodyComponent } from 'mjml-core'

export default class MjButton extends BodyComponent {
  static endingTag = true

  static allowedAttributes = {
    align: 'enum(left,center,right)',
    'background-color': 'color',
    'border-bottom': 'string',
    'border-left': 'string',
    'border-radius': 'string',
    'border-right': 'string',
    'border-top': 'string',
    border: 'string',
    color: 'color',
    'container-background-color': 'color',
    'font-family': 'string',
    'font-size': 'unit(px)',
    'font-style': 'string',
    'font-weight': 'string',
    height: 'unit(px,%)',
    href: 'string',
    name: 'string',
    'inner-padding': 'unit(px,%){1,4}',
    'line-height': 'unit(px,%,)',
    'padding-bottom': 'unit(px,%)',
    'padding-left': 'unit(px,%)',
    'padding-right': 'unit(px,%)',
    'padding-top': 'unit(px,%)',
    padding: 'unit(px,%){1,4}',
    rel: 'string',
    target: 'string',
    'text-decoration': 'string',
    'text-transform': 'string',
    'vertical-align': 'enum(top,bottom,middle)',
    'text-align': 'enum(left,right,center)',
    width: 'unit(px,%)',
  }

  static defaultAttributes = {
    align: 'center',
    'background-color': '#414141',
    border: 'none',
    'border-radius': '3px',
    color: '#ffffff',
    'font-family': 'Ubuntu, Helvetica, Arial, sans-serif',
    'font-size': '13px',
    'font-weight': 'normal',
    'inner-padding': '10px 25px',
    'line-height': '120%',
    padding: '10px 25px',
    target: '_blank',
    'text-decoration': 'none',
    'text-transform': 'none',
    'vertical-align': 'middle',
  }

  getStyles() {
    return {
      table: {
        'border-collapse': 'separate',
        width: this.getAttribute('width'),
        'line-height': '100%',
      },
      td: {
        border: this.getAttribute('border'),
        'border-bottom': this.getAttribute('border-bottom'),
        'border-left': this.getAttribute('border-left'),
        'border-radius': this.getAttribute('border-radius'),
        'border-right': this.getAttribute('border-right'),
        'border-top': this.getAttribute('border-top'),
        cursor: 'auto',
        'font-style': this.getAttribute('font-style'),
        height: this.getAttribute('height'),
        'mso-padding-alt': this.getAttribute('inner-padding'),
        'text-align': this.getAttribute('text-align'),
        background: this.getAttribute('background-color'),
      },
      content: {
        display: 'inline-block',
        background: this.getAttribute('background-color'),
        color: this.getAttribute('color'),
        'font-family': this.getAttribute('font-family'),
        'font-size': this.getAttribute('font-size'),
        'font-style': this.getAttribute('font-style'),
        'font-weight': this.getAttribute('font-weight'),
        'line-height': this.getAttribute('line-height'),
        Margin: '0',
        'text-decoration': this.getAttribute('text-decoration'),
        'text-transform': this.getAttribute('text-transform'),
        padding: this.getAttribute('inner-padding'),
        'mso-padding-alt': '0px',
        'border-radius': this.getAttribute('border-radius'),

      },
    }
  }

  render() {
    const tag = this.getAttribute('href') ? 'a' : 'p'

    return `

            <${tag}
              ${this.htmlAttributes({
                href: this.getAttribute('href'),
                rel: this.getAttribute('rel'),
                name: this.getAttribute('name'),
                style: 'content',
                target: tag === 'a' ? this.getAttribute('target') : undefined,
              })}
            >
              ${this.getContent()}
            </${tag}>

    `
  }
}
<commit_msg>improve button clickability<commit_after>import { BodyComponent } from 'mjml-core'

import widthParser from 'mjml-core/lib/helpers/widthParser'

export default class MjButton extends BodyComponent {
  static endingTag = true

  static allowedAttributes = {
    align: 'enum(left,center,right)',
    'background-color': 'color',
    'border-bottom': 'string',
    'border-left': 'string',
    'border-radius': 'string',
    'border-right': 'string',
    'border-top': 'string',
    border: 'string',
    color: 'color',
    'container-background-color': 'color',
    'font-family': 'string',
    'font-size': 'unit(px)',
    'font-style': 'string',
    'font-weight': 'string',
    height: 'unit(px,%)',
    href: 'string',
    name: 'string',
    'inner-padding': 'unit(px,%){1,4}',
    'line-height': 'unit(px,%,)',
    'padding-bottom': 'unit(px,%)',
    'padding-left': 'unit(px,%)',
    'padding-right': 'unit(px,%)',
    'padding-top': 'unit(px,%)',
    padding: 'unit(px,%){1,4}',
    rel: 'string',
    target: 'string',
    'text-decoration': 'string',
    'text-transform': 'string',
    'vertical-align': 'enum(top,bottom,middle)',
    'text-align': 'enum(left,right,center)',
    width: 'unit(px,%)',
  }

  static defaultAttributes = {
    align: 'center',
    'background-color': '#414141',
    border: 'none',
    'border-radius': '3px',
    color: '#ffffff',
    'font-family': 'Ubuntu, Helvetica, Arial, sans-serif',
    'font-size': '13px',
    'font-weight': 'normal',
    'inner-padding': '10px 25px',
    'line-height': '120%',
    padding: '10px 25px',
    target: '_blank',
    'text-decoration': 'none',
    'text-transform': 'none',
    'vertical-align': 'middle',
  }

  getStyles() {
    return {
      table: {
        'border-collapse': 'separate',
        width: this.getAttribute('width'),
        'line-height': '100%',
      },
      td: {
        border: this.getAttribute('border'),
        'border-bottom': this.getAttribute('border-bottom'),
        'border-left': this.getAttribute('border-left'),
        'border-radius': this.getAttribute('border-radius'),
        'border-right': this.getAttribute('border-right'),
        'border-top': this.getAttribute('border-top'),
        cursor: 'auto',
        'font-style': this.getAttribute('font-style'),
        height: this.getAttribute('height'),
        'mso-padding-alt': this.getAttribute('inner-padding'),
        'text-align': this.getAttribute('text-align'),
        background: this.getAttribute('background-color'),
      },
      content: {
        display: 'inline-block',
        width: this.calculateAWidth(this.getAttribute('width')),
        background: this.getAttribute('background-color'),
        color: this.getAttribute('color'),
        'font-family': this.getAttribute('font-family'),
        'font-size': this.getAttribute('font-size'),
        'font-style': this.getAttribute('font-style'),
        'font-weight': this.getAttribute('font-weight'),
        'line-height': this.getAttribute('line-height'),
        Margin: '0',
        'text-decoration': this.getAttribute('text-decoration'),
        'text-transform': this.getAttribute('text-transform'),
        padding: this.getAttribute('inner-padding'),
        'mso-padding-alt': '0px',
        'border-radius': this.getAttribute('border-radius'),
      },
    }
  }

  calculateAWidth(width) {
    if (!width) return null

    const { parsedWidth, unit } = widthParser(width)

    // impossible to handle percents because it depends on padding and text width
    if (unit !== 'px') return null

    const { borders } = this.getBoxWidths()

    const innerPaddings =
      this.getShorthandAttrValue('inner-padding', 'left') +
      this.getShorthandAttrValue('inner-padding', 'right')

    return `${parsedWidth - innerPaddings - borders}px`
  }

  render() {
    const tag = this.getAttribute('href') ? 'a' : 'p'

    return `

            <${tag}
              ${this.htmlAttributes({
                href: this.getAttribute('href'),
                rel: this.getAttribute('rel'),
                name: this.getAttribute('name'),
                style: 'content',
                target: tag === 'a' ? this.getAttribute('target') : undefined,
              })}
            >
              ${this.getContent()}
            </${tag}>

    `
  }
}
<|endoftext|>


<commit_before>'use strict'

/* @flow */

import { inspect } from 'util'
import {CompositeDisposable, Emitter, Disposable} from 'sb-event-kit'
import vorpal from 'vorpal'

const CLI_DELIMITER = 'motion ❯❯❯'
const WELCOME_MESSAGE = '♥ ♥ ♥ Welcome to Motion ♥ ♥ ♥'

export class CLI {
  active: boolean;
  emitter: Emitter;
  instance: vorpal;
  subscriptions: CompositeDisposable;

  constructor() {
    this.active = false
    this.emitter = new Emitter()
    this.instance = vorpal()
    this.subscriptions = new CompositeDisposable()

    this.subscriptions.add(this.emitter)
  }
  activate() {
    this.instance.delimiter(CLI_DELIMITER)
    this.instance.show()
    this.active = true
    this.instance.log(WELCOME_MESSAGE)
  }
  addCommand(name: string, helpText: string, callback: Function) {
    this.instance.command(name, helpText).action((args, keepRunning) => {
      const result = callback.call(this, args)
      if (result) {
        return result
      } else {
        keepRunning()
      }
    })
  }
  log() {
    let contents = []
    for (let i = 0; i < arguments.length; ++i) {
      const value = arguments[i]
      if (value === null) {
        contents.push('null')
      } else if (typeof value === 'string') {
        contents.push(value)
      } else [
        contents.push(inspect(value))
      ]
    }
    this.instance.log(contents.join(' '))
  }
  dispose() {
    if (this.active) {
      this.instance.hide()
      this.active = false
    }
    this.subscriptions.dispose()
  }
}
<commit_msg>:new: Add colors to CLI<commit_after>'use strict'

/* @flow */

import { inspect } from 'util'
import { CompositeDisposable, Emitter, Disposable } from 'sb-event-kit'
import vorpal from 'vorpal'
import chalk from 'chalk'

const CLI_DELIMITER = `${chalk.blue('motion')} ${chalk.red('❯')}${chalk.yellow('❯')}${chalk.green('❯')}`
const WELCOME_MESSAGE = `${chalk.red('♥ ♥ ♥')} ${chalk.yellow('Welcome to Motion')} ${chalk.red('♥ ♥ ♥')}`

export class CLI {
  active: boolean;
  emitter: Emitter;
  instance: vorpal;
  subscriptions: CompositeDisposable;

  constructor() {
    this.active = false
    this.emitter = new Emitter()
    this.instance = vorpal()
    this.subscriptions = new CompositeDisposable()

    this.subscriptions.add(this.emitter)
  }
  activate() {
    this.instance.delimiter(CLI_DELIMITER)
    this.instance.show()
    this.active = true
    this.instance.log(WELCOME_MESSAGE)
  }
  addCommand(name: string, helpText: string, callback: Function) {
    this.instance.command(name, helpText).action((args, keepRunning) => {
      const result = callback.call(this, args)
      if (result) {
        return result
      } else {
        keepRunning()
      }
    })
  }
  log() {
    let contents = []
    for (let i = 0; i < arguments.length; ++i) {
      const value = arguments[i]
      if (value === null) {
        contents.push('null')
      } else if (typeof value === 'string') {
        contents.push(value)
      } else [
        contents.push(inspect(value))
      ]
    }
    this.instance.log(contents.join(' '))
  }
  dispose() {
    if (this.active) {
      this.instance.hide()
      this.active = false
    }
    this.subscriptions.dispose()
  }
}
<|endoftext|>


<commit_before>//Leaflet-SVGIcon
//SVG icon for any marker class
//Ilya Atkin
//ilya.atkin@unh.edu

L.DivIcon.SVGIcon = L.DivIcon.extend({
    options: {
        "circleText": "",
        "className": "svg-icon",
        "circleAnchor": null, //defaults to [iconSize.x/2, iconSize.x/2]
        "circleColor": null, //defaults to color
        "circleOpacity": null, // defaults to opacity
        "circleFillColor": "rgb(255,255,255)",
        "circleFillOpacity": null, //default to opacity
        "circleRatio": 0.5,
        "circleWeight": null, //defaults to weight
        "color": "rgb(0,102,255)",
        "fillColor": null, // defaults to color
        "fillOpacity": 0.4,
        "fontColor": "rgb(0, 0, 0)",
        "fontOpacity": "1",
        "fontSize": null, // defaults to iconSize.x/4
        "iconAnchor": null, //defaults to [iconSize.x/2, iconSize.y] (point tip)
        "iconSize": L.point(32,48),
        "opacity": 1,
        "popupAnchor": null,
        "weight": 2
    },
    initialize: function(options) {
        options = L.Util.setOptions(this, options)

        if (!options.circleAnchor) {
            options.circleAnchor = L.point(Number(options.iconSize.x)/2, Number(options.iconSize.x)/2)
        }
        if (!options.circleColor) {
            options.circleColor = options.color
        }
        if (!options.circleFillOpacity) {
            options.circleFillOpacity = options.opacity
        }
        if (!options.circleOpacity) {
            options.circleOpacity = options.opacity
        }
        if (!options.circleWeight) {
            options.circleWeight = options.weight
        }
        if (!options.fillColor) {
            options.fillColor = options.color
        }
        if (!options.fontSize) {
            options.fontSize = Number(options.iconSize.x/4)
        }
        if (!options.iconAnchor) {
            options.iconAnchor = L.point(Number(options.iconSize.x)/2, Number(options.iconSize.y))
        }
        if (!options.popupAnchor) {
            options.popupAnchor = L.point(0, (-0.75)*(options.iconSize.y))
        }

        var path = this._createPath()
        var circle = this._createCircle()

        options.html = this._createSVG()
    },
    _createCircle: function() {
        var cx = Number(this.options.circleAnchor.x)
        var cy = Number(this.options.circleAnchor.y)
        var radius = this.options.iconSize.x/2 * Number(this.options.circleRatio)
        var fill = this.options.circleFillColor
        var fillOpacity = this.options.circleFillOpacity
        var stroke = this.options.circleColor
        var strokeOpacity = this.options.circleOpacity
        var strokeWidth = this.options.circleWeight
        var className = this.options.className + "-circle"

        var circle = '<circle class="' + className + '" cx="' + cx + '" cy="' + cy + '" r="' + radius +
            '" fill="' + fill + '" fill-opacity="'+ fillOpacity +
            '" stroke="' + stroke + '" stroke-opacity=' + strokeOpacity + '" stroke-width="' + strokeWidth + '"/>'

        return circle
    },
    _createPathDescription: function() {
        var height = Number(this.options.iconSize.y)
        var width = Number(this.options.iconSize.x)
        var weight = Number(this.options.weight)
        var margin = weight / 2

        var startPoint = "M " + margin + " " + (width/2) + " "
        var leftLine = "L " + (width/2) + " " + (height - weight) + " "
        var rightLine = "L " + (width - margin) + " " + (width/2) + " "
        var arc = "A " + (width/4) + " " + (width/4) + " 0 0 0 " + margin + " " + (width/2) + " Z"

        var d = startPoint + leftLine + rightLine + arc

        return d
    },
    _createPath: function() {
        var pathDescription = this._createPathDescription()
        var strokeWidth = this.options.weight
        var stroke = this.options.color
        var strokeOpacity = this.options.Opacity
        var fill = this.options.fillColor
        var fillOpacity = this.options.fillOpacity
        var className = this.options.className + "-path"

        var path = '<path class="' + className + '" d="' + pathDescription +
            '" stroke-width="' + strokeWidth + '" stroke="' + stroke + '" stroke-opacity="' + strokeOpacity +
            '" fill="' + fill + '" fill-opacity="' + fillOpacity + '"/>'

        return path
    },
    _createSVG: function() {
        var path = this._createPath()
        var circle = this._createCircle()
        var text = this._createText()
        var className = this.options.className + "-svg"

        var style = "width:" + this.options.iconSize.x + "; height:" + this.options.iconSize.y + ";"

        var svg = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="' + className + '" style="' + style + '">' + path + circle + text + '</svg>'

        return svg
    },
    _createText: function() {
        var fontSize = this.options.fontSize + "px"
        var lineHeight = Number(this.options.fontSize)

        var x = Number(this.options.iconSize.x) / 2
        var y = x + (lineHeight * 0.35) //35% was found experimentally
        var circleText = this.options.circleText
        var textColor = this.options.fontColor.replace("rgb(", "rgba(").replace(")", "," + this.options.fontOpacity + ")")

        var text = '<text text-anchor="middle" x="' + x + '" y="' + y + '" style="font-size: ' + fontSize + '" fill="' + textColor + '">' + circleText + '</text>'

        return text
    }
})

L.divIcon.svgIcon = function(options) {
    return new L.DivIcon.SVGIcon(options)
}

L.Marker.SVGMarker = L.Marker.extend({
    options: {
        "iconFactory": L.divIcon.svgIcon,
        "iconOptions": {}
    },
    initialize: function(latlng, options) {
        options = L.Util.setOptions(this, options)
        options.icon = options.iconFactory(options.iconOptions)
        this._latlng = latlng
    },
    onAdd: function(map) {
        L.Marker.prototype.onAdd.call(this, map)
    },
    setStyle: function(style) {
        if (this._icon) {
            var svg = this._icon.children[0]
            var iconBody = this._icon.children[0].children[0]
            var iconCircle = this._icon.children[0].children[1]

            if (style.color && !style.iconOptions) {
                var stroke = style.color.replace("rgb","rgba").replace(")", ","+this.options.icon.options.opacity+")")
                var fill = style.color.replace("rgb","rgba").replace(")", ","+this.options.icon.options.fillOpacity+")")
                iconBody.setAttribute("stroke", stroke)
                iconBody.setAttribute("fill", fill)
                iconCircle.setAttribute("stroke", stroke)

                this.options.icon.fillColor = fill
                this.options.icon.color = stroke
                this.options.icon.circleColor = stroke
            }
            if (style.opacity) {
                this.setOpacity(style.opacity)
            }
            if (style.iconOptions) {
                if (style.color) { style.iconOptions.color = style.color }
                iconOptions = L.Util.setOptions(this.options.icon, style.iconOptions)
                this.setIcon(L.divIcon.svgIcon(iconOptions))
            }
        }
    }
})

L.marker.svgMarker = function(latlng, options) {
    return new L.Marker.SVGMarker(latlng, options)
}
<commit_msg>Added support for Points passed as arrays<commit_after>//Leaflet-SVGIcon
//SVG icon for any marker class
//Ilya Atkin
//ilya.atkin@unh.edu

L.DivIcon.SVGIcon = L.DivIcon.extend({
    options: {
        "circleText": "",
        "className": "svg-icon",
        "circleAnchor": null, //defaults to [iconSize.x/2, iconSize.x/2]
        "circleColor": null, //defaults to color
        "circleOpacity": null, // defaults to opacity
        "circleFillColor": "rgb(255,255,255)",
        "circleFillOpacity": null, //default to opacity
        "circleRatio": 0.5,
        "circleWeight": null, //defaults to weight
        "color": "rgb(0,102,255)",
        "fillColor": null, // defaults to color
        "fillOpacity": 0.4,
        "fontColor": "rgb(0, 0, 0)",
        "fontOpacity": "1",
        "fontSize": null, // defaults to iconSize.x/4
        "iconAnchor": null, //defaults to [iconSize.x/2, iconSize.y] (point tip)
        "iconSize": L.point(32,48),
        "opacity": 1,
        "popupAnchor": null,
        "weight": 2
    },
    initialize: function(options) {
        options = L.Util.setOptions(this, options)

        //iconSize needs to be converted to a Point object if it is not passed as one
        options.iconSize = L.point(options.iconSize)

        //in addition to setting option dependant defaults, Point-based options are converted to Point objects
        if (!options.circleAnchor) {
            options.circleAnchor = L.point(Number(options.iconSize.x)/2, Number(options.iconSize.x)/2)
        }
        else {
            options.circleAnchor = L.point(options.circleAnchor)
        }
        if (!options.circleColor) {
            options.circleColor = options.color
        }
        if (!options.circleFillOpacity) {
            options.circleFillOpacity = options.opacity
        }
        if (!options.circleOpacity) {
            options.circleOpacity = options.opacity
        }
        if (!options.circleWeight) {
            options.circleWeight = options.weight
        }
        if (!options.fillColor) {
            options.fillColor = options.color
        }
        if (!options.fontSize) {
            options.fontSize = Number(options.iconSize.x/4)
        }
        if (!options.iconAnchor) {
            options.iconAnchor = L.point(Number(options.iconSize.x)/2, Number(options.iconSize.y))
        }
        else {
            options.iconAnchor = L.point(options.iconAnchor)
        }
        if (!options.popupAnchor) {
            options.popupAnchor = L.point(0, (-0.75)*(options.iconSize.y))
        }
        else {
            options.popupAnchor = L.point(options.popupAnchor)
        }

        var path = this._createPath()
        var circle = this._createCircle()

        options.html = this._createSVG()
    },
    _createCircle: function() {
        var cx = Number(this.options.circleAnchor.x)
        var cy = Number(this.options.circleAnchor.y)
        var radius = this.options.iconSize.x/2 * Number(this.options.circleRatio)
        var fill = this.options.circleFillColor
        var fillOpacity = this.options.circleFillOpacity
        var stroke = this.options.circleColor
        var strokeOpacity = this.options.circleOpacity
        var strokeWidth = this.options.circleWeight
        var className = this.options.className + "-circle"

        var circle = '<circle class="' + className + '" cx="' + cx + '" cy="' + cy + '" r="' + radius +
            '" fill="' + fill + '" fill-opacity="'+ fillOpacity +
            '" stroke="' + stroke + '" stroke-opacity=' + strokeOpacity + '" stroke-width="' + strokeWidth + '"/>'

        return circle
    },
    _createPathDescription: function() {
        var height = Number(this.options.iconSize.y)
        var width = Number(this.options.iconSize.x)
        var weight = Number(this.options.weight)
        var margin = weight / 2

        var startPoint = "M " + margin + " " + (width/2) + " "
        var leftLine = "L " + (width/2) + " " + (height - weight) + " "
        var rightLine = "L " + (width - margin) + " " + (width/2) + " "
        var arc = "A " + (width/4) + " " + (width/4) + " 0 0 0 " + margin + " " + (width/2) + " Z"

        var d = startPoint + leftLine + rightLine + arc

        return d
    },
    _createPath: function() {
        var pathDescription = this._createPathDescription()
        var strokeWidth = this.options.weight
        var stroke = this.options.color
        var strokeOpacity = this.options.Opacity
        var fill = this.options.fillColor
        var fillOpacity = this.options.fillOpacity
        var className = this.options.className + "-path"

        var path = '<path class="' + className + '" d="' + pathDescription +
            '" stroke-width="' + strokeWidth + '" stroke="' + stroke + '" stroke-opacity="' + strokeOpacity +
            '" fill="' + fill + '" fill-opacity="' + fillOpacity + '"/>'

        return path
    },
    _createSVG: function() {
        var path = this._createPath()
        var circle = this._createCircle()
        var text = this._createText()
        var className = this.options.className + "-svg"

        var style = "width:" + this.options.iconSize.x + "; height:" + this.options.iconSize.y + ";"

        var svg = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="' + className + '" style="' + style + '">' + path + circle + text + '</svg>'

        return svg
    },
    _createText: function() {
        var fontSize = this.options.fontSize + "px"
        var lineHeight = Number(this.options.fontSize)

        var x = Number(this.options.iconSize.x) / 2
        var y = x + (lineHeight * 0.35) //35% was found experimentally
        var circleText = this.options.circleText
        var textColor = this.options.fontColor.replace("rgb(", "rgba(").replace(")", "," + this.options.fontOpacity + ")")

        var text = '<text text-anchor="middle" x="' + x + '" y="' + y + '" style="font-size: ' + fontSize + '" fill="' + textColor + '">' + circleText + '</text>'

        return text
    }
})

L.divIcon.svgIcon = function(options) {
    return new L.DivIcon.SVGIcon(options)
}

L.Marker.SVGMarker = L.Marker.extend({
    options: {
        "iconFactory": L.divIcon.svgIcon,
        "iconOptions": {}
    },
    initialize: function(latlng, options) {
        options = L.Util.setOptions(this, options)
        options.icon = options.iconFactory(options.iconOptions)
        this._latlng = latlng
    },
    onAdd: function(map) {
        L.Marker.prototype.onAdd.call(this, map)
    },
    setStyle: function(style) {
        if (this._icon) {
            var svg = this._icon.children[0]
            var iconBody = this._icon.children[0].children[0]
            var iconCircle = this._icon.children[0].children[1]

            if (style.color && !style.iconOptions) {
                var stroke = style.color.replace("rgb","rgba").replace(")", ","+this.options.icon.options.opacity+")")
                var fill = style.color.replace("rgb","rgba").replace(")", ","+this.options.icon.options.fillOpacity+")")
                iconBody.setAttribute("stroke", stroke)
                iconBody.setAttribute("fill", fill)
                iconCircle.setAttribute("stroke", stroke)

                this.options.icon.fillColor = fill
                this.options.icon.color = stroke
                this.options.icon.circleColor = stroke
            }
            if (style.opacity) {
                this.setOpacity(style.opacity)
            }
            if (style.iconOptions) {
                if (style.color) { style.iconOptions.color = style.color }
                iconOptions = L.Util.setOptions(this.options.icon, style.iconOptions)
                this.setIcon(L.divIcon.svgIcon(iconOptions))
            }
        }
    }
})

L.marker.svgMarker = function(latlng, options) {
    return new L.Marker.SVGMarker(latlng, options)
}
<|endoftext|>


<commit_before>Package.describe({
  summary: "Reactive dictionary",
  version: '1.1.2'
});

Package.onUse(function (api) {
  api.use(['underscore', 'tracker', 'ejson']);
  // If we are loading mongo-livedata, let you store ObjectIDs in it.
  api.use('mongo', {weak: true});
  api.export('ReactiveDict');
  api.addFiles('reactive-dict.js');
  api.addFiles('migration.js');
});

Package.onTest(function (api) {
  api.use('tinytest');
  api.use('reactive-dict');
  api.use('tracker');
  api.use('underscore');
  api.addFiles('reactive-dict-tests.js');
});
<commit_msg>Compile reactive-dict with ecmascript for IE8<commit_after>Package.describe({
  summary: "Reactive dictionary",
  version: '1.1.2'
});

Package.onUse(function (api) {
  api.use(['underscore', 'tracker', 'ejson', 'ecmascript']);
  // If we are loading mongo-livedata, let you store ObjectIDs in it.
  api.use('mongo', {weak: true});
  api.export('ReactiveDict');
  api.addFiles('reactive-dict.js');
  api.addFiles('migration.js');
});

Package.onTest(function (api) {
  api.use('tinytest');
  api.use('reactive-dict');
  api.use('tracker');
  api.use('underscore');
  api.addFiles('reactive-dict-tests.js');
});
<|endoftext|>


<commit_before>const {merge, pick} = require("lodash");

const SLOTS = ["head", "css", "before", "html", "after", "js"];

module.exports = render;
module.exports.SLOTS = SLOTS;

function render(input) {
  return SLOTS
    .reduce((output, slot) => {
      execute(input, output, {name: slot});
      return output;
    }, {});
}

function execute(input, output, {name}) {
  const fn = input[name];

  if (typeof fn !== "function") {
    return output;
  }

  const result = fn();

  if (typeof result === "string" || result === null) {
    output[name] = result;
    return output;
  }

  if (typeof result === "object" && !Array.isArray(result)) {
    merge(output, pick(result, SLOTS));
    return output;
  }

  throw new Error(`render fn "${name}" returned a result of type "${typeof result}". Expected string or object.`);
}
<commit_msg>refactor: distinguish between in and out packages<commit_after>const {merge, pick} = require("lodash");

const IN_SLOTS = ["html", "css", "js", "md", "json"];
const OUT_SLOTS = [...IN_SLOTS, "head", "before", "after", "script"];

module.exports = render;

function render(input) {
  return IN_SLOTS
    .reduce((output, slot) => {
      execute(input, output, {name: slot});
      return output;
    }, {});
}

function execute(input, output, {name}) {
  const fn = input[name];

  if (typeof fn !== "function") {
    return output;
  }

  const result = fn();

  if (typeof result === "string" || result === null) {
    output[name] = result;
    return output;
  }

  if (typeof result === "object" && !Array.isArray(result)) {
    merge(output, pick(result, OUT_SLOTS));
    return output;
  }

  throw new Error(`render fn "${name}" returned a result of type "${typeof result}". Expected string or object.`);
}
<|endoftext|>


<commit_before>import request from 'superagent';
import assert from 'assert';
import { util as storeUtil } from '../store.js';

function getUrl(path) {
  assert(path[0] === '/', 'HttpClient: path passed should start with a /');
  assert(path.substring(0, 5) !== '/api/', 'HttpClient: path passed should not be prefixed with /api');
  path = '/api' + path;
  return process.env.WEBSITE_HOSTNAME ?
    `http://${process.env.WEBSITE_HOSTNAME}${path}` :
    `http://localhost:49730${path}`;
  // `http://127.0.0.1:${global.server.get('port')}${path}`;
}

function bearer(req) {
  var token = localStorage.getItem('token');
  if (token) {
    req.set('Authorization', 'Bearer ' + token);
  }
}

const HttpClient = {
  get: (path, qs) => new Promise((resolve, reject) => {
    request
      .get(getUrl(path))
      .query(qs)
      .use(bearer)
      .accept('application/json')
      .end((err, res) => {
        if (err) {
          if (err.status === 404) {
            resolve(null);
          } else {
            reject(err);
          }
        } else {
          resolve(res.body);
        }
      });
  }),
  post: (url, data) => new Promise((resolve, reject) => {
    //console.log(getUrl(url), data);
    request
      .post(getUrl(url))
      .send(data)
      .use(bearer)
      .set('Accept', 'application/json')
      .set('Content-Type', 'application/json')
      .end(function(err, res) {
        if (err || !res.ok) {
          console.log(url, err || '', res);
          reject();
        } else {
          resolve(res.body);
        }
      });
  })
};

export default HttpClient;<commit_msg>Fixed bug of data not rendering because port in front-end was not the same as port in back-end<commit_after>import request from 'superagent';
import assert from 'assert';
import { util as storeUtil } from '../store.js';

function getUrl(path) {
  assert(path[0] === '/', 'HttpClient: path passed should start with a /');
  assert(path.substring(0, 5) !== '/api/', 'HttpClient: path passed should not be prefixed with /api');
  path = '/api' + path;
  return process.env.WEBSITE_HOSTNAME ?
    `http://${process.env.WEBSITE_HOSTNAME}${path}` :
    `http://localhost:49731${path}`;
  // `http://127.0.0.1:${global.server.get('port')}${path}`;
}

function bearer(req) {
  var token = localStorage.getItem('token');
  if (token) {
    req.set('Authorization', 'Bearer ' + token);
  }
}

const HttpClient = {
  get: (path, qs) => new Promise((resolve, reject) => {
    request
      .get(getUrl(path))
      .query(qs)
      .use(bearer)
      .accept('application/json')
      .end((err, res) => {
        if (err) {
          if (err.status === 404) {
            resolve(null);
          } else {
            reject(err);
          }
        } else {
          resolve(res.body);
        }
      });
  }),
  post: (url, data) => new Promise((resolve, reject) => {
    //console.log(getUrl(url), data);
    request
      .post(getUrl(url))
      .send(data)
      .use(bearer)
      .set('Accept', 'application/json')
      .set('Content-Type', 'application/json')
      .end(function(err, res) {
        if (err || !res.ok) {
          console.log(url, err || '', res);
          reject();
        } else {
          resolve(res.body);
        }
      });
  })
};

export default HttpClient;<|endoftext|>


<commit_before>/////////////////////////////////
//generic utils
export function first(input){
  return input[0]
}

export function flipValue__(newValue, oldValue){
  let val = newValue
  let outValue = (oldValue === newValue ? undefined: newValue)

  return outValue
}

//file utils ??

export function getExtension(fname){
  return fname.substr((~-fname.lastIndexOf(".") >>> 0) + 2).toLowerCase()
}

/////

/*returns an object's (deep) property, given a path as string
taken from : http://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key
*/
export function getPropertyByPath(obj, path) {
    /*if(path && path.indexOf('.') === -1) {
      path = "."+path
    }*/

    let parts = path.split('.'),
      last = parts.pop(),
      l = parts.length,
      i = 1,
      current = parts[0]

    while (l > 0 && (obj = obj[current]) && i < l) {
      current = parts[i]
      i++
    }

    if(obj) {
      return obj[last]
    }
}

export function setPropertyByPath(obj, path, value) {
    let parts = path.split('.'),
      last = parts.pop(),
      l = parts.length,
      i = 1,
      current = parts[0]

    while (l > 0 && (obj = obj[current]) && i < l) {
      current = parts[i]
      i++
    }

    if(obj) {
      obj[last] = value
    }
}

/////////////////////////////////
//app utils
function isToolSelected(){
  return self.state.activeTool
}

//annoying
export function isNoToolSelected(activeTool){
  return !activeTool
}

/////////////////////////////////
//entity utils
export function hasEntity( input ){
  return (input.userData && input.userData.entity)
}

export function getEntity( input ){
  return input.userData.entity
}

export function extractMeshTransforms(mesh){
  let attrs = {
    pos:mesh.position,
    rot:mesh.rotation,
    sca:mesh.scale
  }
  return attrs
}

function attributesToArrays(attrs){
  let output= {}
  for(let key in attrs){
    output[key] = attrs[key].toArray()
  }
  //special case for rotation
  if("rot" in attrs)
  {
    output["rot"] = output["rot"].slice(0,3)
  }
  return output
}

function setEntityT(attrsAndEntity){
  let [transforms, entity] = attrsAndEntity
  setEntityData$({entity:entity,
    pos:transforms.pos,
    rot:transforms.rot,
    sca:transforms.sca
  })

  return attrsAndEntity
}
/////////////////////////////////
//ui utils
export function toggleCursor(toggle, cursorName, element=document.body){
  if(toggle)
  {
    element.style.cursor = cursorName
  }else{
    element.style.cursor = 'default'
  }
  return toggle
}<commit_msg>- removed useless utilities<commit_after>/////////////////////////////////
//generic utils
export function first(input){
  return input[0]
}

export function flipValue__(newValue, oldValue){
  let val = newValue
  let outValue = (oldValue === newValue ? undefined: newValue)

  return outValue
}

//file utils ??

export function getExtension(fname){
  return fname.substr((~-fname.lastIndexOf(".") >>> 0) + 2).toLowerCase()
}

/////

/*returns an object's (deep) property, given a path as string
taken from : http://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key
*/
export function getPropertyByPath(obj, path) {
    /*if(path && path.indexOf('.') === -1) {
      path = "."+path
    }*/

    let parts = path.split('.'),
      last = parts.pop(),
      l = parts.length,
      i = 1,
      current = parts[0]

    while (l > 0 && (obj = obj[current]) && i < l) {
      current = parts[i]
      i++
    }

    if(obj) {
      return obj[last]
    }
}

export function setPropertyByPath(obj, path, value) {
    let parts = path.split('.'),
      last = parts.pop(),
      l = parts.length,
      i = 1,
      current = parts[0]

    while (l > 0 && (obj = obj[current]) && i < l) {
      current = parts[i]
      i++
    }

    if(obj) {
      obj[last] = value
    }
}

/////////////////////////////////
//app utils
function isToolSelected(){
  return self.state.activeTool
}

//annoying
export function isNoToolSelected(activeTool){
  return !activeTool
}

/////////////////////////////////
//entity utils
export function hasEntity( input ){
  return (input.userData && input.userData.entity)
}

export function getEntity( input ){
  return input.userData.entity
}

/////////////////////////////////
//ui utils
export function toggleCursor(toggle, cursorName, element=document.body){
  if(toggle)
  {
    element.style.cursor = cursorName
  }else{
    element.style.cursor = 'default'
  }
  return toggle
}<|endoftext|>


<commit_before>import { countDecimalPlaces } from './utils'

describe('countDecimalPlaces', () => {
  [
    { value: '1.123', expected: 3 },
    { value: '1.12', expected: 2 },
    { value: '1.', expected: 0 },
    { value: '1', expected: 0 },
    { value: '.123', expected: 3 },
    { value: .123, expected: 3 },
    { value: '1e-3', expected: 3 },
    { value: '1e-2', expected: 2 },
    { value: '1.2e-2', expected: 3 },
    { value: '1.e-2', expected: 2 },
    { value: '1.23123e2', expected: 3 },
    { value: '123.123e+2', expected: 1 },
    { value: 123.123e+2, expected: 1 },
    { value: '.2e-2', expected: 3 },
    { value: '1', expected: 0 },
    { value: '123', expected: 0 },
    { value: '0', expected: 0 },
    { value: '-123', expected: 0 },
    { value: 'abc', expected: 0 },
    { value: 'e', expected: 0 },
    { value: '', expected: 0 },
    { value: null, expected: 0 },
    { value: false, expected: 0 },
    { value: undefined, expected: 0 }
  ].forEach(testCase => {
    it(`Should count decimals for ${testCase.value}`, () => {
      expect(countDecimalPlaces(testCase.value)).toBe(testCase.expected)
    })
  })
})
<commit_msg>Add validateMinCap tests<commit_after>import { countDecimalPlaces, validateMinCap } from './utils'

describe('countDecimalPlaces', () => {
  [
    { value: '1.123', expected: 3 },
    { value: '1.12', expected: 2 },
    { value: '1.', expected: 0 },
    { value: '1', expected: 0 },
    { value: '.123', expected: 3 },
    { value: .123, expected: 3 },
    { value: '1e-3', expected: 3 },
    { value: '1e-2', expected: 2 },
    { value: '1.2e-2', expected: 3 },
    { value: '1.e-2', expected: 2 },
    { value: '1.23123e2', expected: 3 },
    { value: '123.123e+2', expected: 1 },
    { value: 123.123e+2, expected: 1 },
    { value: '.2e-2', expected: 3 },
    { value: '1', expected: 0 },
    { value: '123', expected: 0 },
    { value: '0', expected: 0 },
    { value: '-123', expected: 0 },
    { value: 'abc', expected: 0 },
    { value: 'e', expected: 0 },
    { value: '', expected: 0 },
    { value: null, expected: 0 },
    { value: false, expected: 0 },
    { value: undefined, expected: 0 }
  ].forEach(testCase => {
    it(`Should count decimals for ${testCase.value}`, () => {
      expect(countDecimalPlaces(testCase.value)).toBe(testCase.expected)
    })
  })
})

describe('validateMinCap', () => {
  [
    { value: '', expected: true },
    { value: '0', expected: true },
    { value: '00', expected: true },
    { value: '1', expected: true },
    { value: '001', expected: true },
    { value: '150', expected: true },
    { value: '999', expected: true },
    { value: '-10', expected: false },
    { value: .123, expected: false },
    { value: '1.12', expected: false },
    { value: '1.', expected: false },
    { value: '1e10', expected: false },
    { value: '+1', expected: false },
    { value: null, expected: false },
    { value: false, expected: false },
    { value: undefined, expected: false }
  ].forEach(testCase => {
    const action = testCase.expected ? 'pass' : 'fail'

    it(`Should ${action} for '${testCase.value}'`, () => {
      expect(validateMinCap(testCase.value)).toBe(testCase.expected)
    })
  })
})
<|endoftext|>


<commit_before>var fs = require('fs');
var Gettext = require('node-gettext');
var glob = require("glob")
var path = require("path")

module.exports = function(app, options) {

    var options = options || {};
    var logger = options.logger || console;
    var gt = new Gettext();

    // Defaults
    options.defaultLocale               = options.defaultLocale || 'en-US';
    options.currentLocale               = options.currentLocale || 'en-US';
    options.directory                   = options.directory || 'locales';
    options.alias                       = options.alias || 'gettext';
    options.useAcceptedLangugeHeader    = options.useAcceptedLangugeHeader || true;

    // Load translations from PO files
    var dirPath = path.join(options.directory, "**/*.po");

    glob(dirPath, {}, function (err, files) {

        if(err) {
            logger.error('err', err);
        }

        files.forEach(function(file) {

            var fileContents = fs.readFileSync(file);
            var locale = file.match(/[a-z]{2}(-|_)[A-Z]{2}/)[0].replace('_','-').toLowerCase(); // Extract locale from path
            gt.addTextdomain(locale, fileContents);

        });

    });

    var getText = function(textKey, locale) {

        var currentLocale = locale || options.currentLocale;
        var text = gt._getTranslation(currentLocale.toLowerCase(), textKey);

        if(!text) {
            // Fallback to default langauge
            text = gt._getTranslation(options.defaultLocale.toLowerCase(), textKey);
        }

        if(!text) {
            // Fallback to text key
            text = '[MISSING]' + textKey;
        }

        return text;

    }

    var setCurrentLocale = function(language) {
        options.currentLocale = language;
    }

    // Setup locals for Express
    app.locals[options.alias] = getText;
    app.locals.currentLocale = options.currentLocale;
    app.locals.setCurrentLocale = setCurrentLocale;

    // Return middelware function to map locals on Request
    return function(req, res, next) {

        res.locals[options.alias] = getText;
        req.setCurrentLocale = setCurrentLocale;

        if(options.useAcceptedLangugeHeader) {

            // Use first match from accepted languages header
            if(req.acceptedLanguages.length) {
                req.setCurrentLocale(req.acceptedLanguages[0]);
            }

        }

        next();
    };

}
<commit_msg>Use 'locale' module for the locale detection base upon accept-language header, and expose other things to the other world. <commit_after>var fs = require('fs');
var Gettext = require('node-gettext');
var glob = require("glob")
var path = require("path")
var locale = require("locale");

module.exports = function(app, options) {

    var options = options || {};
    var logger = options.logger || console;
    var gt = new Gettext();

    // Default options
    options.directory                   = options.directory || 'locales';
    options.alias                       = options.alias || 'gettext';
    options.useAcceptedLangugeHeader    = options.useAcceptedLangugeHeader || true;

    // Locales
    var localeDetector;
    var supportedLocales    = [];
    var defaultLocale       = options.defaultLocale || 'en-US';
    var currentLocale       = options.currentLocale || 'en-US';

    // Load translations from PO files
    var dirPath = path.join(options.directory, "**/*.po");

    glob(dirPath, {}, function (err, files) {

        var locales = []

        if(err) {
            logger.error('err', err);
        }

        files.forEach(function(file) {

            var fileContents = fs.readFileSync(file);
            var locale = file.match(/[a-z]{2}(-|_)[A-Z]{2}/)[0].replace('-','_').toLowerCase(); // Extract locale from path

            if(locale) {
                locales.push(locale);
                gt.addTextdomain(locale, fileContents);
            }

        });

        supportedLocales = new locale.Locales(locales);
        localeDetector = locale(supportedLocales);

    });

    var getText = function(textKey, locale) {

        var targetLocale = (locale || currentLocale).toLowerCase();
        var text = gt._getTranslation(targetLocale, textKey);

        if(!text) {
            // Fallback to default langauge
            var locale = defaultLocale.toLowerCase();
            text = gt._getTranslation(locale, textKey);
        }

        if(!text) {
            // Fallback to text key
            text = '[MISSING]' + textKey;
        }

        return text;

    }

    var setCurrentLocale = function(locale) {
        currentLocale = locale;
    };

    var getCurrentLocale = function() {
        return currentLocale;
    };

    var getFormattedLocale = function() {
        return getCurrentLocale().replace('_', '-');
    }

    // Setup locals for Express
    app.locals[options.alias] = getText;
    app.locals.getCurrentLocale = getFormattedLocale;
    app.locals.setCurrentLocale = setCurrentLocale;

    // Return middelware function to map locals on Request
    return function(req, res, next) {

        if(options.useAcceptedLangugeHeader) {
            var locales = new locale.Locales(req.headers["accept-language"])
            var matchedLocale = locales.best(supportedLocales);

            setCurrentLocale(matchedLocale.normalized);
        }

        res.locals[options.alias] = getText;
        req.setCurrentLocale = setCurrentLocale;
        req.getCurrentLocale = getFormattedLocale;

        next();
    };

}
<|endoftext|>


<commit_before>var fs = require('fs');
var Gettext = require('node-gettext');
var glob = require("glob")
var path = require("path")
var locale = require("locale");

module.exports = function(app, options) {

    var options = options || {};
    var logger = options.logger || console;
    var gt = new Gettext();

    // Default options
    options.directory                   = options.directory || 'locales';
    options.alias                       = options.alias || 'gettext';
    options.detectors                   = options.detectors || {
        header: 'accept-language',
        query: 'locale'
    }

    // Locales
    var localeDetector;
    var supportedLocales    = [];
    var defaultLocale       = options.defaultLocale || 'en-US';
    var currentLocale       = options.currentLocale || 'en-US';

    // Load translations from PO files
    var dirPath = path.join(options.directory, "**/*.po");

    glob(dirPath, {}, function (err, files) {

        var locales = []

        if(err) {
            logger.error('err', err);
        }

        files.forEach(function(file) {

            var fileContents = fs.readFileSync(file);
            var locale = file.match(/[a-z]{2}(-|_)[A-Z]{2}/)[0].replace('-','_').toLowerCase(); // Extract locale from path

            if(locale) {

                if(locales.indexOf(locale) == -1) {
                    locales.push(locale);
                }

                gt.addTextdomain(locale, fileContents);
            }

        });

        supportedLocales = new locale.Locales(locales);
        localeDetector = locale(supportedLocales);

    });

    var getText = function(textKey, locale) {

        var targetLocale = (locale || currentLocale).toLowerCase();
        var text = gt._getTranslation(targetLocale, textKey);

        if(!text) {
            // Fallback to default langauge
            var locale = defaultLocale.toLowerCase();
            text = gt._getTranslation(locale, textKey);
        }

        if(!text) {
            // Fallback to text key
            text = '[MISSING]' + textKey;
        }

        return text;

    }

    var setCurrentLocale = function(locale) {
        currentLocale = locale;
    };

    var getCurrentLocale = function() {
        return currentLocale;
    };

    var getFormattedLocale = function() {
        return getCurrentLocale().replace('_', '-');
    }

    var getSupportedLocales = function() {
        return supportedLocales.toJSON().map(function(locale) {
            return locale.normalized;
        });
    }

    // Setup locals for Express
    app.locals[options.alias] = getText;
    app.locals.getCurrentLocale = getFormattedLocale;
    app.locals.setCurrentLocale = setCurrentLocale;
    app.locals.getSupportedLocales = getSupportedLocales;

    // Return middelware function to map locals on Request
    return function(req, res, next) {

        if(options.detectors.header) {
            var locales = new locale.Locales(req.headers[options.detectors.header])
            var matchedLocale = locales.best(supportedLocales);

            setCurrentLocale(matchedLocale.normalized);
        }

        if(options.detectors.query) {
            var locales = new locale.Locales(req.query[options.detectors.query])
            var matchedLocale = locales.best(supportedLocales);

            setCurrentLocale(matchedLocale.normalized);
        }

        res.locals[options.alias] = getText;
        req.setCurrentLocale = setCurrentLocale;
        req.getCurrentLocale = getFormattedLocale;
        req.getSupportedLocales = getSupportedLocales;

        next();
    };

}
<commit_msg>Formatting<commit_after>var fs = require('fs');
var Gettext = require('node-gettext');
var glob = require("glob")
var path = require("path")
var locale = require("locale");

module.exports = function(app, options) {

    var options = options || {};
    var logger = options.logger || console;
    var gt = new Gettext();

    // Default options
    options.directory                   = options.directory || 'locales';
    options.alias                       = options.alias || 'gettext';
    options.detectors                   = options.detectors || {
        header: 'accept-language',
        query:  'locale'
    }

    // Locales
    var localeDetector;
    var supportedLocales    = [];
    var defaultLocale       = options.defaultLocale || 'en-US';
    var currentLocale       = options.currentLocale || 'en-US';

    // Load translations from PO files
    var dirPath = path.join(options.directory, "**/*.po");

    glob(dirPath, {}, function (err, files) {

        var locales = []

        if(err) {
            logger.error('err', err);
        }

        files.forEach(function(file) {

            var fileContents = fs.readFileSync(file);
            var locale = file.match(/[a-z]{2}(-|_)[A-Z]{2}/)[0].replace('-','_').toLowerCase(); // Extract locale from path

            if(locale) {

                if(locales.indexOf(locale) == -1) {
                    locales.push(locale);
                }

                gt.addTextdomain(locale, fileContents);
            }

        });

        supportedLocales = new locale.Locales(locales);
        localeDetector = locale(supportedLocales);

    });

    var getText = function(textKey, locale) {

        var targetLocale = (locale || currentLocale).toLowerCase();
        var text = gt._getTranslation(targetLocale, textKey);

        if(!text) {
            // Fallback to default langauge
            var locale = defaultLocale.toLowerCase();
            text = gt._getTranslation(locale, textKey);
        }

        if(!text) {
            // Fallback to text key
            text = '[MISSING]' + textKey;
        }

        return text;

    }

    var setCurrentLocale = function(locale) {
        currentLocale = locale;
    };

    var getCurrentLocale = function() {
        return currentLocale;
    };

    var getFormattedLocale = function() {
        return getCurrentLocale().replace('_', '-');
    }

    var getSupportedLocales = function() {
        return supportedLocales.toJSON().map(function(locale) {
            return locale.normalized;
        });
    }

    // Setup locals for Express
    app.locals[options.alias] = getText;
    app.locals.getCurrentLocale = getFormattedLocale;
    app.locals.setCurrentLocale = setCurrentLocale;
    app.locals.getSupportedLocales = getSupportedLocales;

    // Return middelware function to map locals on Request
    return function(req, res, next) {

        if(options.detectors.header) {
            var locales = new locale.Locales(req.headers[options.detectors.header])
            var matchedLocale = locales.best(supportedLocales);

            setCurrentLocale(matchedLocale.normalized);
        }

        if(options.detectors.query) {
            var locales = new locale.Locales(req.query[options.detectors.query])
            var matchedLocale = locales.best(supportedLocales);

            setCurrentLocale(matchedLocale.normalized);
        }

        res.locals[options.alias] = getText;
        req.setCurrentLocale = setCurrentLocale;
        req.getCurrentLocale = getFormattedLocale;
        req.getSupportedLocales = getSupportedLocales;

        next();
    };

}
<|endoftext|>