<commit_before>
module.exports = help

help.completion = function (opts, cb) {
  if (opts.conf.argv.remain.length > 2) return cb(null, [])
  var num = 1
  if (-1 !== opts.conf.argv.remain[1].indexOf("api")) num = 3
  getSections(num, cb)
}

var fs = require("graceful-fs")
  , path = require("path")
  , spawn = require("child_process").spawn
  , npm = require("./npm.js")
  , log = require("npmlog")
  , opener = require("opener")

function help (args, cb) {
  var num = 1
    , argv = npm.config.get("argv").cooked
  if (argv.length && -1 !== argv[0].indexOf("api")) {
    num = 3
  }

  if (args.length > 1 && args[0]) {
    return npm.commands["help-search"](args, num, cb)
  }

  var section = npm.deref(args[0]) || args[0]

  if (section) {
    if ( npm.config.get("usage")
      && npm.commands[section]
      && npm.commands[section].usage
    ) {
      npm.config.set("loglevel", "silent")
      log.level = "silent"
      console.log(npm.commands[section].usage)
      return cb()
    }

    var sectionPath = path.join( __dirname, "..", "man", "man" + num
                               , section + "." + num)
      , htmlPath = path.resolve( __dirname, "..", "html"
                               , num === 3 ? "api" : "doc"
                               , section+".html" )
    return fs.stat
      ( sectionPath
      , function (e, o) {
          if (e) return npm.commands["help-search"](args, cb)

          var manpath = path.join(__dirname, "..", "man")
            , env = {}
          Object.keys(process.env).forEach(function (i) {
            env[i] = process.env[i]
          })
          env.MANPATH = manpath
          var viewer = npm.config.get("viewer")

          switch (viewer) {
            case "woman":
              var a = ["-e", "(woman-find-file \"" + sectionPath + "\")"]
              var conf = { env: env, customFds: [ 0, 1, 2] }
              var woman = spawn("emacsclient", a, conf)
              woman.on("close", cb)
              break

            case "browser":
              opener(htmlPath, { command: npm.config.get("browser") }, cb)
              break

            default:
              var conf = { env: env, customFds: [ 0, 1, 2] }
              var man = spawn("man", [num, section], conf)
              man.on("close", cb)
          }
        }
      )
  } else getSections(function (er, sections) {
    if (er) return cb(er)
    npm.config.set("loglevel", "silent")
    log.level = "silent"
    console.log
      ( ["\nUsage: npm <command>"
        , ""
        , "where <command> is one of:"
        , npm.config.get("long") ? usages()
          : "    " + wrap(Object.keys(npm.commands))
        , ""
        , "npm <cmd> -h     quick help on <cmd>"
        , "npm -l           display full usage info"
        , "npm faq          commonly asked questions"
        , "npm help <term>  search for help on <term>"
        , "npm help npm     involved overview"
        , ""
        , "Specify configs in the ini-formatted file:"
        , "    " + npm.config.get("userconfig")
        , "or on the command line via: npm <command> --key value"
        , "Config info can be viewed via: npm help config"
        , ""
        , "npm@" + npm.version + " " + path.dirname(__dirname)
        ].join("\n"))
    cb(er)
  })
}

function usages () {
  // return a string of <cmd>: <usage>
  var maxLen = 0
  return Object.keys(npm.commands).filter(function (c) {
    return c === npm.deref(c)
  }).reduce(function (set, c) {
    set.push([c, npm.commands[c].usage || ""])
    maxLen = Math.max(maxLen, c.length)
    return set
  }, []).map(function (item) {
    var c = item[0]
      , usage = item[1]
    return "\n    " + c + (new Array(maxLen - c.length + 2).join(" "))
         + (usage.split("\n")
            .join("\n" + (new Array(maxLen + 6).join(" "))))
  }).join("\n")
  return out
}

function wrap (arr) {
  var out = ['']
    , l = 0
  arr.sort(function (a,b) { return a<b?-1:1 })
    .forEach(function (c) {
      if (out[l].length + c.length + 2 < 60) {
        out[l] += ', '+c
      } else {
        out[l++] += ','
        out[l] = c
      }
    })
  return out.join("\n    ").substr(2)
}

function getSections (num, cb) {
  if (typeof cb !== "function") cb = num, num = 1

  var mp = path.join(__dirname, "../man/man" + num + "/")
    , cleaner = new RegExp("\\." + num + "$")
  fs.readdir(mp, function (er, files) {
    if (er) return cb(er)
    var sectionList = files.concat("help." + num)
      .filter(function (s) { return s.match(cleaner) })
      .map(function (s) { return s.replace(cleaner, "")})
    cb(null, sectionList)
  })
}
<commit_msg>help: Use new doc file layout<commit_after>
module.exports = help

help.completion = function (opts, cb) {
  if (opts.conf.argv.remain.length > 2) return cb(null, [])
  getSections(cb)
}

var fs = require("graceful-fs")
  , path = require("path")
  , spawn = require("child_process").spawn
  , npm = require("./npm.js")
  , log = require("npmlog")
  , opener = require("opener")
  , glob = require("glob")

function help (args, cb) {
  var  argv = npm.config.get("argv").cooked

  // npm help foo bar baz: search topics
  if (args.length > 1 && args[0]) {
    return npm.commands["help-search"](args, num, cb)
  }

  var section = npm.deref(args[0]) || args[0]

  // npm help <noargs>:  show basic usage
  if (!section)
    return npmUsage(cb)

  // npm <cmd> -h: show command usage
  if ( npm.config.get("usage")
    && npm.commands[section]
    && npm.commands[section].usage
  ) {
    npm.config.set("loglevel", "silent")
    log.level = "silent"
    console.log(npm.commands[section].usage)
    return cb()
  }

  // npm apihelp <section>: Prefer section 3 over section 1
  var apihelp = argv.length && -1 !== argv[0].indexOf("api")
  var pref = apihelp ? [3, 1, 5, 7] : [1, 3, 5, 7]

  // npm help <section>: Try to find the path
  var manroot = path.resolve(__dirname, "..", "man")
  var htmlroot = path.resolve(__dirname, "..", "html", "doc")

  // find either /section.n or /npm-section.n
  var f = "+(npm-" + section + "|" + section + ").[0-9]"
  return glob(manroot + "/*/" + f, function (er, mans) {
    if (er)
      return cb(er)

    if (!mans.length)
      return npm.commands["help-search"](args, cb)

    viewMan(pickMan(mans, pref), cb)
  })
}

function pickMan (mans, pref_) {
  var nre = /([0-9]+)$/
  var pref = {}
  pref_.forEach(function (sect, i) {
    pref[sect] = i
  })
  mans = mans.sort(function (a, b) {
    var an = a.match(nre)[1]
    var bn = b.match(nre)[1]
    return an === bn ? (a > b ? -1 : 1)
         : pref[an] < pref[bn] ? -1
         : 1
  })
  return mans[0]
}

function viewMan (man, cb) {
  var nre = /([0-9]+)$/
  var num = man.match(nre)[1]
  var section = path.basename(man, "." + num)

  // at this point, we know that the specified man page exists
  var manpath = path.join(__dirname, "..", "man")
    , env = {}
  Object.keys(process.env).forEach(function (i) {
    env[i] = process.env[i]
  })
  env.MANPATH = manpath
  var viewer = npm.config.get("viewer")

  switch (viewer) {
    case "woman":
      var a = ["-e", "(woman-find-file \"" + man + "\")"]
      var conf = { env: env, customFds: [ 0, 1, 2] }
      var woman = spawn("emacsclient", a, conf)
      woman.on("close", cb)
      break

    case "browser":
      opener(htmlMan(man), { command: npm.config.get("browser") }, cb)
      break

    default:
      var conf = { env: env, customFds: [ 0, 1, 2] }
      var man = spawn("man", [num, section], conf)
      man.on("close", cb)
      break
  }
}

function htmlMan (man) {
  var sect = +man.match(/([0-9]+)$/)[1]
  var f = path.basename(man).replace(/([0-9]+)$/, "html")
  switch (sect) {
    case 1:
      sect = "cli"
      break
    case 3:
      sect = "api"
      break
    case 5:
      sect = "files"
      break
    case 7:
      sect = "misc"
      break
    default:
      throw new Error("invalid man section: " + sect)
  }
  return path.resolve(__dirname, "..", "html", "doc", sect, f)
}

function npmUsage (cb) {
  npm.config.set("loglevel", "silent")
  log.level = "silent"
  console.log
    ( ["\nUsage: npm <command>"
      , ""
      , "where <command> is one of:"
      , npm.config.get("long") ? usages()
        : "    " + wrap(Object.keys(npm.commands))
      , ""
      , "npm <cmd> -h     quick help on <cmd>"
      , "npm -l           display full usage info"
      , "npm faq          commonly asked questions"
      , "npm help <term>  search for help on <term>"
      , "npm help npm     involved overview"
      , ""
      , "Specify configs in the ini-formatted file:"
      , "    " + npm.config.get("userconfig")
      , "or on the command line via: npm <command> --key value"
      , "Config info can be viewed via: npm help config"
      , ""
      , "npm@" + npm.version + " " + path.dirname(__dirname)
      ].join("\n"))
  cb()
}

function usages () {
  // return a string of <cmd>: <usage>
  var maxLen = 0
  return Object.keys(npm.commands).filter(function (c) {
    return c === npm.deref(c)
  }).reduce(function (set, c) {
    set.push([c, npm.commands[c].usage || ""])
    maxLen = Math.max(maxLen, c.length)
    return set
  }, []).map(function (item) {
    var c = item[0]
      , usage = item[1]
    return "\n    " + c + (new Array(maxLen - c.length + 2).join(" "))
         + (usage.split("\n")
            .join("\n" + (new Array(maxLen + 6).join(" "))))
  }).join("\n")
  return out
}

function wrap (arr) {
  var out = ['']
    , l = 0
    , line

  line = process.stdout.columns
  if (!line)
    line = 60
  else
    line = Math.max(line - 16, 24)

  arr.sort(function (a,b) { return a<b?-1:1 })
    .forEach(function (c) {
      if (out[l].length + c.length + 2 < line) {
        out[l] += ', '+c
      } else {
        out[l++] += ','
        out[l] = c
      }
    })
  return out.join("\n    ").substr(2)
}

function getSections (cb) {
  var g = path.resolve(__dirname, "../man/man[0-9]/*.[0-9]")
  glob(g, function (er, files) {
    if (er)
      return cb(er)
    cb(null, Object.keys(files.reduce(function (acc, file) {
      file = path.basename(file).replace(/\.[0-9]+$/, "")
      file = file.replace(/^npm-/, "")
      acc[file] = true
      return acc
    }, { help: true })))
  })
}
<|endoftext|>


<commit_before>/*
 * Mentions Input
 * Version 1.0
 * Written by: Kenneth Auchenberg (Podio)
 *
 * Using underscore.js
 *
 * License: MIT License - http://www.opensource.org/licenses/mit-license.php
 */

(function ($, _, undefined) {

  // Settings
  var KEY = { BACKSPACE : 8, TAB : 9, RETURN : 13, ESC : 27, LEFT : 37, UP : 38, RIGHT : 39, DOWN : 40, COMMA : 188, SPACE : 32, HOME : 36, END : 35 }; // Keys "enum"
  var defaultSettings = {
    triggerChar   : '@',
    onDataRequest : $.noop,
    minChars      : 2,
    showAvatars   : true,
    elastic       : true,
    classes       : {
      autoCompleteItemActive : "active"
    },
    templates     : {
      wrapper                    : _.template('

'),
      autocompleteList           : _.template('

'),
      autocompleteListItem       : _.template('<li data-ref-id="<%= id %>" data-ref-type="<%= type %>" data-display="<%= display %>"><%= content %>
'),
      autocompleteListItemAvatar : _.template('<img  src="<%= avatar %>" />'),
      autocompleteListItemIcon   : _.template('<div class="icon <%= icon %>">
'),
      mentionsOverlay            : _.template('

'),
      mentionItemSyntax          : _.template('@[<%= value %>](<%= type %>:<%= id %>)'),
      mentionItemHighlight       : _.template('<%= value %>')
    }
  };

  var utils = {
    htmlEncode       : function (str) {
      return _.escape(str);
    },
    highlightTerm    : function (value, term) {
      if (!term && !term.length) {
        return value;
      }
      return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "$1");
    },
    setCaratPosition : function (domNode, caretPos) {
      if (domNode.createTextRange) {
        var range = domNode.createTextRange();
        range.move('character', caretPos);
        range.select();
      } else {
        if (domNode.selectionStart) {
          domNode.focus();
          domNode.setSelectionRange(caretPos, caretPos);
        } else {
          domNode.focus();
        }
      }
    }
  };

  var MentionsInput = function (input) {
    var settings;
    var elmInputBox, elmInputWrapper, elmAutocompleteList, elmWrapperBox, elmMentionsOverlay, elmActiveAutoCompleteItem;
    var mentionsCollection = [];
    var inputBuffer = [];
    var currentDataQuery;

    function initTextarea() {
      elmInputBox = $(input);

      if (elmInputBox.attr('data-mentions-input') == 'true') {
        return;
      }

      elmInputWrapper = elmInputBox.parent();
      elmWrapperBox = $(settings.templates.wrapper());
      elmInputBox.wrapAll(elmWrapperBox);
      elmWrapperBox = elmInputWrapper.find('> div');

      elmInputBox.attr('data-mentions-input', 'true');
      elmInputBox.bind('keydown', onInputBoxKeyDown);
      elmInputBox.bind('keypress', onInputBoxKeyPress);
      elmInputBox.bind('input', onInputBoxInput);
      elmInputBox.bind('click', onInputBoxClick);

      if (settings.elastic) {
        elmInputBox.elastic();
      }
    }

    function initAutocomplete() {
      elmAutocompleteList = $(settings.templates.autocompleteList());
      elmAutocompleteList.appendTo(elmWrapperBox);
      elmAutocompleteList.delegate('li', 'click', onAutoCompleteItemClick);
    }

    function initMentionsOverlay() {
      elmMentionsOverlay = $(settings.templates.mentionsOverlay());
      elmMentionsOverlay.prependTo(elmWrapperBox);
    }

    function updateValues() {
      var syntaxMessage = getInputBoxValue();

      _.each(mentionsCollection, function (mention) {
        var textSyntax = settings.templates.mentionItemSyntax({ value : mention.value, type : 'contact', id : mention.id });
        syntaxMessage = syntaxMessage.replace(mention.value, textSyntax);
      });

      var mentionText = utils.htmlEncode(syntaxMessage);

      _.each(mentionsCollection, function (mention) {
        var textSyntax = settings.templates.mentionItemSyntax({ value : utils.htmlEncode(mention.value), type : 'contact', id : mention.id });
        var textHighlight = settings.templates.mentionItemHighlight({ value : utils.htmlEncode(mention.value) });

        mentionText = mentionText.replace(textSyntax, textHighlight);
      });

      mentionText = mentionText.replace(/\n/g, '
');
      mentionText = mentionText.replace(/ {2}/g, '  ');

      elmInputBox.data('messageText', syntaxMessage);
      elmMentionsOverlay.find('div').html(mentionText);
    }

    function resetBuffer() {
      inputBuffer = [];
    }

    function updateMentionsCollection() {
      var inputText = getInputBoxValue();

      mentionsCollection = _.reject(mentionsCollection, function (mention, index) {
        return !mention.value || inputText.indexOf(mention.value) == -1;
      });
      mentionsCollection = _.compact(mentionsCollection);
    }

    function addMention(value, id, type) {
      var currentMessage = getInputBoxValue();

      // Using a regex to figure out positions
      var regex = new RegExp("\\" + settings.triggerChar + currentDataQuery, "gi");
      regex.exec(currentMessage);

      var startCaretPosition = regex.lastIndex - currentDataQuery.length - 1;
      var currentCaretPosition = regex.lastIndex;

      var start = currentMessage.substr(0, startCaretPosition);
      var end = currentMessage.substr(currentCaretPosition, currentMessage.length);
      var startEndIndex = (start + value).length;

      var updatedMessageText = start + value + end;

      mentionsCollection.push({
        id    : id,
        type  : type,
        value : value
      });

      // Cleaning before inserting the value, otherwise auto-complete would be triggered with "old" inputbuffer
      resetBuffer();
      currentDataQuery = '';
      hideAutoComplete();

      // Mentions & syntax message
      elmInputBox.val(updatedMessageText);
      updateValues();

      // Set correct focus and selection
      elmInputBox.focus();
      utils.setCaratPosition(elmInputBox[0], startEndIndex);
    }

    function getInputBoxValue() {
      return $.trim(elmInputBox.val());
    }

    function onAutoCompleteItemClick(e) {
      var elmTarget = $(this);

      addMention(elmTarget.attr('data-display'), elmTarget.attr('data-ref-id'), elmTarget.attr('data-ref-type'));

      return false;
    }

    function onInputBoxClick(e) {
      resetBuffer();
    }

    function onInputBoxInput(e) {
      updateValues();
      updateMentionsCollection();
      hideAutoComplete();

      var triggerCharIndex = _.lastIndexOf(inputBuffer, settings.triggerChar);
      if (triggerCharIndex > -1) {
        currentDataQuery = inputBuffer.slice(triggerCharIndex + 1).join('');

        _.defer(_.bind(doSearch, this, currentDataQuery));
      }
    }

    function onInputBoxKeyPress(e) {
      var typedValue = String.fromCharCode(e.which || e.keyCode);
      inputBuffer.push(typedValue);
    }

    function onInputBoxKeyDown(e) {

      // This also matches HOME/END on OSX which is CMD+LEFT, CMD+RIGHT
      if (e.keyCode == KEY.LEFT || e.keyCode == KEY.RIGHT || e.keyCode == KEY.HOME || e.keyCode == KEY.END) {
        // Defer execution to ensure carat pos has changed after HOME/END keys
        _.defer(resetBuffer);
        return;
      }

      if (e.keyCode == KEY.BACKSPACE) {
        inputBuffer = inputBuffer.slice(0, -1 + inputBuffer.length); // Can't use splice, not available in IE
        return;
      }

      if (!elmAutocompleteList.is(':visible')) {
        return true;
      }

      switch (e.keyCode) {
        case KEY.UP:
        case KEY.DOWN:
          var elmCurrentAutoCompleteItem = null;
          if (e.keyCode == KEY.DOWN) {
            if (elmActiveAutoCompleteItem && elmActiveAutoCompleteItem.length) {
              elmCurrentAutoCompleteItem = elmActiveAutoCompleteItem.next();
            } else {
              elmCurrentAutoCompleteItem = elmAutocompleteList.find('li').first();
            }
          } else {
            elmCurrentAutoCompleteItem = $(elmActiveAutoCompleteItem).prev();
          }

          if (elmCurrentAutoCompleteItem.length) {
            selectAutoCompleteItem(elmCurrentAutoCompleteItem);
          }

          return false;

        case KEY.RETURN:
        case KEY.TAB:
          if (elmActiveAutoCompleteItem && elmActiveAutoCompleteItem.length) {
            elmActiveAutoCompleteItem.click();
            return false;
          }

          break;
      }

      return true;
    }

    function hideAutoComplete() {
      elmActiveAutoCompleteItem = null;
      elmAutocompleteList.empty().hide();
    }

    function selectAutoCompleteItem(elmItem) {
      elmItem.addClass(settings.classes.autoCompleteItemActive);
      elmItem.siblings().removeClass(settings.classes.autoCompleteItemActive);

      elmActiveAutoCompleteItem = elmItem;
    }

    function populateDropdown(query, results) {
      elmAutocompleteList.show();

      // Filter items that has already been mentioned
      var mentionValues = _.pluck(mentionsCollection, 'value');
      results = _.reject(results, function (item) {
        return _.include(mentionValues, item.name);
      });

      if (!results.length) {
        hideAutoComplete();
        return;
      }

      elmAutocompleteList.empty();
      var elmDropDownList = $("
").appendTo(elmAutocompleteList).hide();

      _.each(results, function (item) {
        var elmListItem = $(settings.templates.autocompleteListItem({
          'id'      : utils.htmlEncode(item.id),
          'display' : utils.htmlEncode(item.name),
          'type'    : utils.htmlEncode(item.type),
          'content' : utils.highlightTerm(utils.htmlEncode((item.name)), query)
        }));

        if (settings.showAvatars) {
          var elmIcon;

          if (item.avatar) {
            elmIcon = $(settings.templates.autocompleteListItemAvatar({ avatar : item.avatar }));
          } else {
            elmIcon = $(settings.templates.autocompleteListItemIcon({ icon : item.icon }));
          }
          elmIcon.prependTo(elmListItem);
        }
        elmListItem = elmListItem.appendTo(elmDropDownList);
      });

      elmAutocompleteList.show();
      elmDropDownList.show();
    }

    function doSearch(query) {
      if (query && query.length && query.length >= settings.minChars) {
        settings.onDataRequest.call(this, 'search', query, function (responseData) {
          populateDropdown(query, responseData);
        });
      }
    }

    // Public methods
    return {
      init : function (options) {
        settings = options;

        initTextarea();
        initAutocomplete();
        initMentionsOverlay();
      },

      val : function (callback) {
        if (!_.isFunction(callback)) {
          return;
        }

        var value = mentionsCollection.length ? elmInputBox.data('messageText') : getInputBoxValue();
        callback.call(this, value);
      },

      reset : function () {
        elmInputBox.val('');
        mentionsCollection = [];
        updateValues();
      },

      getMentions : function (callback) {
        if (!_.isFunction(callback)) {
          return;
        }

        callback.call(this, mentionsCollection);
      }
    };
  };

  $.fn.mentionsInput = function (method, settings) {

    if (typeof method === 'object' || !method) {
      settings = method;
    }

    if (!settings) {
      settings = {};
    }

    settings = _.defaults(settings, defaultSettings);
    var outerArguments = arguments;

    return this.each(function () {
      var instance = $.data(this, 'mentionsInput') || $.data(this, 'mentionsInput', new MentionsInput(this));

      if (_.isFunction(instance[method])) {
        return instance[method].apply(this, Array.prototype.slice.call(outerArguments, 1));

      } else if (typeof method === 'object' || !method) {
        return instance.init.call(this, settings);

      } else {
        $.error('Method ' + method + ' does not exist');
      }

    });
  };

})(jQuery, _);<commit_msg>Use a deep copy for settings instead of defaults<commit_after>/*
 * Mentions Input
 * Version 1.0
 * Written by: Kenneth Auchenberg (Podio)
 *
 * Using underscore.js
 *
 * License: MIT License - http://www.opensource.org/licenses/mit-license.php
 */

(function ($, _, undefined) {

  // Settings
  var KEY = { BACKSPACE : 8, TAB : 9, RETURN : 13, ESC : 27, LEFT : 37, UP : 38, RIGHT : 39, DOWN : 40, COMMA : 188, SPACE : 32, HOME : 36, END : 35 }; // Keys "enum"
  var defaultSettings = {
    triggerChar   : '@',
    onDataRequest : $.noop,
    minChars      : 2,
    showAvatars   : true,
    elastic       : true,
    classes       : {
      autoCompleteItemActive : "active"
    },
    templates     : {
      wrapper                    : _.template('

'),
      autocompleteList           : _.template('

'),
      autocompleteListItem       : _.template('<li data-ref-id="<%= id %>" data-ref-type="<%= type %>" data-display="<%= display %>"><%= content %>
'),
      autocompleteListItemAvatar : _.template('<img  src="<%= avatar %>" />'),
      autocompleteListItemIcon   : _.template('<div class="icon <%= icon %>">
'),
      mentionsOverlay            : _.template('

'),
      mentionItemSyntax          : _.template('@[<%= value %>](<%= type %>:<%= id %>)'),
      mentionItemHighlight       : _.template('<%= value %>')
    }
  };

  var utils = {
    htmlEncode       : function (str) {
      return _.escape(str);
    },
    highlightTerm    : function (value, term) {
      if (!term && !term.length) {
        return value;
      }
      return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "$1");
    },
    setCaratPosition : function (domNode, caretPos) {
      if (domNode.createTextRange) {
        var range = domNode.createTextRange();
        range.move('character', caretPos);
        range.select();
      } else {
        if (domNode.selectionStart) {
          domNode.focus();
          domNode.setSelectionRange(caretPos, caretPos);
        } else {
          domNode.focus();
        }
      }
    }
  };

  var MentionsInput = function (input) {
    var settings;
    var elmInputBox, elmInputWrapper, elmAutocompleteList, elmWrapperBox, elmMentionsOverlay, elmActiveAutoCompleteItem;
    var mentionsCollection = [];
    var inputBuffer = [];
    var currentDataQuery;

    function initTextarea() {
      elmInputBox = $(input);

      if (elmInputBox.attr('data-mentions-input') == 'true') {
        return;
      }

      elmInputWrapper = elmInputBox.parent();
      elmWrapperBox = $(settings.templates.wrapper());
      elmInputBox.wrapAll(elmWrapperBox);
      elmWrapperBox = elmInputWrapper.find('> div');

      elmInputBox.attr('data-mentions-input', 'true');
      elmInputBox.bind('keydown', onInputBoxKeyDown);
      elmInputBox.bind('keypress', onInputBoxKeyPress);
      elmInputBox.bind('input', onInputBoxInput);
      elmInputBox.bind('click', onInputBoxClick);

      if (settings.elastic) {
        elmInputBox.elastic();
      }
    }

    function initAutocomplete() {
      elmAutocompleteList = $(settings.templates.autocompleteList());
      elmAutocompleteList.appendTo(elmWrapperBox);
      elmAutocompleteList.delegate('li', 'click', onAutoCompleteItemClick);
    }

    function initMentionsOverlay() {
      elmMentionsOverlay = $(settings.templates.mentionsOverlay());
      elmMentionsOverlay.prependTo(elmWrapperBox);
    }

    function updateValues() {
      var syntaxMessage = getInputBoxValue();

      _.each(mentionsCollection, function (mention) {
        var textSyntax = settings.templates.mentionItemSyntax({ value : mention.value, type : 'contact', id : mention.id });
        syntaxMessage = syntaxMessage.replace(mention.value, textSyntax);
      });

      var mentionText = utils.htmlEncode(syntaxMessage);

      _.each(mentionsCollection, function (mention) {
        var textSyntax = settings.templates.mentionItemSyntax({ value : utils.htmlEncode(mention.value), type : 'contact', id : mention.id });
        var textHighlight = settings.templates.mentionItemHighlight({ value : utils.htmlEncode(mention.value) });

        mentionText = mentionText.replace(textSyntax, textHighlight);
      });

      mentionText = mentionText.replace(/\n/g, '
');
      mentionText = mentionText.replace(/ {2}/g, '  ');

      elmInputBox.data('messageText', syntaxMessage);
      elmMentionsOverlay.find('div').html(mentionText);
    }

    function resetBuffer() {
      inputBuffer = [];
    }

    function updateMentionsCollection() {
      var inputText = getInputBoxValue();

      mentionsCollection = _.reject(mentionsCollection, function (mention, index) {
        return !mention.value || inputText.indexOf(mention.value) == -1;
      });
      mentionsCollection = _.compact(mentionsCollection);
    }

    function addMention(value, id, type) {
      var currentMessage = getInputBoxValue();

      // Using a regex to figure out positions
      var regex = new RegExp("\\" + settings.triggerChar + currentDataQuery, "gi");
      regex.exec(currentMessage);

      var startCaretPosition = regex.lastIndex - currentDataQuery.length - 1;
      var currentCaretPosition = regex.lastIndex;

      var start = currentMessage.substr(0, startCaretPosition);
      var end = currentMessage.substr(currentCaretPosition, currentMessage.length);
      var startEndIndex = (start + value).length;

      var updatedMessageText = start + value + end;

      mentionsCollection.push({
        id    : id,
        type  : type,
        value : value
      });

      // Cleaning before inserting the value, otherwise auto-complete would be triggered with "old" inputbuffer
      resetBuffer();
      currentDataQuery = '';
      hideAutoComplete();

      // Mentions & syntax message
      elmInputBox.val(updatedMessageText);
      updateValues();

      // Set correct focus and selection
      elmInputBox.focus();
      utils.setCaratPosition(elmInputBox[0], startEndIndex);
    }

    function getInputBoxValue() {
      return $.trim(elmInputBox.val());
    }

    function onAutoCompleteItemClick(e) {
      var elmTarget = $(this);

      addMention(elmTarget.attr('data-display'), elmTarget.attr('data-ref-id'), elmTarget.attr('data-ref-type'));

      return false;
    }

    function onInputBoxClick(e) {
      resetBuffer();
    }

    function onInputBoxInput(e) {
      updateValues();
      updateMentionsCollection();
      hideAutoComplete();

      var triggerCharIndex = _.lastIndexOf(inputBuffer, settings.triggerChar);
      if (triggerCharIndex > -1) {
        currentDataQuery = inputBuffer.slice(triggerCharIndex + 1).join('');

        _.defer(_.bind(doSearch, this, currentDataQuery));
      }
    }

    function onInputBoxKeyPress(e) {
      var typedValue = String.fromCharCode(e.which || e.keyCode);
      inputBuffer.push(typedValue);
    }

    function onInputBoxKeyDown(e) {

      // This also matches HOME/END on OSX which is CMD+LEFT, CMD+RIGHT
      if (e.keyCode == KEY.LEFT || e.keyCode == KEY.RIGHT || e.keyCode == KEY.HOME || e.keyCode == KEY.END) {
        // Defer execution to ensure carat pos has changed after HOME/END keys
        _.defer(resetBuffer);
        return;
      }

      if (e.keyCode == KEY.BACKSPACE) {
        inputBuffer = inputBuffer.slice(0, -1 + inputBuffer.length); // Can't use splice, not available in IE
        return;
      }

      if (!elmAutocompleteList.is(':visible')) {
        return true;
      }

      switch (e.keyCode) {
        case KEY.UP:
        case KEY.DOWN:
          var elmCurrentAutoCompleteItem = null;
          if (e.keyCode == KEY.DOWN) {
            if (elmActiveAutoCompleteItem && elmActiveAutoCompleteItem.length) {
              elmCurrentAutoCompleteItem = elmActiveAutoCompleteItem.next();
            } else {
              elmCurrentAutoCompleteItem = elmAutocompleteList.find('li').first();
            }
          } else {
            elmCurrentAutoCompleteItem = $(elmActiveAutoCompleteItem).prev();
          }

          if (elmCurrentAutoCompleteItem.length) {
            selectAutoCompleteItem(elmCurrentAutoCompleteItem);
          }

          return false;

        case KEY.RETURN:
        case KEY.TAB:
          if (elmActiveAutoCompleteItem && elmActiveAutoCompleteItem.length) {
            elmActiveAutoCompleteItem.click();
            return false;
          }

          break;
      }

      return true;
    }

    function hideAutoComplete() {
      elmActiveAutoCompleteItem = null;
      elmAutocompleteList.empty().hide();
    }

    function selectAutoCompleteItem(elmItem) {
      elmItem.addClass(settings.classes.autoCompleteItemActive);
      elmItem.siblings().removeClass(settings.classes.autoCompleteItemActive);

      elmActiveAutoCompleteItem = elmItem;
    }

    function populateDropdown(query, results) {
      elmAutocompleteList.show();

      // Filter items that has already been mentioned
      var mentionValues = _.pluck(mentionsCollection, 'value');
      results = _.reject(results, function (item) {
        return _.include(mentionValues, item.name);
      });

      if (!results.length) {
        hideAutoComplete();
        return;
      }

      elmAutocompleteList.empty();
      var elmDropDownList = $("
").appendTo(elmAutocompleteList).hide();

      _.each(results, function (item) {
        var elmListItem = $(settings.templates.autocompleteListItem({
          'id'      : utils.htmlEncode(item.id),
          'display' : utils.htmlEncode(item.name),
          'type'    : utils.htmlEncode(item.type),
          'content' : utils.highlightTerm(utils.htmlEncode((item.name)), query)
        }));

        if (settings.showAvatars) {
          var elmIcon;

          if (item.avatar) {
            elmIcon = $(settings.templates.autocompleteListItemAvatar({ avatar : item.avatar }));
          } else {
            elmIcon = $(settings.templates.autocompleteListItemIcon({ icon : item.icon }));
          }
          elmIcon.prependTo(elmListItem);
        }
        elmListItem = elmListItem.appendTo(elmDropDownList);
      });

      elmAutocompleteList.show();
      elmDropDownList.show();
    }

    function doSearch(query) {
      if (query && query.length && query.length >= settings.minChars) {
        settings.onDataRequest.call(this, 'search', query, function (responseData) {
          populateDropdown(query, responseData);
        });
      }
    }

    // Public methods
    return {
      init : function (options) {
        settings = options;

        initTextarea();
        initAutocomplete();
        initMentionsOverlay();
      },

      val : function (callback) {
        if (!_.isFunction(callback)) {
          return;
        }

        var value = mentionsCollection.length ? elmInputBox.data('messageText') : getInputBoxValue();
        callback.call(this, value);
      },

      reset : function () {
        elmInputBox.val('');
        mentionsCollection = [];
        updateValues();
      },

      getMentions : function (callback) {
        if (!_.isFunction(callback)) {
          return;
        }

        callback.call(this, mentionsCollection);
      }
    };
  };

  $.fn.mentionsInput = function (method, settings) {

    if (typeof method === 'object' || !method) {
      settings = $.extend(true, {}, defaultSettings, method);
    }

    var outerArguments = arguments;

    return this.each(function () {
      var instance = $.data(this, 'mentionsInput') || $.data(this, 'mentionsInput', new MentionsInput(this));

      if (_.isFunction(instance[method])) {
        return instance[method].apply(this, Array.prototype.slice.call(outerArguments, 1));

      } else if (typeof method === 'object' || !method) {
        return instance.init.call(this, settings);

      } else {
        $.error('Method ' + method + ' does not exist');
      }

    });
  };

})(jQuery, _);
<|endoftext|>


<commit_before>// this runs on all vikings with an etcd client to listen for events
var etcdjs = require('etcdjs')
var config = require('./config')()
var utils = require('component-consoler');
var HostMonitor = require('./hostmonitor')

module.exports = function(etcdhosts){
	var etcd = etcdjs(etcdhosts)

	var vikingHostname = config.network.hostname

	var hostMonitor = HostMonitor(config, etcd)

	var leaderRunning = false

	// this will be trigged in another viking master if the etcd leadership changes
	function runLeader(){
		if(leaderRunning) return
		utils.log('leader', 'starting')
		leaderRunning = true

		hostMonitor.leader(function(){
			// the leader module has all the servies like registry and git push
			var leader = require('./leader')(config, etcd)
			leader.start(function(err){
				if(err){
					console.error('ERROR STARTING LEADER ' + err)
					return
				}

				utils.log('leader', 'running')
			})
		})
	}

	function runSlave(){
		var slave = require('./slave')(config, etcd)
		slave.start(function(err){
			if(err){
				utils.error('ERROR STARTING SLAVE ' + err)
				return
			}

			utils.log('slave', 'running')
		})
	}

	function masterLoop(){
		etcd.stats.leader(function(err, stats){
			if(err){
				//utils.error(err)
				setTimeout(masterLoop, 200)
				return
			}
			if(!stats){
				utils.error('no stats were returned from the etcd server')
				setTimeout(masterLoop, 200)
				return
			}
			console.log('leader stats')
			console.dir(stats)
			if(stats.leader==vikingHostname){
				runLeader()
			}
			setTimeout(masterLoop, 2000)
		})
	}

	setTimeout(function(){

		hostMonitor.start(function(){
			utils.log('host monitor', 'running')
		})

		setTimeout(function(){

			if(config.master){
				masterLoop()
			}

			runSlave()

		}, 500)
	}, 500)

}
<commit_msg>remove logging each host hit<commit_after>// this runs on all vikings with an etcd client to listen for events
var etcdjs = require('etcdjs')
var config = require('./config')()
var utils = require('component-consoler');
var HostMonitor = require('./hostmonitor')

module.exports = function(etcdhosts){
	var etcd = etcdjs(etcdhosts)

	var vikingHostname = config.network.hostname

	var hostMonitor = HostMonitor(config, etcd)

	var leaderRunning = false

	// this will be trigged in another viking master if the etcd leadership changes
	function runLeader(){
		if(leaderRunning) return
		utils.log('leader', 'starting')
		leaderRunning = true

		hostMonitor.leader(function(){
			// the leader module has all the servies like registry and git push
			var leader = require('./leader')(config, etcd)
			leader.start(function(err){
				if(err){
					console.error('ERROR STARTING LEADER ' + err)
					return
				}

				utils.log('leader', 'running')
			})
		})
	}

	function runSlave(){
		var slave = require('./slave')(config, etcd)
		slave.start(function(err){
			if(err){
				utils.error('ERROR STARTING SLAVE ' + err)
				return
			}

			utils.log('slave', 'running')
		})
	}

	function masterLoop(){
		etcd.stats.leader(function(err, stats){
			if(err){
				//utils.error(err)
				setTimeout(masterLoop, 200)
				return
			}
			if(!stats){
				utils.error('no stats were returned from the etcd server')
				setTimeout(masterLoop, 200)
				return
			}

			if(stats.leader==vikingHostname){
				runLeader()
			}
			setTimeout(masterLoop, 2000)
		})
	}

	setTimeout(function(){

		hostMonitor.start(function(){
			utils.log('host monitor', 'running')
		})

		setTimeout(function(){

			if(config.master){
				masterLoop()
			}

			runSlave()

		}, 500)
	}, 500)

}
<|endoftext|>


<commit_before>// Copyright 2015-2020, University of Colorado Boulder

/**
 * Warning displayed when we have to fall back to Canvas
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */

import inherit from '../../phet-core/js/inherit.js';
import openPopup from '../../phet-core/js/openPopup.js';
import HBox from '../../scenery/js/nodes/HBox.js';
import Text from '../../scenery/js/nodes/Text.js';
import VBox from '../../scenery/js/nodes/VBox.js';
import FontAwesomeNode from '../../sun/js/FontAwesomeNode.js';
import PhetFont from './PhetFont.js';
import sceneryPhetStrings from './sceneryPhetStrings.js';
import sceneryPhet from './sceneryPhet.js';

const webglWarningBodyString = sceneryPhetStrings.webglWarning.body;
const webglWarningTitleString = sceneryPhetStrings.webglWarning.title;

/**
 * @constructor
 */
function CanvasWarningNode() {
  HBox.call( this, {
    children: [
      new FontAwesomeNode( 'warning_sign', {
        fill: '#E87600', // "safety orange", according to Wikipedia
        scale: 0.6
      } ),
      new VBox( {
        children: [
          new Text( webglWarningTitleString, {
            font: new PhetFont( 14 ),
            fill: '#ddd'
          } ),
          new Text( webglWarningBodyString, {
            font: new PhetFont( 10 ),
            fill: '#999'
          } )
        ],
        spacing: 3,
        align: 'left'
      } )
    ],
    spacing: 12,
    align: 'center',
    cursor: 'pointer'
  } );

  this.mouseArea = this.touchArea = this.localBounds;

  this.addInputListener( {
    up: function() {
      openPopup( 'http://phet.colorado.edu/webgl-disabled-page?simLocale=' + phet.joist.sim.locale );
    }
  } );
}

sceneryPhet.register( 'CanvasWarningNode', CanvasWarningNode );

inherit( HBox, CanvasWarningNode );
export default CanvasWarningNode;<commit_msg>convert CanvasWarningNode to ES6, https://github.com/phetsims/tasks/issues/1044<commit_after>// Copyright 2015-2020, University of Colorado Boulder

/**
 * Warning displayed when we have to fall back to Canvas
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */

import openPopup from '../../phet-core/js/openPopup.js';
import HBox from '../../scenery/js/nodes/HBox.js';
import Text from '../../scenery/js/nodes/Text.js';
import VBox from '../../scenery/js/nodes/VBox.js';
import FontAwesomeNode from '../../sun/js/FontAwesomeNode.js';
import PhetFont from './PhetFont.js';
import sceneryPhet from './sceneryPhet.js';
import sceneryPhetStrings from './sceneryPhetStrings.js';

class CanvasWarningNode extends HBox {

  constructor() {

    super( {
      children: [
        new FontAwesomeNode( 'warning_sign', {
          fill: '#E87600', // "safety orange", according to Wikipedia
          scale: 0.6
        } ),
        new VBox( {
          children: [
            new Text( sceneryPhetStrings.webglWarning.title, {
              font: new PhetFont( 14 ),
              fill: '#ddd'
            } ),
            new Text( sceneryPhetStrings.webglWarning.body, {
              font: new PhetFont( 10 ),
              fill: '#999'
            } )
          ],
          spacing: 3,
          align: 'left'
        } )
      ],
      spacing: 12,
      align: 'center',
      cursor: 'pointer'
    } );

    this.mouseArea = this.touchArea = this.localBounds;

    this.addInputListener( {
      up: function() {
        openPopup( 'http://phet.colorado.edu/webgl-disabled-page?simLocale=' + phet.joist.sim.locale );
      }
    } );
  }
}

sceneryPhet.register( 'CanvasWarningNode', CanvasWarningNode );
export default CanvasWarningNode;<|endoftext|>


<commit_before>// Copyright 2014-2017, University of Colorado Boulder

/**
 * Horizontal bar placed above something that can be expanded/collapsed.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // modules
  var ExpandCollapseButton = require( 'SUN/ExpandCollapseButton' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Rectangle = require( 'SCENERY/nodes/Rectangle' );
  var Shape = require( 'KITE/Shape' );
  var sun = require( 'SUN/sun' );
  var Tandem = require( 'TANDEM/Tandem' );

  /**
   * @param {Node} titleNode
   * @param {Property.<boolean>} expandedProperty
   * @param {Object} [options]
   * @constructor
   */
  function ExpandCollapseBar( titleNode, expandedProperty, options ) {

    options = _.extend( {
      buttonLength: 15,
      minWidth: 1, // minimum width of the bar
      minHeight: 1, // minimum height of the bar
      cornerRadius: 6,
      xMargin: 10,
      yMargin: 8,
      xSpacing: 10,
      barFill: 'white',
      barStroke: 'black',
      barLineWidth: 1,
      tandem: Tandem.required
    }, options );

    Node.call( this );

    // expand/collapse button
    var button = new ExpandCollapseButton( expandedProperty, {
      sideLength: options.buttonLength,
      tandem: options.tandem.createTandem( 'button' )
    } );
    button.touchArea = Shape.bounds( button.localBounds.dilatedXY( 10, 10 ) );

    // bar
    var barWidth = Math.max( options.minWidth, titleNode.width + button.width + options.xSpacing + ( 2 * options.xMargin ) );
    var barHeight = Math.max( options.minHeight, Math.max( titleNode.height, button.height ) + ( 2 * options.yMargin ) );
    var barNode = new Rectangle( 0, 0, barWidth, barHeight, options.cornerRadius, options.cornerRadius, {
      fill: options.barFill,
      stroke: options.barStroke,
      lineWidth: options.barLineWidth
    } );

    // rendering order
    this.addChild( barNode );
    this.addChild( titleNode );
    this.addChild( button );

    // layout
    titleNode.left = barNode.left + options.xMargin;
    titleNode.centerY = barNode.centerY;
    button.right = barNode.right - options.xMargin;
    button.centerY = barNode.centerY;

    this.mutate( { tandem: options.tandem } );
  }

  sun.register( 'ExpandCollapseBar', ExpandCollapseBar );

  return inherit( Node, ExpandCollapseBar );
} );
<commit_msg>Pass options to Node constructor, see https://github.com/phetsims/tandem/issues/44<commit_after>// Copyright 2014-2017, University of Colorado Boulder

/**
 * Horizontal bar placed above something that can be expanded/collapsed.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // modules
  var ExpandCollapseButton = require( 'SUN/ExpandCollapseButton' );
  var inherit = require( 'PHET_CORE/inherit' );
  var IOObject = require( 'TANDEM/IOObject' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Rectangle = require( 'SCENERY/nodes/Rectangle' );
  var Shape = require( 'KITE/Shape' );
  var sun = require( 'SUN/sun' );
  var Tandem = require( 'TANDEM/Tandem' );

  /**
   * @param {Node} titleNode
   * @param {Property.<boolean>} expandedProperty
   * @param {Object} [options]
   * @constructor
   */
  function ExpandCollapseBar( titleNode, expandedProperty, options ) {

    options = _.extend( {
      buttonLength: 15,
      minWidth: 1, // minimum width of the bar
      minHeight: 1, // minimum height of the bar
      cornerRadius: 6,
      xMargin: 10,
      yMargin: 8,
      xSpacing: 10,
      barFill: 'white',
      barStroke: 'black',
      barLineWidth: 1,
      tandem: Tandem.required
    }, options );

    Node.call( this, IOObject.getOptions( options ) );

    // expand/collapse button
    var button = new ExpandCollapseButton( expandedProperty, {
      sideLength: options.buttonLength,
      tandem: options.tandem.createTandem( 'button' )
    } );
    button.touchArea = Shape.bounds( button.localBounds.dilatedXY( 10, 10 ) );

    // bar
    var barWidth = Math.max( options.minWidth, titleNode.width + button.width + options.xSpacing + ( 2 * options.xMargin ) );
    var barHeight = Math.max( options.minHeight, Math.max( titleNode.height, button.height ) + ( 2 * options.yMargin ) );
    var barNode = new Rectangle( 0, 0, barWidth, barHeight, options.cornerRadius, options.cornerRadius, {
      fill: options.barFill,
      stroke: options.barStroke,
      lineWidth: options.barLineWidth
    } );

    // rendering order
    this.addChild( barNode );
    this.addChild( titleNode );
    this.addChild( button );

    // layout
    titleNode.left = barNode.left + options.xMargin;
    titleNode.centerY = barNode.centerY;
    button.right = barNode.right - options.xMargin;
    button.centerY = barNode.centerY;
  }

  sun.register( 'ExpandCollapseBar', ExpandCollapseBar );

  return inherit( Node, ExpandCollapseBar );
} );
<|endoftext|>


<commit_before>var OfflinePlugin = require('../../');
var path = require('path');

module.exports = {
  entry: {
    main: 'main.js'
  },

  output: {
    path: path.join(__dirname, 'output')
  },

  plugins: [
    new OfflinePlugin()
  ],

  resolve: {
    root: path.join(__dirname),
    extensions: ['', '.js']
  }
};<commit_msg>Fix test<commit_after>var OfflinePlugin = require('../../');
var path = require('path');

module.exports = {
  entry: {
    main: 'main.js'
  },

  output: {
    path: path.join(__dirname, 'output'),
    filename: '[name].js',
  },

  plugins: [
    new OfflinePlugin()
  ],

  resolve: {
    root: path.join(__dirname),
    extensions: ['', '.js']
  }
};<|endoftext|>


<commit_before>'use strict';

var mongoose = require('mongoose'),
  Person = mongoose.model('Person');

/**
 * Create a Person
 */
exports.create = function (req, res) {
  var person = new Person(req.body);
  person.user = req.user;

  person.save(function (err) {
    if (err) {
      return res.status(404).send({
        message: err.message
      });
    } else {
      res.json(person);
    }
  });
};

/**
 * Show the current Person
 */
exports.read = function (req, res) {
  var person = req.person ? req.person.toJSON() : {};
  res.json(person);
};

/**
 * Update a Person
 */
exports.update = function (req, res) {
  var person = req.person;
  person.full_name     = req.body.full_name;
  person.url           = req.body.url;
  person.phone         = req.body.phone;
  person.email         = req.body.email;
  person.job           = req.body.job;
  person.location_safe = req.body.location_safe;
  person.notes         = req.body.notes;
  person.keywords      = req.body.keywords;

  person.save(function (err) {
    if (err) {
      return res.status(400).send({
        message: err.message
      });
    } else {
      res.json(person);
    }
  });
};

/**
 * Delete a Person
 */
exports.delete = function (req, res) {
  var person = req.person;

  person.remove(function (err) {
    if (err) {
      return res.status(400).send({
        message: err.message
      });
    } else {
      res.json(person);
    }
  });
};

/**
 * List of People
 */
exports.list = function (req, res) {
  var search = req.query.keywords ? {'keywords': new RegExp(req.query.keywords, 'i')} : {};
  var limit = req.query.limit || 100;

  Person.find(search).sort('-created').exec(function (err, people) {
    if (err) {
      return res.status(400).send({
        message: err.message
      });
    } else {
      res.json(people);
    }
  });
};

/**
 * Person Middleware
 */
exports.personByID = function (req, res, next, id) {
  if (!mongoose.Types.ObjectId.isValid(id)) {
    return res.status(400).send({
      message: 'Person is invalid'
    });
  }

  Person.findById(id).exec(function (err, person) {
    if (err) {
      return next(err);
    } else if (!person) {
      return res.status(404).send({
        message: 'No person with that identifier has been found'
      });
    }
    req.person = person;
    next();
  });
};

<commit_msg>Don't search if nothing entered<commit_after>'use strict';

var mongoose = require('mongoose'),
  Person = mongoose.model('Person');

/**
 * Create a Person
 */
exports.create = function (req, res) {
  var person = new Person(req.body);
  person.user = req.user;

  person.save(function (err) {
    if (err) {
      return res.status(404).send({
        message: err.message
      });
    } else {
      res.json(person);
    }
  });
};

/**
 * Show the current Person
 */
exports.read = function (req, res) {
  var person = req.person ? req.person.toJSON() : {};
  res.json(person);
};

/**
 * Update a Person
 */
exports.update = function (req, res) {
  var person = req.person;
  person.full_name     = req.body.full_name;
  person.url           = req.body.url;
  person.phone         = req.body.phone;
  person.email         = req.body.email;
  person.job           = req.body.job;
  person.location_safe = req.body.location_safe;
  person.notes         = req.body.notes;
  person.keywords      = req.body.keywords;

  person.save(function (err) {
    if (err) {
      return res.status(400).send({
        message: err.message
      });
    } else {
      res.json(person);
    }
  });
};

/**
 * Delete a Person
 */
exports.delete = function (req, res) {
  var person = req.person;

  person.remove(function (err) {
    if (err) {
      return res.status(400).send({
        message: err.message
      });
    } else {
      res.json(person);
    }
  });
};

/**
 * List of People
 */
exports.list = function (req, res) {
  if (!req.query.keywords) {
    return res.status(400).send({
      message: 'Search for something that isn\'t nothing, or whitespace'
    });
  }
  var search = req.query.keywords ? {'keywords': new RegExp(req.query.keywords, 'i')} : {};
  var limit = 100;

  Person.find(search).sort('-created').exec(function (err, people) {
    if (err) {
      return res.status(400).send({
        message: err.message
      });
    } else {
      res.json(people);
    }
  });
};

/**
 * Person Middleware
 */
exports.personByID = function (req, res, next, id) {
  if (!mongoose.Types.ObjectId.isValid(id)) {
    return res.status(400).send({
      message: 'Person is invalid'
    });
  }

  Person.findById(id).exec(function (err, person) {
    if (err) {
      return next(err);
    } else if (!person) {
      return res.status(404).send({
        message: 'No person with that identifier has been found'
      });
    }
    req.person = person;
    next();
  });
};

<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.medusa',
  name: 'MedusaAdapterDAO',
  extends: 'foam.dao.ProxyDAO',

  implements: [
//    'foam.nanos.boot.NSpecAware',
  ],

  documentation: `Create a medusa entry for argument model.`,

  javaImports: [
    'foam.core.FObject',
    'foam.dao.DOP',
    'foam.lib.formatter.FObjectFormatter',
    'foam.lib.formatter.JSONFObjectFormatter',
    'foam.nanos.logger.PrefixLogger',
    'foam.nanos.logger.Logger',
    'foam.nanos.pm.PM',
    'foam.util.SafetyUtil'
  ],

  properties: [
    {
      name: 'nSpec',
      class: 'FObjectProperty',
      of: 'foam.nanos.boot.NSpec'
    },
    {
      name: 'medusaEntryDAO',
      class: 'FObjectProperty',
      of: 'foam.dao.DAO',
      javaFactory: 'return (foam.dao.DAO) getX().get("localMedusaEntryDAO");'
    },
    {
      name: 'clientDAO',
      class: 'FObjectProperty',
      of: 'foam.dao.DAO',
      javaFactory: `
      return new foam.nanos.medusa.ClusterClientDAO.Builder(getX())
        .setNSpec(getNSpec())
        .setDelegate(new foam.dao.NullDAO(getX(), getDelegate().getOf()))
        .build();
      `
    },
    {
      name: 'logger',
      class: 'FObjectProperty',
      of: 'foam.nanos.logger.Logger',
      visibility: 'HIDDEN',
      javaFactory: `
        return new PrefixLogger(new Object[] {
          this.getClass().getSimpleName(),
          getNSpec().getName()
        }, (Logger) getX().get("logger"));
      `
    }
  ],

  axioms: [
    {
      name: 'javaExtras',
      buildJavaClass: function(cls) {
        cls.extras.push(foam.java.Code.create({
          data: `
  protected static final ThreadLocal<FObjectFormatter> formatter_ = new ThreadLocal<FObjectFormatter>() {
    @Override
    protected JSONFObjectFormatter initialValue() {
      JSONFObjectFormatter formatter = new JSONFObjectFormatter();
      formatter.setQuoteKeys(false); // default
      formatter.setOutputShortNames(true); // default
      formatter.setOutputDefaultValues(true);
      formatter.setOutputClassNames(true); // default
      formatter.setOutputDefaultClassNames(true); // default
      formatter.setOutputReadableDates(false);
      formatter.setPropertyPredicate(new foam.lib.StoragePropertyPredicate());
      return formatter;
    }

    @Override
    public FObjectFormatter get() {
      FObjectFormatter formatter = super.get();
      formatter.reset();
      return formatter;
    }
  };
          `
        }));
      }
    }
  ],

  methods: [
    {
      documentation: `
      1. If primary mediator, then delegate to medusaAdapter, accept result.
      2. If secondary mediator, proxy to next 'server', find result.
      3. If not mediator, proxy to the next 'server', put result.`,
      name: 'put_',
      javaCode: `
      if ( obj instanceof Clusterable &&
           ! ((Clusterable) obj).getClusterable() ) {
        getLogger().debug("put", "not clusterable", obj.getProperty("id"));
        return getDelegate().put_(x, obj);
      }

      ClusterConfigSupport support = (ClusterConfigSupport) x.get("clusterConfigSupport");
      ClusterConfig config = support.getConfig(x, support.getConfigId());

      if ( config.getIsPrimary() ) {
        // Primary instance - put to MDAO (delegate)

        ClusterCommand cmd = null;
        if ( obj instanceof ClusterCommand ) {
          cmd = (ClusterCommand) obj;
          obj = cmd.getData();
        }

        getLogger().debug("put", "primary", obj.getClass().getSimpleName());
        FObject old = getDelegate().find_(x, obj.getProperty("id"));
        FObject nu = getDelegate().put_(x, obj);
        String data = data(x, nu, old, DOP.PUT);
        if ( SafetyUtil.isEmpty(data) ) {
          getLogger().info("put", "primary", obj.getProperty("id"), "data", "no delta");
        } else {
          MedusaEntry entry = (MedusaEntry) submit(x, data, DOP.PUT);
          if ( cmd != null ) {
            getLogger().debug("put", "primary", obj.getProperty("id"), "setMedusaEntryId", entry.toSummary(), entry.getId().toString());
            cmd.setMedusaEntryId(entry.getId());
            cmd.setData(nu);
          }
        }
        if ( cmd != null ) {
          return cmd;
        }
        return nu;
      }

      ClusterCommand cmd = new ClusterCommand(x, getNSpec().getName(), DOP.PUT, obj);
      getLogger().debug("put", "client", "cmd", obj.getProperty("id"), "send");
      cmd = (ClusterCommand) getClientDAO().cmd_(x, cmd);
      getLogger().debug("put", "client", "cmd", obj.getProperty("id"), "receive", cmd.getMedusaEntryId());

      FObject result = cmd.getData();
      if ( result != null ) {
        getLogger().debug("put", "delegate", result.getProperty("id"));
        FObject nu = getDelegate().put_(x, result);
        if ( nu == null ) {
          getLogger().debug("put", "delegate", "returned null");
        } else {
          FObject f = getDelegate().find_(x, nu.getProperty("id"));
          if ( f == null ) {
            getLogger().debug("put", "delegate", "find null");
            getLogger().debug("put", "delegate", "dao", getDelegate().getClass().getSimpleName());
          }
        }
        return nu;
//        return getDelegate().put_(x, result);
      }
      getLogger().warning("put", obj.getProperty("id"), "result,null");
      return result;
      `
    },
    {
      name: 'remove_',
      javaCode: `
      // INCOMPLETE.
      if ( obj instanceof Clusterable &&
           ! ((Clusterable) obj).getClusterable() ) {
        return getDelegate().remove_(x, obj);
      }

      if ( obj instanceof ClusterCommand ) {
        obj = ((ClusterCommand) obj).getData();
      }

      ClusterConfigSupport support = (ClusterConfigSupport) x.get("clusterConfigSupport");
      ClusterConfig config = support.getConfig(x, support.getConfigId());
      if ( config.getIsPrimary() ) {
        getDelegate().remove_(x, obj);
        return submit(x, data(x, obj, null, DOP.REMOVE), DOP.REMOVE);
      }

      FObject result = getClientDAO().remove_(x, obj);
      if ( config.getType() == MedusaType.MEDIATOR ) {
        return result;
      }
      return getDelegate().remove_(x, result);
      `
    },
    {
      name: 'cmd_',
      javaCode: `
      getLogger().debug("cmd");
      if ( foam.dao.MDAO.GET_MDAO_CMD.equals(obj) ) {
        return this;
        // return getDelegate().cmd_(x, obj);
      }
      if ( obj instanceof ClusterCommand ) {
        ClusterConfigSupport support = (ClusterConfigSupport) x.get("clusterConfigSupport");
        ClusterConfig config = support.getConfig(x, support.getConfigId());
        ClusterCommand cmd = (ClusterCommand) obj;

        if ( config.getIsPrimary() ) {
          getLogger().debug("cmd", "ClusterCommand", "primary");
          if ( DOP.PUT == cmd.getDop() ) {
            return put_(x, cmd);
          } else {
            getLogger().warning("Unsupported operation", cmd.getDop().getLabel());
            throw new UnsupportedOperationException(cmd.getDop().getLabel());
          }
        }

        getLogger().debug("cmd", "ClusterCommand", "non-primary");
        cmd = (ClusterCommand) getClientDAO().cmd_(x, obj);

        if ( config.getType() == MedusaType.MEDIATOR ) {
          MedusaEntryId id = cmd.getMedusaEntryId();
          if ( id != null ) {
            MedusaRegistry registry = (MedusaRegistry) x.get("medusaRegistry");
            registry.wait(x, id.getIndex());
          } else {
            getLogger().debug("cmd", "ClusterCommand", "medusaEntry", "null");
          }
        }
        getLogger().debug("cmd", "ClusterCommand", "return");
        return cmd;
      }
      getLogger().debug("cmd", "getClientDAO");
      return getClientDAO().cmd_(x, obj);
      `
    },
    {
      name: 'data',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'FObject'
        },
        {
          name: 'old',
          type: 'FObject'
        },
        {
          name: 'dop',
          type: 'foam.dao.DOP'
        }
      ],
      type: 'String',
      javaCode: `
      PM pm = PM.create(x, this.getOwnClassInfo(), "data");
      String data = null;
      try {
        FObjectFormatter formatter = formatter_.get();
        if ( old != null ) {
          formatter.outputDelta(old, obj);
        } else {
          formatter.output(obj);
        }
        data = formatter.builder().toString();
      } finally {
        pm.log(x);
      }
      return data;
      `
    },
    {
      name: 'submit',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'data',
          type: 'String'
        },
        {
          name: 'dop',
          type: 'foam.dao.DOP'
        }
      ],
      type: 'FObject',
      javaCode: `
      PM pm = PM.create(x, this.getOwnClassInfo(), "submit");
      MedusaEntry entry = x.create(MedusaEntry.class);
      try {
        DaggerService dagger = (DaggerService) x.get("daggerService");
        entry = dagger.link(x, entry);
        entry.setNSpecName(getNSpec().getName());
        entry.setDop(dop);
        entry.setData(data);

        MedusaRegistry registry = (MedusaRegistry) x.get("medusaRegistry");
        registry.register(x, entry.getIndex());
        entry = (MedusaEntry) getMedusaEntryDAO().put_(x, entry);
        registry.wait(x, entry.getIndex());
        return entry;
      } catch (Throwable t) {
        getLogger().error("submit", entry.toSummary(), t.getMessage(), t);
        throw t;
      } finally {
        pm.log(x);
      }
      `
    }
  ]
});
<commit_msg>info to debug<commit_after>/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.medusa',
  name: 'MedusaAdapterDAO',
  extends: 'foam.dao.ProxyDAO',

  implements: [
//    'foam.nanos.boot.NSpecAware',
  ],

  documentation: `Create a medusa entry for argument model.`,

  javaImports: [
    'foam.core.FObject',
    'foam.dao.DOP',
    'foam.lib.formatter.FObjectFormatter',
    'foam.lib.formatter.JSONFObjectFormatter',
    'foam.nanos.logger.PrefixLogger',
    'foam.nanos.logger.Logger',
    'foam.nanos.pm.PM',
    'foam.util.SafetyUtil'
  ],

  properties: [
    {
      name: 'nSpec',
      class: 'FObjectProperty',
      of: 'foam.nanos.boot.NSpec'
    },
    {
      name: 'medusaEntryDAO',
      class: 'FObjectProperty',
      of: 'foam.dao.DAO',
      javaFactory: 'return (foam.dao.DAO) getX().get("localMedusaEntryDAO");'
    },
    {
      name: 'clientDAO',
      class: 'FObjectProperty',
      of: 'foam.dao.DAO',
      javaFactory: `
      return new foam.nanos.medusa.ClusterClientDAO.Builder(getX())
        .setNSpec(getNSpec())
        .setDelegate(new foam.dao.NullDAO(getX(), getDelegate().getOf()))
        .build();
      `
    },
    {
      name: 'logger',
      class: 'FObjectProperty',
      of: 'foam.nanos.logger.Logger',
      visibility: 'HIDDEN',
      javaFactory: `
        return new PrefixLogger(new Object[] {
          this.getClass().getSimpleName(),
          getNSpec().getName()
        }, (Logger) getX().get("logger"));
      `
    }
  ],

  axioms: [
    {
      name: 'javaExtras',
      buildJavaClass: function(cls) {
        cls.extras.push(foam.java.Code.create({
          data: `
  protected static final ThreadLocal<FObjectFormatter> formatter_ = new ThreadLocal<FObjectFormatter>() {
    @Override
    protected JSONFObjectFormatter initialValue() {
      JSONFObjectFormatter formatter = new JSONFObjectFormatter();
      formatter.setQuoteKeys(false); // default
      formatter.setOutputShortNames(true); // default
      formatter.setOutputDefaultValues(true);
      formatter.setOutputClassNames(true); // default
      formatter.setOutputDefaultClassNames(true); // default
      formatter.setOutputReadableDates(false);
      formatter.setPropertyPredicate(new foam.lib.StoragePropertyPredicate());
      return formatter;
    }

    @Override
    public FObjectFormatter get() {
      FObjectFormatter formatter = super.get();
      formatter.reset();
      return formatter;
    }
  };
          `
        }));
      }
    }
  ],

  methods: [
    {
      documentation: `
      1. If primary mediator, then delegate to medusaAdapter, accept result.
      2. If secondary mediator, proxy to next 'server', find result.
      3. If not mediator, proxy to the next 'server', put result.`,
      name: 'put_',
      javaCode: `
      if ( obj instanceof Clusterable &&
           ! ((Clusterable) obj).getClusterable() ) {
        getLogger().debug("put", "not clusterable", obj.getProperty("id"));
        return getDelegate().put_(x, obj);
      }

      ClusterConfigSupport support = (ClusterConfigSupport) x.get("clusterConfigSupport");
      ClusterConfig config = support.getConfig(x, support.getConfigId());

      if ( config.getIsPrimary() ) {
        // Primary instance - put to MDAO (delegate)

        ClusterCommand cmd = null;
        if ( obj instanceof ClusterCommand ) {
          cmd = (ClusterCommand) obj;
          obj = cmd.getData();
        }

        getLogger().debug("put", "primary", obj.getClass().getSimpleName());
        FObject old = getDelegate().find_(x, obj.getProperty("id"));
        FObject nu = getDelegate().put_(x, obj);
        String data = data(x, nu, old, DOP.PUT);
        if ( SafetyUtil.isEmpty(data) ) {
          getLogger().debug("put", "primary", obj.getProperty("id"), "data", "no delta");
        } else {
          MedusaEntry entry = (MedusaEntry) submit(x, data, DOP.PUT);
          if ( cmd != null ) {
            getLogger().debug("put", "primary", obj.getProperty("id"), "setMedusaEntryId", entry.toSummary(), entry.getId().toString());
            cmd.setMedusaEntryId(entry.getId());
            cmd.setData(nu);
          }
        }
        if ( cmd != null ) {
          return cmd;
        }
        return nu;
      }

      ClusterCommand cmd = new ClusterCommand(x, getNSpec().getName(), DOP.PUT, obj);
      getLogger().debug("put", "client", "cmd", obj.getProperty("id"), "send");
      cmd = (ClusterCommand) getClientDAO().cmd_(x, cmd);
      getLogger().debug("put", "client", "cmd", obj.getProperty("id"), "receive", cmd.getMedusaEntryId());

      FObject result = cmd.getData();
      if ( result != null ) {
        getLogger().debug("put", "delegate", result.getProperty("id"));
        FObject nu = getDelegate().put_(x, result);
        if ( nu == null ) {
          getLogger().debug("put", "delegate", "returned null");
        } else {
          FObject f = getDelegate().find_(x, nu.getProperty("id"));
          if ( f == null ) {
            getLogger().debug("put", "delegate", "find null");
            getLogger().debug("put", "delegate", "dao", getDelegate().getClass().getSimpleName());
          }
        }
        return nu;
//        return getDelegate().put_(x, result);
      }
      getLogger().warning("put", obj.getProperty("id"), "result,null");
      return result;
      `
    },
    {
      name: 'remove_',
      javaCode: `
      // INCOMPLETE.
      if ( obj instanceof Clusterable &&
           ! ((Clusterable) obj).getClusterable() ) {
        return getDelegate().remove_(x, obj);
      }

      if ( obj instanceof ClusterCommand ) {
        obj = ((ClusterCommand) obj).getData();
      }

      ClusterConfigSupport support = (ClusterConfigSupport) x.get("clusterConfigSupport");
      ClusterConfig config = support.getConfig(x, support.getConfigId());
      if ( config.getIsPrimary() ) {
        getDelegate().remove_(x, obj);
        return submit(x, data(x, obj, null, DOP.REMOVE), DOP.REMOVE);
      }

      FObject result = getClientDAO().remove_(x, obj);
      if ( config.getType() == MedusaType.MEDIATOR ) {
        return result;
      }
      return getDelegate().remove_(x, result);
      `
    },
    {
      name: 'cmd_',
      javaCode: `
      getLogger().debug("cmd");
      if ( foam.dao.MDAO.GET_MDAO_CMD.equals(obj) ) {
        return this;
        // return getDelegate().cmd_(x, obj);
      }
      if ( obj instanceof ClusterCommand ) {
        ClusterConfigSupport support = (ClusterConfigSupport) x.get("clusterConfigSupport");
        ClusterConfig config = support.getConfig(x, support.getConfigId());
        ClusterCommand cmd = (ClusterCommand) obj;

        if ( config.getIsPrimary() ) {
          getLogger().debug("cmd", "ClusterCommand", "primary");
          if ( DOP.PUT == cmd.getDop() ) {
            return put_(x, cmd);
          } else {
            getLogger().warning("Unsupported operation", cmd.getDop().getLabel());
            throw new UnsupportedOperationException(cmd.getDop().getLabel());
          }
        }

        getLogger().debug("cmd", "ClusterCommand", "non-primary");
        cmd = (ClusterCommand) getClientDAO().cmd_(x, obj);

        if ( config.getType() == MedusaType.MEDIATOR ) {
          MedusaEntryId id = cmd.getMedusaEntryId();
          if ( id != null ) {
            MedusaRegistry registry = (MedusaRegistry) x.get("medusaRegistry");
            registry.wait(x, id.getIndex());
          } else {
            getLogger().debug("cmd", "ClusterCommand", "medusaEntry", "null");
          }
        }
        getLogger().debug("cmd", "ClusterCommand", "return");
        return cmd;
      }
      getLogger().debug("cmd", "getClientDAO");
      return getClientDAO().cmd_(x, obj);
      `
    },
    {
      name: 'data',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'FObject'
        },
        {
          name: 'old',
          type: 'FObject'
        },
        {
          name: 'dop',
          type: 'foam.dao.DOP'
        }
      ],
      type: 'String',
      javaCode: `
      PM pm = PM.create(x, this.getOwnClassInfo(), "data");
      String data = null;
      try {
        FObjectFormatter formatter = formatter_.get();
        if ( old != null ) {
          formatter.outputDelta(old, obj);
        } else {
          formatter.output(obj);
        }
        data = formatter.builder().toString();
      } finally {
        pm.log(x);
      }
      return data;
      `
    },
    {
      name: 'submit',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'data',
          type: 'String'
        },
        {
          name: 'dop',
          type: 'foam.dao.DOP'
        }
      ],
      type: 'FObject',
      javaCode: `
      PM pm = PM.create(x, this.getOwnClassInfo(), "submit");
      MedusaEntry entry = x.create(MedusaEntry.class);
      try {
        DaggerService dagger = (DaggerService) x.get("daggerService");
        entry = dagger.link(x, entry);
        entry.setNSpecName(getNSpec().getName());
        entry.setDop(dop);
        entry.setData(data);

        MedusaRegistry registry = (MedusaRegistry) x.get("medusaRegistry");
        registry.register(x, entry.getIndex());
        entry = (MedusaEntry) getMedusaEntryDAO().put_(x, entry);
        registry.wait(x, entry.getIndex());
        return entry;
      } catch (Throwable t) {
        getLogger().error("submit", entry.toSummary(), t.getMessage(), t);
        throw t;
      } finally {
        pm.log(x);
      }
      `
    }
  ]
});
<|endoftext|>


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

"use strict"

const install = require("./install"),
    path = require("path"),
    unzip = require('unzipper'),
    fs = require('fs'),
    request = require('superagent'),
    packageJsonPath = path.join(__dirname, "..", "package.json"),
    binPath = "./bin";

var downloadAndExtract = function(version) {
    console.log(`Fetching download url for Gauge version ${version}`);
    let url = install.getBinaryUrl(version);
    let gaugeExecutable = process.platform === "win32" ? "gauge.exe" : "gauge"
    console.log(`Downloading ${url} to ${binPath}`);
    return unzip.Open.url(request, url).then((d) => {
        return new Promise((resolve, reject) => {
            d.files[0].stream()
            .pipe(fs.createWriteStream(path.join(binPath, gaugeExecutable)))
            .on('error',reject)
            .on('finish',resolve)
        });
    });
}

install.getVersion(packageJsonPath)
.then((v) => downloadAndExtract(v.split('-')[0]))
.catch((e) => console.error(e));<commit_msg>correct download and extract gauge-zip, fixes #1666 (#1669)<commit_after>#!/usr/bin/env node

"use strict"

const install = require("./install"),
    path = require("path"),
    unzip = require('unzipper'),
    request = require('superagent'),
    packageJsonPath = path.join(__dirname, "..", "package.json"),
    binPath = "./bin";

var downloadAndExtract = function(version) {
    console.log(`Fetching download url for Gauge version ${version}`);
    let url = install.getBinaryUrl(version);
    console.log(`Downloading ${url} to ${binPath}`);
    return new Promise((resolve, reject) => {
        try {
            request.get(url).pipe(unzip.Extract({ path: path.normalize(binPath) }));
            resolve();
        } catch (error) {
            reject(error);
        }
    })
}

install.getVersion(packageJsonPath)
.then((v) => downloadAndExtract(v.split('-')[0]))
.catch((e) => console.error(e));<|endoftext|>


<commit_before>/*global require*/
/*global exports*/
/*global module*/
/*global console*/
/*jslint nomen: true*/

(function () {

    'use strict';

    var League = {},
        util = require('./util'),
        authKey,
        region = 'na',
        endpoint = 'http://prod.api.pvp.net/api/lol',
        championUrl = '/v1.1/champion',
        gameUrl = '/v1.2/game/by-summoner',
        leagueUrl = '/v2.2/league/by-summoner',
        statsUrl = '/v1.2/stats/by-summoner',
        summonerUrl = '/v1.2/summoner',
        teamUrl = '/v2.2/team/by-summoner';

    League.Stats = {};
    League.Summoner = {};

    League.init = function (key, region) {
        authKey = key;
        if (region) {
            this.region = region;
        }
    };

    League.getRegions = function (callback) {
        callback(null, {
            'na': 'North America',
            'euw': 'Europe West',
            'eune': 'Europe Nordic and East'
        });
    };

    League.getQueues = function (callback) {
        callback(null, {
            2: 'Normal 5v5 Blind Pick',
            4: 'Ranked Solo 5v5',
            7: 'Coop vs AI 5v5',
            8: 'Normal 3v3',
            14: 'Normal 5v5 Draft Pick',
            16: 'Dominion 5v5 Blind Pick',
            17: 'Dominion 5v5 Draft Pick',
            25: 'Dominion Coop vs AI',
            41: 'Ranked Team 3v3',
            42: 'Ranked Team 5v5',
            52: 'Twisted Treeline Coop vs AI',
            65: 'ARAM',
            67: 'ARAM Coop vs AI'
        });
    };

    League.getMapNames = function (callback) {
        callback(null, {
            1: "Summoner's Rift Summer Variant",
            2: "Summoner's Rift Autumn Variant",
            3: 'The Proving Grounds',
            4: 'Twisted Treeline Original Version',
            8: 'The Crystal Scar',
            10: 'Twisted Treeline Current Version',
            12: 'Howling Abyss'
        });
    };

    League.getChampions = function (freeToPlay, regionOrFunction, callback) {
        var url,
            freetoPlayQuery = '',
            regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback);

        if (!(freeToPlay === null || typeof (freetoPlayQuery) === 'boolean')) {
            console.log('Invalid query parameter for freeToPlay: ' + freeToPlay);
        }

        if (freeToPlay) {
            freetoPlayQuery = 'freeToPlay=true&';
        }

        url = util.craftUrl(endpoint, regionAndFunc.region, championUrl + '?' + freetoPlayQuery, authKey);
        util.makeRequest(url, 'Error getting champions: ', 'champions', regionAndFunc.callback);
    };

    League.getRecentGames = function (summonerId, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url = util.craftUrl(endpoint, regionAndFunc.region, gameUrl + '/' + summonerId + '/recent?', authKey);

        util.makeRequest(url, 'Error getting recent games: ', 'games', regionAndFunc.callback);
    };

    League.getLeagueData = function (summonerId, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url = util.craftUrl(endpoint, regionAndFunc.region, leagueUrl + '/' + summonerId + '?', authKey);

        util.makeRequest(url, 'Error getting league data: ', null, regionAndFunc.callback);
    };

    League.Stats.getPlayerSummary = function (summonerId, season, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            seasonURL = '',
            url;

        if (util.getValidSeasonParam(season)) {
            if (season) {
                seasonURL = 'season=SEASON' + season + '&';
            }
        } else {
            console.log('Invalid query parameter for season: ' + season);
        }

        url = util.craftUrl(endpoint, regionAndFunc.region, statsUrl + '/' + summonerId + '/summary?' + seasonURL, authKey);
        util.makeRequest(url, 'Error getting summary data: ', 'playerStatSummaries', regionAndFunc.callback);
    };

    League.Stats.getRanked = function (summonerId, season, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            seasonURL = '',
            url;

        if (util.getValidSeasonParam(season)) {
            if (season) {
                seasonURL = 'season=SEASON' + season + '&';
            }
        } else {
            console.log('Invalid query parameter for season: ' + season);
        }

        url = util.craftUrl(endpoint, regionAndFunc.region, statsUrl + '/' + summonerId + '/ranked?' + seasonURL, authKey);
        util.makeRequest(url, 'Error getting ranked data: ', 'champions', regionAndFunc.callback);
    };

    League.Summoner.getMasteries = function (summonerId, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url = util.craftUrl(endpoint, regionAndFunc.region, summonerUrl + '/' + summonerId + '/masteries?', authKey);

        util.makeRequest(url, 'Error getting mastery data: ', 'pages', regionAndFunc.callback);
    };

    League.Summoner.getRunes = function (summonerId, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url = util.craftUrl(endpoint, regionAndFunc.region, summonerUrl + '/' + summonerId + '/runes?', authKey);

        util.makeRequest(url, 'Error getting rune data: ', 'pages', regionAndFunc.callback);
    };

    League.Summoner.getByName = function (name, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url;

        name = name.split(" ").join("");
        url = util.craftUrl(endpoint, regionAndFunc.region, summonerUrl + '/by-name/' + name + '?', authKey);

        util.makeRequest(url, 'Error getting summoner data using name: ', null, regionAndFunc.callback);
    };

    League.Summoner.getByID = function (summonerId, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url = util.craftUrl(endpoint, regionAndFunc.region, summonerUrl + '/' + summonerId + '?', authKey);

        util.makeRequest(url, 'Error getting summoner data: ', null, regionAndFunc.callback);
    };

    League.Summoner.listNamesByIDs = function (ids, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url = util.craftUrl(endpoint, regionAndFunc.region, summonerUrl + '/' + ids + '/name?', authKey);

        util.makeRequest(url, 'Error getting summoner data using list of ids: ', 'summoners', regionAndFunc.callback);
    };

    League.getTeams = function (summonerId, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url = util.craftUrl(endpoint, regionAndFunc.region, teamUrl + '/' + summonerId + '?', authKey);

        util.makeRequest(url, 'Error getting summoner teams info: ', null, regionAndFunc.callback);
    };

    module.exports = League
}());<commit_msg>Moved the util methods into their own module to keep things modularized<commit_after>/*global require*/
/*global exports*/
/*global module*/
/*global console*/
/*jslint nomen: true*/

(function () {

    'use strict';

    var League = {},
        util = require('./util'),
        authKey,
        region = 'na',
        endpoint = 'http://prod.api.pvp.net/api/lol',
        championUrl = '/v1.1/champion',
        gameUrl = '/v1.2/game/by-summoner',
        leagueUrl = '/v2.2/league/by-summoner',
        statsUrl = '/v1.2/stats/by-summoner',
        summonerUrl = '/v1.2/summoner',
        teamUrl = '/v2.2/team/by-summoner';

    League.Stats = {};

    League.Summoner = {};

    League.init = function (key, region) {
        authKey = key;
        if (region) {
            this.region = region;
        }
    };

    League.getRegions = function (callback) {
        callback(null, {
            'na': 'North America',
            'euw': 'Europe West',
            'eune': 'Europe Nordic and East'
        });
    };

    League.getQueues = function (callback) {
        callback(null, {
            2: 'Normal 5v5 Blind Pick',
            4: 'Ranked Solo 5v5',
            7: 'Coop vs AI 5v5',
            8: 'Normal 3v3',
            14: 'Normal 5v5 Draft Pick',
            16: 'Dominion 5v5 Blind Pick',
            17: 'Dominion 5v5 Draft Pick',
            25: 'Dominion Coop vs AI',
            41: 'Ranked Team 3v3',
            42: 'Ranked Team 5v5',
            52: 'Twisted Treeline Coop vs AI',
            65: 'ARAM',
            67: 'ARAM Coop vs AI'
        });
    };

    League.getMapNames = function (callback) {
        callback(null, {
            1: "Summoner's Rift Summer Variant",
            2: "Summoner's Rift Autumn Variant",
            3: 'The Proving Grounds',
            4: 'Twisted Treeline Original Version',
            8: 'The Crystal Scar',
            10: 'Twisted Treeline Current Version',
            12: 'Howling Abyss'
        });
    };

    League.getChampions = function (freeToPlay, regionOrFunction, callback) {
        var url,
            freetoPlayQuery = '',
            regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback);

        if (!(freeToPlay === null || typeof (freetoPlayQuery) === 'boolean')) {
            console.log('Invalid query parameter for freeToPlay: ' + freeToPlay);
        }

        if (freeToPlay) {
            freetoPlayQuery = 'freeToPlay=true&';
        }

        url = util.craftUrl(endpoint, regionAndFunc.region, championUrl + '?' + freetoPlayQuery, authKey);
        util.makeRequest(url, 'Error getting champions: ', 'champions', regionAndFunc.callback);
    };

    League.getRecentGames = function (summonerId, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url = util.craftUrl(endpoint, regionAndFunc.region, gameUrl + '/' + summonerId + '/recent?', authKey);

        util.makeRequest(url, 'Error getting recent games: ', 'games', regionAndFunc.callback);
    };

    League.getLeagueData = function (summonerId, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url = util.craftUrl(endpoint, regionAndFunc.region, leagueUrl + '/' + summonerId + '?', authKey);

        util.makeRequest(url, 'Error getting league data: ', null, regionAndFunc.callback);
    };

    League.Stats.getPlayerSummary = function (summonerId, season, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            seasonURL = '',
            url;

        if (util.getValidSeasonParam(season)) {
            if (season) {
                seasonURL = 'season=SEASON' + season + '&';
            }
        } else {
            console.log('Invalid query parameter for season: ' + season);
        }

        url = util.craftUrl(endpoint, regionAndFunc.region, statsUrl + '/' + summonerId + '/summary?' + seasonURL, authKey);
        util.makeRequest(url, 'Error getting summary data: ', 'playerStatSummaries', regionAndFunc.callback);
    };

    League.Stats.getRanked = function (summonerId, season, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            seasonURL = '',
            url;

        if (util.getValidSeasonParam(season)) {
            if (season) {
                seasonURL = 'season=SEASON' + season + '&';
            }
        } else {
            console.log('Invalid query parameter for season: ' + season);
        }

        url = util.craftUrl(endpoint, regionAndFunc.region, statsUrl + '/' + summonerId + '/ranked?' + seasonURL, authKey);
        util.makeRequest(url, 'Error getting ranked data: ', 'champions', regionAndFunc.callback);
    };

    League.Summoner.getMasteries = function (summonerId, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url = util.craftUrl(endpoint, regionAndFunc.region, summonerUrl + '/' + summonerId + '/masteries?', authKey);

        util.makeRequest(url, 'Error getting mastery data: ', 'pages', regionAndFunc.callback);
    };

    League.Summoner.getRunes = function (summonerId, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url = util.craftUrl(endpoint, regionAndFunc.region, summonerUrl + '/' + summonerId + '/runes?', authKey);

        util.makeRequest(url, 'Error getting rune data: ', 'pages', regionAndFunc.callback);
    };

    League.Summoner.getByName = function (name, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url;

        name = name.split(" ").join("");
        url = util.craftUrl(endpoint, regionAndFunc.region, summonerUrl + '/by-name/' + name + '?', authKey);

        util.makeRequest(url, 'Error getting summoner data using name: ', null, regionAndFunc.callback);
    };

    League.Summoner.getByID = function (summonerId, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url = util.craftUrl(endpoint, regionAndFunc.region, summonerUrl + '/' + summonerId + '?', authKey);

        util.makeRequest(url, 'Error getting summoner data: ', null, regionAndFunc.callback);
    };

    League.Summoner.listNamesByIDs = function (ids, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url = util.craftUrl(endpoint, regionAndFunc.region, summonerUrl + '/' + ids + '/name?', authKey);

        util.makeRequest(url, 'Error getting summoner data using list of ids: ', 'summoners', regionAndFunc.callback);
    };

    League.getTeams = function (summonerId, regionOrFunction, callback) {
        var regionAndFunc = util.getCallbackAndRegion(regionOrFunction, region, callback),
            url = util.craftUrl(endpoint, regionAndFunc.region, teamUrl + '/' + summonerId + '?', authKey);

        util.makeRequest(url, 'Error getting summoner teams info: ', null, regionAndFunc.callback);
    };

    module.exports = League;
}());<|endoftext|>


<commit_before>/**
 * Localization!
 *
 */
var model = require('./model')();

// Spoof because navigator.language sucks
function getLocaleFromQueryString() {
    var regex = new RegExp('[\\?&]locale=([^&#]*)');
    var results = regex.exec(window.location.search);

    if (results === null) {
        return '';
    } else {
        return decodeURIComponent(results[1].replace(/\+/g, ' '));
    }
}

function Localize () {
    var self = this;

    self.defaultLang = 'en-US';

    self.dictionary =  {};
    self.dictionaries = {};
    self.url = '';

    self.bind = function (langs, vue) {

        self.dictionaries = langs;

        // Bind directives/filters
        if (vue) {
            vue.filter('i18n', self.i18nFilter);
            vue.directive('bind-i18n-html', self.bindHtml);
        }
    };

    self.setLocale = function (locale, autodetect) {
        var html = window.document.querySelector('html');

        // Try to autodetect locale
        if (autodetect) {
            var spoof = getLocaleFromQueryString();
            var navLocale = navigator.language;
            var defaultLang = self.defaultLang;
            self.locale = spoof || locale || navLocale || defaultLang;
            model.locale = self.locale;
        }

        // Set dictionary
        var currentLangDict = self.dictionaries[model.locale];
        var defaultLangDict = self.dictionaries[self.defaultLang];
        self.dictionary = currentLangDict || defaultLangDict;

        if (html) {
            html.setAttribute('lang', model.locale);
        }

    };

    self.get = function (key) {
        var dict = self.dictionary[key];
        var defaultLang = self.dictionaries[self.defaultLang][key];
        return dict || defaultLang || key;
    };

    self.i18nFilter = function (key) {
        return self.get(key);
    };

    self.bindHtml = function (key) {
        var raw = self.get(key);
        this.el.innerHTML = raw;
    };
}

module.exports = new Localize();
<commit_msg>Fix l10n related issue with sidebar and related one<commit_after>/**
 * Localization!
 *
 */
var model = require('./model')();

// Spoof because navigator.language sucks
function getLocaleFromQueryString() {
    var regex = new RegExp('[\\?&]locale=([^&#]*)');
    var results = regex.exec(window.location.search);

    if (results === null) {
        return '';
    } else {
        return decodeURIComponent(results[1].replace(/\+/g, ' '));
    }
}

function Localize () {
    var self = this;

    self.defaultLang = 'en-US';
    self.locale = navigator.language;

    self.dictionary =  {};
    self.dictionaries = {};
    self.url = '';

    self.bind = function (langs, vue) {

        self.dictionaries = langs;

        // Bind directives/filters
        if (vue) {
            vue.filter('i18n', self.i18nFilter);
            vue.directive('bind-i18n-html', self.bindHtml);
        }
    };

    self.setLocale = function (locale, autodetect) {
        var html = window.document.querySelector('html');

        // Try to autodetect locale
        if (autodetect) {
            var defaultLang = self.defaultLang;
            var navLocale = navigator.language;
            var spoof = getLocaleFromQueryString();
            self.locale = spoof || locale || navLocale || defaultLang;
            model.locale = self.locale;
        }

        // Set dictionary
        var currentLangDict = self.dictionaries[model.locale];
        var defaultLangDict = self.dictionaries[self.defaultLang];
        self.dictionary = currentLangDict || defaultLangDict;

        if (html) {
            html.setAttribute('lang', model.locale);
        }

    };

    self.get = function (key) {
        var dict = self.dictionary[key];
        var defaultLang = self.dictionaries[self.defaultLang][key];
        if (self.dictionaries[self.locale] !== undefined) {
            return self.dictionaries[self.locale][key];
        }
        return dict || defaultLang || key;
    };

    self.i18nFilter = function (key) {
        return self.get(key);
    };

    self.bindHtml = function (key) {
        var raw = self.get(key);
        this.el.innerHTML = raw;
    };
}

module.exports = new Localize();
<|endoftext|>


<commit_before>import $ from './vendor/jquery.slim.min';

const storageKey = 'cachedNames';

const getCachedUsers = cb => {
	chrome.storage.local.get(storageKey, data => cb(data[storageKey]));
};

const updateCachedUsers = users => {
	chrome.storage.local.set({[storageKey]: users});
};

const addUsersName = (user, name) => {
	const $usernameLinks = $(`.timeline-comment-header-text:not(.has-full-name) a[href="/${user}"]`);
	$usernameLinks.each((i, userLink) => {
		if (user !== name) {
			$(`<span class="comment-full-name">`).text(`${name} -`).insertAfter(userLink);
		}
		$(userLink).closest('.timeline-comment-header-text').addClass('has-full-name');
	});
};

export default () => {
	getCachedUsers((users = {}) => {
		const usersOnPage = $('.js-discussion .author').get().map(el => el.innerText);
		const uniqueUsers = new Set(usersOnPage);

		// Add cached users to DOM first, since the calls for everyone else will be slow
		for (const user of uniqueUsers) {
			const cachedName = users[user];
			if (cachedName) {
				addUsersName(user, cachedName);
				uniqueUsers.delete(user);
			}
		}

		const userUrl = user => `${location.origin}/${user}/following`;
		const requests = Array.from(uniqueUsers).map(username => {
			const req = fetch(userUrl(username));
			return req.then(res => res.text()).then(profile => ({
				username,
				profile
			}));
		});

		Promise.all(requests).then(profiles => {
			const userCache = {};

			for (const {username, profile} of profiles) {
				const profileDOM = new DOMParser().parseFromString(profile, 'text/html');
				const fullname = $(profileDOM).find('h1 strong').text().slice(1, -1);

				// Possible for a user to not set a name
				if (fullname) {
					userCache[username] = fullname;
					addUsersName(username, fullname);
				}
			}

			updateCachedUsers(Object.assign({}, users, userCache));
		}).catch(console.error);
	});
};
<commit_msg>Fix text formatting for name of post editor (#488)<commit_after>import $ from './vendor/jquery.slim.min';

const storageKey = 'cachedNames';

const getCachedUsers = cb => {
	chrome.storage.local.get(storageKey, data => cb(data[storageKey]));
};

const updateCachedUsers = users => {
	chrome.storage.local.set({[storageKey]: users});
};

const addUsersName = (user, name) => {
	const $usernameLinks = $(`.timeline-comment-header-text:not(.has-full-name) a[href="/${user}"]`);
	$usernameLinks.each((i, userLink) => {
		const $userLink = $(userLink);
		if (user !== name) {
			let nameText = name;
			if (!$userLink.parent().hasClass('timestamp-edited')) {
				nameText += ' -';
			}
			$userLink.after(`<span class="comment-full-name">${nameText}</span>`);
		}
		$userLink.closest('.timeline-comment-header-text').addClass('has-full-name');
	});
};

export default () => {
	getCachedUsers((users = {}) => {
		const usersOnPage = $('.js-discussion .author').get().map(el => el.innerText);
		const uniqueUsers = new Set(usersOnPage);

		// Add cached users to DOM first, since the calls for everyone else will be slow
		for (const user of uniqueUsers) {
			const cachedName = users[user];
			if (cachedName) {
				addUsersName(user, cachedName);
				uniqueUsers.delete(user);
			}
		}

		const userUrl = user => `${location.origin}/${user}/following`;
		const requests = Array.from(uniqueUsers).map(username => {
			const req = fetch(userUrl(username));
			return req.then(res => res.text()).then(profile => ({
				username,
				profile
			}));
		});

		Promise.all(requests).then(profiles => {
			const userCache = {};

			for (const {username, profile} of profiles) {
				const profileDOM = new DOMParser().parseFromString(profile, 'text/html');
				const fullname = $(profileDOM).find('h1 strong').text().slice(1, -1);

				// Possible for a user to not set a name
				if (fullname) {
					userCache[username] = fullname;
					addUsersName(username, fullname);
				}
			}

			updateCachedUsers(Object.assign({}, users, userCache));
		}).catch(console.error);
	});
};
<|endoftext|>