<commit_before>var express = require("express");
var bodyParser = require("body-parser");
var elasticsearch = require("elasticsearch");
var root = express();
var app = express();

var applicantService = require("./services/applicants.js");
var labelService = require("./services/labels.js");
var attachmentService = require("./services/attachments.js");
var uploadService = require("./services/uploads.js");

//used for serving static files (html, client js, images)
app.use(express.static("client"));

app.use(express.static("node_modules"));

//parses the text as url encoded data and exposes the resulting object on req.body
app.use(bodyParser.urlencoded({
  extended: true
}));

//body-parser extracts the entire body portion of an incoming request stream
//and exposes it on req.body
app.use(bodyParser.json());

/**
 * HTTP GET request to retrieve applicants
 *
 * @param route - Routes HTTP GET requests to the specified path
 * @param callback function - Calls a service method to get specified applicants
 */
app.get("/service/applicants", function(req, res) {
  var type = null;
  if (!req.query || !req.query.type) {
    type = "new";
  } else {
    type = req.query.type.toLowerCase();
  }
  applicantService.listApplicants(req, res, type);
});

/**
 * HTTP POST request to index applicants
 *
 * @param route - Routes HTTP POST requests to the specified path
 * @param callback function - Calls a service method to index an applicant
 */
app.post("/service/labels", function(req, res) {
  labelService.index(req, res);
});

/**
 * HTTP DELETE request to retrieve applicants
 *
 * @param route - Routes HTTP DELETE requests to the specified path
 * @param callback function - Calls a service method to remove an applicant from labels index
 */
app.delete("/service/labels/:id", function(req, res) {
  labelService.delete(req, res);
});

/**
 * HTTP GET request to retrieve attachments
 *
 * @param route - Routes HTTP GET requests to the specified path
 * @param callback function - Calls a service method to get attachments
 */
app.get("/service/attachments", function(req, res) {
  attachmentService.getAttachment(req, res);
});

/**
 * HTTP POST request to index user uploaded resumes
 *
 * @param route - Routes HTTP POST requests to the specified path
 * @param callback function - Calls a service method to index the attachments
 */
app.post("/service/uploads", function(req,res) {
  uploadService.index(req,res);
});

/**
 * HTTP GET request to retrieve terms for autocomplete based on user input
 *
 * @param route - Routes HTTP GET requests to the specified path
 * @param callback function - Calls a service method to query user input to find relavent terms
 */
app.get("/service/suggest", function(req, res) {
  var term = req.query.term.toLowerCase();
  applicantService.suggest(term, res);
});

app.get("/service/graphs", function(req, res) {
  applicantService.aggregations(res, req.query.field);
});

/**
 * HTTP GET request on the app root
 *
 * @param route - Routes HTTP GET requests to the specified path
 * @param callback function - redirects to homepage
 */
root.get("/", function(req, res) {
  res.redirect("/app");
});

root.use('/app', app);

/**
 * HTML5 mode, gets rid of the '#' in URLs
 *
 * @param route -
 * @param callback function -
 */
app.all('/*', function(req, res) {
  res.sendFile('index.html', {
    root: __dirname + "/../client/"
  });
});

var server = root.listen(8082, function() {
  var host = server.address().address
  var port = server.address().port

  console.log("SmartHire listening at http://%s:%s", host, port)

});

<commit_msg>increased file upload size<commit_after>var express = require("express");
var bodyParser = require("body-parser");
var elasticsearch = require("elasticsearch");
var root = express();
var app = express();

var applicantService = require("./services/applicants.js");
var labelService = require("./services/labels.js");
var attachmentService = require("./services/attachments.js");
var uploadService = require("./services/uploads.js");

//used for serving static files (html, client js, images)
app.use(express.static("client"));

//node module directory
app.use(express.static("node_modules"));

//max file size for uploads
app.use(bodyParser.json({limit: '50mb'}));

//parses the text as url encoded data and exposes the resulting object on req.body
app.use(bodyParser.urlencoded({
  limit: '50mb',
  extended: true
}));

//body-parser extracts the entire body portion of an incoming request stream
//and exposes it on req.body
app.use(bodyParser.json());

/**
 * HTTP GET request to retrieve applicants
 *
 * @param route - Routes HTTP GET requests to the specified path
 * @param callback function - Calls a service method to get specified applicants
 */
app.get("/service/applicants", function(req, res) {
  var type = null;
  if (!req.query || !req.query.type) {
    type = "new";
  } else {
    type = req.query.type.toLowerCase();
  }
  applicantService.listApplicants(req, res, type);
});

/**
 * HTTP POST request to index applicants
 *
 * @param route - Routes HTTP POST requests to the specified path
 * @param callback function - Calls a service method to index an applicant
 */
app.post("/service/labels", function(req, res) {
  labelService.index(req, res);
});

/**
 * HTTP DELETE request to retrieve applicants
 *
 * @param route - Routes HTTP DELETE requests to the specified path
 * @param callback function - Calls a service method to remove an applicant from labels index
 */
app.delete("/service/labels/:id", function(req, res) {
  labelService.delete(req, res);
});

/**
 * HTTP GET request to retrieve attachments
 *
 * @param route - Routes HTTP GET requests to the specified path
 * @param callback function - Calls a service method to get attachments
 */
app.get("/service/attachments", function(req, res) {
  attachmentService.getAttachment(req, res);
});

/**
 * HTTP POST request to index user uploaded resumes
 *
 * @param route - Routes HTTP POST requests to the specified path
 * @param callback function - Calls a service method to index the attachments
 */
app.post("/service/uploads", function(req,res) {
  uploadService.index(req,res);
});

/**
 * HTTP GET request to retrieve terms for autocomplete based on user input
 *
 * @param route - Routes HTTP GET requests to the specified path
 * @param callback function - Calls a service method to query user input to find relavent terms
 */
app.get("/service/suggest", function(req, res) {
  var term = req.query.term.toLowerCase();
  applicantService.suggest(term, res);
});

app.get("/service/graphs", function(req, res) {
  applicantService.aggregations(res, req.query.field);
});

/**
 * HTTP GET request on the app root
 *
 * @param route - Routes HTTP GET requests to the specified path
 * @param callback function - redirects to homepage
 */
root.get("/", function(req, res) {
  res.redirect("/app");
});

root.use('/app', app);

/**
 * HTML5 mode, gets rid of the '#' in URLs
 *
 * @param route -
 * @param callback function -
 */
app.all('/*', function(req, res) {
  res.sendFile('index.html', {
    root: __dirname + "/../client/"
  });
});

var server = root.listen(8082, function() {
  var host = server.address().address
  var port = server.address().port

  console.log("SmartHire listening at http://%s:%s", host, port)

});

<|endoftext|>


<commit_before>;(function () {
    "use strict";

    var canvases = [];

    var cvs1overwrap = $("<div/>").addClass("SSM_gswrap");
    var cvs1 = canvas({ resizable:false });
    cvs1.container.prepend(cvs1overwrap);
    cvs1overwrap.append(cvs1.title_anchor).append(cvs1.wrapper).append(cvs1.caption_anchor);
    cvs1.overwrap = cvs1overwrap;
    canvases.push(cvs1);

    var cvs2overwrap = $("<div/>").addClass("SSM_gswrap");
    var cvs2 = canvas({ resizable:false });
    cvs2.container.prepend(cvs2overwrap);
    cvs2overwrap.append(cvs2.title_anchor).append(cvs2.wrapper).append(cvs2.caption_anchor);
    cvs2.overwrap = cvs2overwrap;
    canvases.push(cvs2);

    //this.canvas.wrapper.css({float:"left"});

    var high = Number(window.innerHeight) - 57;                     // 36 for status bar, 21 for title
    var wide = Number(window.innerWidth) - 20                       // 20 for good measure
    var cvsdim = Math.min(high,(wide-200)/2.0);

    cvs1.width = cvs1.height = cvs2.width = cvs2.height = cvsdim;   // Set canvas dimensions.
    sphere({ canvas: cvs1, visible: false });                       // Activate cvs1.
    sphere({ canvas: cvs2, visible: false });                       // Activate cvs2.

    //this.canvas.wrapper.css({margin: '4px'});
    //$(this.canvas.__canvas_element).css({border: '1px solid #AAA'});
    //$(this.canvas.__overlay_element).css({border: '1px solid #AAA'});

    print('', {end:''});
    print_options({width:200, height:cvsdim});

    var myStylesLocation = "https://raw.githack.com/thehappyt/SSModels/master/gsssm0.1.css";
    $('<link rel="stylesheet" type="text/css" href="'+myStylesLocation+'" >') .appendTo("head");

    var global = window;
    function Export( exports ) {
        if (!global.gsssm) global.gsssm = {}
        for(var id in exports) {
            if (!global[id]) global[id] = exports[id]
            gsssm[id] = exports[id]
        }
    }

    var exports = { canvases: canvases }
    Export(exports)
}) ();
<commit_msg>Fix typo in CSS import.<commit_after>;(function () {
    "use strict";

    var canvases = [];

    var cvs1overwrap = $("<div/>").addClass("SSM_gswrap");
    var cvs1 = canvas({ resizable:false });
    cvs1.container.prepend(cvs1overwrap);
    cvs1overwrap.append(cvs1.title_anchor).append(cvs1.wrapper).append(cvs1.caption_anchor);
    cvs1.overwrap = cvs1overwrap;
    canvases.push(cvs1);

    var cvs2overwrap = $("<div/>").addClass("SSM_gswrap");
    var cvs2 = canvas({ resizable:false });
    cvs2.container.prepend(cvs2overwrap);
    cvs2overwrap.append(cvs2.title_anchor).append(cvs2.wrapper).append(cvs2.caption_anchor);
    cvs2.overwrap = cvs2overwrap;
    canvases.push(cvs2);

    //this.canvas.wrapper.css({float:"left"});

    var high = Number(window.innerHeight) - 57;                     // 36 for status bar, 21 for title
    var wide = Number(window.innerWidth) - 20                       // 20 for good measure
    var cvsdim = Math.min(high,(wide-200)/2.0);

    cvs1.width = cvs1.height = cvs2.width = cvs2.height = cvsdim;   // Set canvas dimensions.
    sphere({ canvas: cvs1, visible: false });                       // Activate cvs1.
    sphere({ canvas: cvs2, visible: false });                       // Activate cvs2.

    //this.canvas.wrapper.css({margin: '4px'});
    //$(this.canvas.__canvas_element).css({border: '1px solid #AAA'});
    //$(this.canvas.__overlay_element).css({border: '1px solid #AAA'});

    print('', {end:''});
    print_options({width:200, height:cvsdim});

    var myStylesLocation = "https://raw.githack.com/thehappyt/SSModels/gh-pages/gsssm0.1.css";
    $('<link rel="stylesheet" type="text/css" href="'+myStylesLocation+'" >') .appendTo("head");

    var global = window;
    function Export( exports ) {
        if (!global.gsssm) global.gsssm = {}
        for(var id in exports) {
            if (!global[id]) global[id] = exports[id]
            gsssm[id] = exports[id]
        }
    }

    var exports = { canvases: canvases }
    Export(exports)
}) ();
<|endoftext|>


<commit_before>(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";

  var HINT_ELEMENT_CLASS        = "CodeMirror-hint";
  var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";

  CodeMirror.showHint = function(cm, getHints, options) {
    // We want a single cursor position.
    if (cm.listSelections().length > 1 || cm.somethingSelected()) return;
    if (getHints == null) {
      if (options && options.async) return;
      else getHints = CodeMirror.hint.auto;
    }

    if (cm.state.completionActive) cm.state.completionActive.close();

    var completion = cm.state.completionActive = new Completion(cm, getHints, options || {});
    CodeMirror.signal(cm, "startCompletion", cm);
    if (completion.options.async)
      getHints(cm, function(hints) { completion.showHints(hints); }, completion.options);
    else
      return completion.showHints(getHints(cm, completion.options));
  };

  function Completion(cm, getHints, options) {
    this.cm = cm;
    this.getHints = getHints;
    this.options = options;
    this.widget = this.onClose = null;
  }

  Completion.prototype = {
    close: function() {
      if (!this.active()) return;
      this.cm.state.completionActive = null;

      if (this.widget) this.widget.close();
      if (this.onClose) this.onClose();
      CodeMirror.signal(this.cm, "endCompletion", this.cm);
    },

    active: function() {
      return this.cm.state.completionActive == this;
    },

    pick: function(data, i) {
      var completion = data.list[i];
      if (completion.hint) completion.hint(this.cm, data, completion);
      else this.cm.replaceRange(getText(completion), data.from, data.to);
      CodeMirror.signal(data, "pick", completion);
      this.close();
    },

    showHints: function(data) {
      if (!data || !data.list.length || !this.active()) return this.close();

      if (this.options.completeSingle != false && data.list.length == 1)
        this.pick(data, 0);
      else
        this.showWidget(data);
    },

    showWidget: function(data) {
      this.widget = new Widget(this, data);
      CodeMirror.signal(data, "shown");

      var debounce = 0, completion = this, finished;
      var closeOn = this.options.closeCharacters || /[\s()\[\]{};:>,]/;
      var startPos = this.cm.getCursor(), startLen = this.cm.getLine(startPos.line).length;

      var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
        return setTimeout(fn, 1000/60);
      };
      var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;

      function done() {
        if (finished) return;
        finished = true;
        completion.close();
        completion.cm.off("cursorActivity", activity);
        if (data) CodeMirror.signal(data, "close");
      }

      function update() {
        if (finished) return;
        CodeMirror.signal(data, "update");
        if (completion.options.async)
          completion.getHints(completion.cm, finishUpdate, completion.options);
        else
          finishUpdate(completion.getHints(completion.cm, completion.options));
      }
      function finishUpdate(data_) {
        data = data_;
        if (finished) return;
        if (!data || !data.list.length) return done();
        completion.widget = new Widget(completion, data);
      }

      function clearDebounce() {
        if (debounce) {
          cancelAnimationFrame(debounce);
          debounce = 0;
        }
      }

      function activity() {
        clearDebounce();
        var pos = completion.cm.getCursor(), line = completion.cm.getLine(pos.line);
        if (pos.line != startPos.line || line.length - pos.ch != startLen - startPos.ch ||
            pos.ch < startPos.ch || completion.cm.somethingSelected() ||
            (pos.ch && closeOn.test(line.charAt(pos.ch - 1)))) {
          completion.close();
        } else {
          debounce = requestAnimationFrame(update);
          if (completion.widget) completion.widget.close();
        }
      }
      this.cm.on("cursorActivity", activity);
      this.onClose = done;
    }
  };

  function getText(completion) {
    if (typeof completion == "string") return completion;
    else return completion.text;
  }

  function buildKeyMap(options, handle) {
    var baseMap = {
      Up: function() {handle.moveFocus(-1);},
      Down: function() {handle.moveFocus(1);},
      PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
      PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
      Home: function() {handle.setFocus(0);},
      End: function() {handle.setFocus(handle.length - 1);},
      Enter: handle.pick,
      Tab: handle.pick,
      Esc: handle.close
    };
    var ourMap = options.customKeys ? {} : baseMap;
    function addBinding(key, val) {
      var bound;
      if (typeof val != "string")
        bound = function(cm) { return val(cm, handle); };
      // This mechanism is deprecated
      else if (baseMap.hasOwnProperty(val))
        bound = baseMap[val];
      else
        bound = val;
      ourMap[key] = bound;
    }
    if (options.customKeys)
      for (var key in options.customKeys) if (options.customKeys.hasOwnProperty(key))
        addBinding(key, options.customKeys[key]);
    if (options.extraKeys)
      for (var key in options.extraKeys) if (options.extraKeys.hasOwnProperty(key))
        addBinding(key, options.extraKeys[key]);
    return ourMap;
  }

  function getHintElement(hintsElement, el) {
    while (el && el != hintsElement) {
      if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
      el = el.parentNode;
    }
  }

  function Widget(completion, data) {
    this.completion = completion;
    this.data = data;
    var widget = this, cm = completion.cm, options = completion.options;

    var hints = this.hints = document.createElement("ul");
    hints.className = "CodeMirror-hints";
    this.selectedHint = options.getDefaultSelection ? options.getDefaultSelection(cm,options,data) : 0;

    var completions = data.list;
    for (var i = 0; i < completions.length; ++i) {
      var elt = hints.appendChild(document.createElement("li")), cur = completions[i];
      var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
      if (cur.className != null) className = cur.className + " " + className;
      elt.className = className;
      if (cur.render) cur.render(elt, data, cur);
      else elt.appendChild(document.createTextNode(cur.displayText || getText(cur)));
      elt.hintId = i;
    }

    var pos = cm.cursorCoords(options.alignWithWord !== false ? data.from : null);
    var left = pos.left, top = pos.bottom, below = true;
    hints.style.left = left + "px";
    hints.style.top = top + "px";
    // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
    var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
    var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
    (options.container || document.body).appendChild(hints);
    var box = hints.getBoundingClientRect();
    var overlapX = box.right - winW, overlapY = box.bottom - winH;
    if (overlapX > 0) {
      if (box.right - box.left > winW) {
        hints.style.width = (winW - 5) + "px";
        overlapX -= (box.right - box.left) - winW;
      }
      hints.style.left = (left = pos.left - overlapX) + "px";
    }
    if (overlapY > 0) {
      var height = box.bottom - box.top;
      if (box.top - (pos.bottom - pos.top) - height > 0) {
        overlapY = height + (pos.bottom - pos.top);
        below = false;
      } else if (height > winH) {
        hints.style.height = (winH - 5) + "px";
        overlapY -= height - winH;
      }
      hints.style.top = (top = pos.bottom - overlapY) + "px";
    }

    cm.addKeyMap(this.keyMap = buildKeyMap(options, {
      moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
      setFocus: function(n) { widget.changeActive(n); },
      menuSize: function() { return widget.screenAmount(); },
      length: completions.length,
      close: function() { completion.close(); },
      pick: function() { widget.pick(); }
    }));

    if (options.closeOnUnfocus !== false) {
      var closingOnBlur;
      cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
      cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
    }

    var startScroll = cm.getScrollInfo();
    cm.on("scroll", this.onScroll = function() {
      var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
      var newTop = top + startScroll.top - curScroll.top;
      var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop);
      if (!below) point += hints.offsetHeight;
      if (point <= editor.top || point >= editor.bottom) return completion.close();
      hints.style.top = newTop + "px";
      hints.style.left = (left + startScroll.left - curScroll.left) + "px";
    });

    CodeMirror.on(hints, "dblclick", function(e) {
      var t = getHintElement(hints, e.target || e.srcElement);
      if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
    });

    CodeMirror.on(hints, "click", function(e) {
      var t = getHintElement(hints, e.target || e.srcElement);
      if (t && t.hintId != null) {
        widget.changeActive(t.hintId);
        if (options.completeOnSingleClick) widget.pick();
      }
    });

    CodeMirror.on(hints, "mousedown", function() {
      setTimeout(function(){cm.focus();}, 20);
    });

    CodeMirror.signal(data, "select", completions[0], hints.firstChild);
    return true;
  }

  Widget.prototype = {
    close: function() {
      if (this.completion.widget != this) return;
      this.completion.widget = null;
      this.hints.parentNode.removeChild(this.hints);
      this.completion.cm.removeKeyMap(this.keyMap);

      var cm = this.completion.cm;
      if (this.completion.options.closeOnUnfocus !== false) {
        cm.off("blur", this.onBlur);
        cm.off("focus", this.onFocus);
      }
      cm.off("scroll", this.onScroll);
    },

    pick: function() {
      this.completion.pick(this.data, this.selectedHint);
    },

    changeActive: function(i, avoidWrap) {
      if (i >= this.data.list.length)
        i = avoidWrap ? this.data.list.length - 1 : 0;
      else if (i < 0)
        i = avoidWrap ? 0  : this.data.list.length - 1;
      if (this.selectedHint == i) return;
      var node = this.hints.childNodes[this.selectedHint];
      node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
      node = this.hints.childNodes[this.selectedHint = i];
      node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
      if (node.offsetTop < this.hints.scrollTop)
        this.hints.scrollTop = node.offsetTop - 3;
      else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
        this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
      CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
    },

    screenAmount: function() {
      return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
    }
  };

  CodeMirror.registerHelper("hint", "auto", function(cm, options) {
    var helpers = cm.getHelpers(cm.getCursor(), "hint");
    if (helpers.length) {
      for (var i = 0; i < helpers.length; i++) {
        var cur = helpers[i](cm, options);
        if (cur && cur.list.length) return cur;
      }
    } else {
      var words = cm.getHelper(cm.getCursor(), "hintWords");
      if (words) return CodeMirror.hint.fromList(cm, {words: words});
    }
  });

  CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
    var cur = cm.getCursor(), token = cm.getTokenAt(cur);
    var found = [];
    for (var i = 0; i < options.words.length; i++) {
      var word = options.words[i];
      if (word.slice(0, token.string.length) == token.string)
        found.push(word);
    }

    if (found.length) return {
      list: found,
      from: CodeMirror.Pos(cur.line, token.start),
            to: CodeMirror.Pos(cur.line, token.end)
    };
  });

  CodeMirror.commands.autocomplete = CodeMirror.showHint;
});
<commit_msg>[show-hint addon] Don't cover cursor when taking up full screen height<commit_after>(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";

  var HINT_ELEMENT_CLASS        = "CodeMirror-hint";
  var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";

  CodeMirror.showHint = function(cm, getHints, options) {
    // We want a single cursor position.
    if (cm.listSelections().length > 1 || cm.somethingSelected()) return;
    if (getHints == null) {
      if (options && options.async) return;
      else getHints = CodeMirror.hint.auto;
    }

    if (cm.state.completionActive) cm.state.completionActive.close();

    var completion = cm.state.completionActive = new Completion(cm, getHints, options || {});
    CodeMirror.signal(cm, "startCompletion", cm);
    if (completion.options.async)
      getHints(cm, function(hints) { completion.showHints(hints); }, completion.options);
    else
      return completion.showHints(getHints(cm, completion.options));
  };

  function Completion(cm, getHints, options) {
    this.cm = cm;
    this.getHints = getHints;
    this.options = options;
    this.widget = this.onClose = null;
  }

  Completion.prototype = {
    close: function() {
      if (!this.active()) return;
      this.cm.state.completionActive = null;

      if (this.widget) this.widget.close();
      if (this.onClose) this.onClose();
      CodeMirror.signal(this.cm, "endCompletion", this.cm);
    },

    active: function() {
      return this.cm.state.completionActive == this;
    },

    pick: function(data, i) {
      var completion = data.list[i];
      if (completion.hint) completion.hint(this.cm, data, completion);
      else this.cm.replaceRange(getText(completion), data.from, data.to);
      CodeMirror.signal(data, "pick", completion);
      this.close();
    },

    showHints: function(data) {
      if (!data || !data.list.length || !this.active()) return this.close();

      if (this.options.completeSingle != false && data.list.length == 1)
        this.pick(data, 0);
      else
        this.showWidget(data);
    },

    showWidget: function(data) {
      this.widget = new Widget(this, data);
      CodeMirror.signal(data, "shown");

      var debounce = 0, completion = this, finished;
      var closeOn = this.options.closeCharacters || /[\s()\[\]{};:>,]/;
      var startPos = this.cm.getCursor(), startLen = this.cm.getLine(startPos.line).length;

      var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
        return setTimeout(fn, 1000/60);
      };
      var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;

      function done() {
        if (finished) return;
        finished = true;
        completion.close();
        completion.cm.off("cursorActivity", activity);
        if (data) CodeMirror.signal(data, "close");
      }

      function update() {
        if (finished) return;
        CodeMirror.signal(data, "update");
        if (completion.options.async)
          completion.getHints(completion.cm, finishUpdate, completion.options);
        else
          finishUpdate(completion.getHints(completion.cm, completion.options));
      }
      function finishUpdate(data_) {
        data = data_;
        if (finished) return;
        if (!data || !data.list.length) return done();
        completion.widget = new Widget(completion, data);
      }

      function clearDebounce() {
        if (debounce) {
          cancelAnimationFrame(debounce);
          debounce = 0;
        }
      }

      function activity() {
        clearDebounce();
        var pos = completion.cm.getCursor(), line = completion.cm.getLine(pos.line);
        if (pos.line != startPos.line || line.length - pos.ch != startLen - startPos.ch ||
            pos.ch < startPos.ch || completion.cm.somethingSelected() ||
            (pos.ch && closeOn.test(line.charAt(pos.ch - 1)))) {
          completion.close();
        } else {
          debounce = requestAnimationFrame(update);
          if (completion.widget) completion.widget.close();
        }
      }
      this.cm.on("cursorActivity", activity);
      this.onClose = done;
    }
  };

  function getText(completion) {
    if (typeof completion == "string") return completion;
    else return completion.text;
  }

  function buildKeyMap(options, handle) {
    var baseMap = {
      Up: function() {handle.moveFocus(-1);},
      Down: function() {handle.moveFocus(1);},
      PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
      PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
      Home: function() {handle.setFocus(0);},
      End: function() {handle.setFocus(handle.length - 1);},
      Enter: handle.pick,
      Tab: handle.pick,
      Esc: handle.close
    };
    var ourMap = options.customKeys ? {} : baseMap;
    function addBinding(key, val) {
      var bound;
      if (typeof val != "string")
        bound = function(cm) { return val(cm, handle); };
      // This mechanism is deprecated
      else if (baseMap.hasOwnProperty(val))
        bound = baseMap[val];
      else
        bound = val;
      ourMap[key] = bound;
    }
    if (options.customKeys)
      for (var key in options.customKeys) if (options.customKeys.hasOwnProperty(key))
        addBinding(key, options.customKeys[key]);
    if (options.extraKeys)
      for (var key in options.extraKeys) if (options.extraKeys.hasOwnProperty(key))
        addBinding(key, options.extraKeys[key]);
    return ourMap;
  }

  function getHintElement(hintsElement, el) {
    while (el && el != hintsElement) {
      if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
      el = el.parentNode;
    }
  }

  function Widget(completion, data) {
    this.completion = completion;
    this.data = data;
    var widget = this, cm = completion.cm, options = completion.options;

    var hints = this.hints = document.createElement("ul");
    hints.className = "CodeMirror-hints";
    this.selectedHint = options.getDefaultSelection ? options.getDefaultSelection(cm,options,data) : 0;

    var completions = data.list;
    for (var i = 0; i < completions.length; ++i) {
      var elt = hints.appendChild(document.createElement("li")), cur = completions[i];
      var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
      if (cur.className != null) className = cur.className + " " + className;
      elt.className = className;
      if (cur.render) cur.render(elt, data, cur);
      else elt.appendChild(document.createTextNode(cur.displayText || getText(cur)));
      elt.hintId = i;
    }

    var pos = cm.cursorCoords(options.alignWithWord !== false ? data.from : null);
    var left = pos.left, top = pos.bottom, below = true;
    hints.style.left = left + "px";
    hints.style.top = top + "px";
    // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
    var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
    var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
    (options.container || document.body).appendChild(hints);
    var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
    if (overlapY > 0) {
      var height = box.bottom - box.top, curTop = box.top - (pos.bottom - pos.top);
      if (curTop - height > 0) { // Fits above cursor
        hints.style.top = (top = curTop - height) + "px";
        below = false;
      } else if (height > winH) {
        hints.style.height = (winH - 5) + "px";
        hints.style.top = (top = pos.bottom - box.top) + "px";
        var cursor = cm.getCursor();
        if (data.from.ch != cursor.ch) {
          pos = cm.cursorCoords(cursor);
          hints.style.left = (left = pos.left) + "px";
          box = hints.getBoundingClientRect();
        }
      }
    }
    var overlapX = box.left - winW;
    if (overlapX > 0) {
      if (box.right - box.left > winW) {
        hints.style.width = (winW - 5) + "px";
        overlapX -= (box.right - box.left) - winW;
      }
      hints.style.left = (left = pos.left - overlapX) + "px";
    }

    cm.addKeyMap(this.keyMap = buildKeyMap(options, {
      moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
      setFocus: function(n) { widget.changeActive(n); },
      menuSize: function() { return widget.screenAmount(); },
      length: completions.length,
      close: function() { completion.close(); },
      pick: function() { widget.pick(); }
    }));

    if (options.closeOnUnfocus !== false) {
      var closingOnBlur;
      cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
      cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
    }

    var startScroll = cm.getScrollInfo();
    cm.on("scroll", this.onScroll = function() {
      var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
      var newTop = top + startScroll.top - curScroll.top;
      var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop);
      if (!below) point += hints.offsetHeight;
      if (point <= editor.top || point >= editor.bottom) return completion.close();
      hints.style.top = newTop + "px";
      hints.style.left = (left + startScroll.left - curScroll.left) + "px";
    });

    CodeMirror.on(hints, "dblclick", function(e) {
      var t = getHintElement(hints, e.target || e.srcElement);
      if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
    });

    CodeMirror.on(hints, "click", function(e) {
      var t = getHintElement(hints, e.target || e.srcElement);
      if (t && t.hintId != null) {
        widget.changeActive(t.hintId);
        if (options.completeOnSingleClick) widget.pick();
      }
    });

    CodeMirror.on(hints, "mousedown", function() {
      setTimeout(function(){cm.focus();}, 20);
    });

    CodeMirror.signal(data, "select", completions[0], hints.firstChild);
    return true;
  }

  Widget.prototype = {
    close: function() {
      if (this.completion.widget != this) return;
      this.completion.widget = null;
      this.hints.parentNode.removeChild(this.hints);
      this.completion.cm.removeKeyMap(this.keyMap);

      var cm = this.completion.cm;
      if (this.completion.options.closeOnUnfocus !== false) {
        cm.off("blur", this.onBlur);
        cm.off("focus", this.onFocus);
      }
      cm.off("scroll", this.onScroll);
    },

    pick: function() {
      this.completion.pick(this.data, this.selectedHint);
    },

    changeActive: function(i, avoidWrap) {
      if (i >= this.data.list.length)
        i = avoidWrap ? this.data.list.length - 1 : 0;
      else if (i < 0)
        i = avoidWrap ? 0  : this.data.list.length - 1;
      if (this.selectedHint == i) return;
      var node = this.hints.childNodes[this.selectedHint];
      node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
      node = this.hints.childNodes[this.selectedHint = i];
      node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
      if (node.offsetTop < this.hints.scrollTop)
        this.hints.scrollTop = node.offsetTop - 3;
      else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
        this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
      CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
    },

    screenAmount: function() {
      return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
    }
  };

  CodeMirror.registerHelper("hint", "auto", function(cm, options) {
    var helpers = cm.getHelpers(cm.getCursor(), "hint");
    if (helpers.length) {
      for (var i = 0; i < helpers.length; i++) {
        var cur = helpers[i](cm, options);
        if (cur && cur.list.length) return cur;
      }
    } else {
      var words = cm.getHelper(cm.getCursor(), "hintWords");
      if (words) return CodeMirror.hint.fromList(cm, {words: words});
    }
  });

  CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
    var cur = cm.getCursor(), token = cm.getTokenAt(cur);
    var found = [];
    for (var i = 0; i < options.words.length; i++) {
      var word = options.words[i];
      if (word.slice(0, token.string.length) == token.string)
        found.push(word);
    }

    if (found.length) return {
      list: found,
      from: CodeMirror.Pos(cur.line, token.start),
            to: CodeMirror.Pos(cur.line, token.end)
    };
  });

  CodeMirror.commands.autocomplete = CodeMirror.showHint;
});
<|endoftext|>


<commit_before>// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Depends on jsonlint.js from https://github.com/zaach/jsonlint

// declare global: jsonlint

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.registerHelper("lint", "json", function(text) {
  var found = [];
  if (!window.jsonlint) {
    if (window.console) {
      window.console.error("Error: window.jsonlint not defined, CodeMirror JSON linting cannot run.");
    }
    return found;
  }
  // for jsonlint's web dist jsonlint is exported as an object with a single property parser, of which parseError
  // is a subproperty
  if (window.jsonlint.parser) {
    var jsonlint = window.jsonlint.parser;
  }
  jsonlint.parseError = function(str, hash) {
    var loc = hash.loc;
    found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column),
                to: CodeMirror.Pos(loc.last_line - 1, loc.last_column),
                message: str});
  };
  try { jsonlint.parse(text); }
  catch(e) {}
  return found;
});

});
<commit_msg>[json-lint addon] Fix broken use of var declaration<commit_after>// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Depends on jsonlint.js from https://github.com/zaach/jsonlint

// declare global: jsonlint

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.registerHelper("lint", "json", function(text) {
  var found = [];
  if (!window.jsonlint) {
    if (window.console) {
      window.console.error("Error: window.jsonlint not defined, CodeMirror JSON linting cannot run.");
    }
    return found;
  }
  // for jsonlint's web dist jsonlint is exported as an object with a single property parser, of which parseError
  // is a subproperty
  var jsonlint = window.jsonlint.parser || window.jsonlint
  jsonlint.parseError = function(str, hash) {
    var loc = hash.loc;
    found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column),
                to: CodeMirror.Pos(loc.last_line - 1, loc.last_column),
                message: str});
  };
  try { jsonlint.parse(text); }
  catch(e) {}
  return found;
});

});
<|endoftext|>


<commit_before>import config from 'ember-get-config';
import Ember from 'ember';
import extend from 'ember-es-adapter/utils/extend';

const defaultQuerySize = 20;

/**
* ElasticSearch Tools for interfacing
*
* @class EsTools
* @constructor
*/
class EsTools {

  constructor () {
    this.host = config.EsAdapter.host;
    this.namespace = config.EsAdapter.namespace;
  }

  /**
  * Gets the mapping from ElasticSearch in form of array.
  *
  * @method getMapping
  * @private
  * @return {Object} Object containing arrays of mappings.
  * e.g. {'post':[{mapping:'body', type:'string'}]}
  */
  getMapping() {
    if (!this.host || !this.namespace) {
      console.log('[EsMapper][getMapping]: Host or Namespace not defined.');
      return false;
    }

    let host = this.host,
        namespace = this.namespace;

    return new Ember.RSVP.Promise(function(resolve, reject) {
      fetch(host + '/'+ namespace + '/_mappings')
        .then((resp) => {
          let r = resp.json(),
              types = {};

          r.then((result) => {
              for (var i in result) {
                if (result[i]['mappings']) {
                  let _types = result[i]['mappings'];

                  for (var j in _types) {
                    if (_types[j]) {
                      let _properties = _types[j]['properties'];
                      let _propKeys = Object.keys(_properties);

                      types[j] = [];

                      for (var k=0; k < _propKeys.length; k++) {
                        types[j].push({
                          'mapping': _propKeys[k],
                          'type': _properties[_propKeys[k]].type
                        });
                      }

                      resolve(types);
                    }
                    else {
                      reject('[EsMapper][getMapping]: No Types Found.');
                    }
                  }
                }
                else {
                  reject('[EsMapper][getMapping]: No Mappings Found.');
                }
              }
            });

          });

    });
  }

  getTrue() {
    return true;
  }

  getLastId(index,field) {
    let host = this.host,
        namespace = this.namespace,
        queryString = "_search?query=match_all&size=1&fields=" + field + "&sort=" + field + ":desc",
        url = [host, namespace, index, queryString].join('/');

    return new Ember.RSVP.Promise(function(resolve, reject) {
      fetch(url)
        .then((resp) => {
          resp.json()
            .then((json) => {
              if (json && json.hits.hits.length) {
                resolve(parseInt(json.hits.hits[0]._id));
              }
              else {
                reject('[EsMapper][getLastId]: No Response.');
              }
            });
        });
    });
  }

}

/**
* ElasticSearch Tools for interfacing
*
* @class EsTools
* @constructor
*/
class QueryDSL {

  constructor (opts) {
    this.opts = JSON.parse(JSON.stringify(opts)) || null;
    this.sort = [];
    this.options = this._options(opts);
    this._defaultSortSet = false;

  }

  /**
  * Private:
  * Sets the options variable for the class.
  *
  * @method _options
  * @private
  * @param {Object} options Overrides for the class.
  * @return {Object} default = { 'sortType': 'desc', 'sort': '_score' };
  */
  _options(options) {
    options = options ? options : {};
    options.esParams = options.esParams ? options.esParams: {};

    let defaults = {
      'from': 0,
      'size': defaultQuerySize
    };

    options = extend(defaults, options, options.esParams);

    if (options.page) {
      options.from = this._getOffsetFromPage(options.page, options.size);
    }

    return options;
  }

  query() {
    this._query = { query: {} };
    return this;
  }

  match(options) {
    this._add('match', options);
    return this;
  }

  match_phrase(options) {
    this._add('match_phrase', options);
    return this;
  }

  multi_match(options) {
    this._add('multi_match', options);
    return this;
  }

  bool(kind) {
    this._addParent('bool', kind);
    return this;
  }

  getThis() {
    return this._query;
  }

  _add(type, options) {
    if (options == null) {
      options = {};
    }

    let params = {};
    params[type] = options;

    return this._query.query[type] = options;
  }

  _addParent(type, kind) {
    let params = {};
    params[type] = {};
    params[type][kind] = {};

    return this._query[type] = options;
  }

  /**
  * Private:
  * Convert page to offset for use with pagination

  * @method _getOffsetFromPage
  * @private
  * @param {Integer} page Page that request is on.
  * @param {Integer} size Size of pages (optional).
  * @return {Integer} Returns offset.
  */
  _getOffsetFromPage(page, size) {
    size = size ? size : defaultQuerySize;

    return page * size;
  }

  /**
  * Public:
  * Returns options from the class.
  *
  * @method getOptions
  * @return {Object} { 'sortType': 'desc', 'sort': '_score' }
  */
  getOptions() {
    return this.options;
  }

  /**
  * Private:
  * Generates the template for a "Bool" query.
  *   ```json
  *   {
  *     "query": {
  *       "bool": {
  *         "must": [],
  *         "filter": [],
  *         "must_not": [],
  *         "should": [],
  *       }
  *     }
  *   }
  *   ```
  *
  * @method _templateBoolQuery
  * @private
  * @return {Object} Returns the default structure for the query.
  */
  _templateBoolQuery() {
    return {
       "query": {
         "bool": {
           "must": [],
           "filter": [],
           "must_not": [],
           "should": []
         }
       }
    };
  }

  /**
  * Adds a sort param. Takes a string or object. These are stackable
  * so multiple sorts can be applied.
  *
  *   ```json
  *   Example use:
  *   let es, myQuery;
  *   es = new esQuery();
  *   es.addSort('title');
  *   es.addSort({'date' : { 'order': 'asc'}});
  *   ```
  *
  *   ```json
  *   Example Sorts
  *   `simple sort`
  *   "user"
  *
  *   `less simple sort`
  *   { "name": "asc" }
  *
  *   `complexish simple sort`
  *   { "post_date": { "order": "asc"} }
  *
  * @method addSort
  * @param {Object} sort Sort object/string to be added.
  */
  addSort(sort) {
    this.sort.push(sort);
  }

  /**
  * Adds a sort param.
  *
  * @method _addDefaultSort
  * @private
  */
  _addDefaultSort() {
    let options = this.options;
    let sort;

    if (options.sort) {
      if (options.sortType) {
        let defaultSort = {};

        defaultSort[options.sort] = options.sortType;
        sort = defaultSort;
      }
      else {
        sort = options.sort;
      }

      this._defaultSortSet = true;
      this.addSort(sort);
    }
  }

  /**
  * Public:
  * Adds a query to Bool. Allows for complex queries.
  *
  *   ```json
  *   Example objects:
  *
  *   `complex match`
  *   {
  *     "match": {
  *       "message": {
  *         "query": "to be or not to be",
  *         "operator": "and",
  *         "zero_terms_query": "all"
  *       }
  *     }
  *   }
  *
  *   `simple match`
  *   {
  *     "match": {
  *       "message": "this is a test"
  *     }
  *   }
  *
  *   `other queries`
  *   {
  *     "term": {
  *       "tag": "tech"
  *     }
  *   }
  *   ```
  *
  * @method addBool
  * @param {Object} query Query parameters
  * @param {String} type Type of Bool query should be applied to.
  *                 [must,filter,must_not,should]. Defaults to 'must'.
  */
  addBool(obj, type) {
    type = type ? type : 'must';

    this._addBool(obj, type);
  }

  /**
  * Private:
  * Adds a query to Bool. Secrely.
  *
  * @method _addBool
  * @private
  * @param {Object} query Query parameters
  * @param {String} type Type of Bool query should be applied to.
  *                 [must,filter,must_not,should]. Defaults to 'must'.
  */
  _addBool(obj, type) {
    let query = this.query.query;

    if (query.bool[type]) {
      if (typeof obj === 'object') {
        query.bool[type].push(obj);
      }
    }
  }

  /**
  * Public:
  * Adds a query to Bool with the type 'match'.
  *   ```json
  *   {
  *     "match": {
  *       "{field}": "{value}"
  *     }
  *   }
  *   ```
  *
  * @method addBoolMatchField
  * @param {String} field Field name to run query against.
  * @param {String} value Value of field.
  */
  addBoolMatchField(fieldName, value) {
    let bool = {
      "match": {}
    };

    bool.match[fieldName] = value;

    this._addBool(bool, 'must');
  }

  /**
  * Public:
  * Builds the return query.
  *
  * @method buildQuery
  * @return {Object} Returns full query object.
  */
  buildQuery() {
    if (!this._defaultSortSet) {
      this._addDefaultSort();
    }

    let sort = this.sort;
    let query = this.query;
    let { from, size } = this.options;

    return { query, sort, from, size };
  }

}

export {
  EsTools,
  QueryDSL
};
<commit_msg>fix undefined<commit_after>import config from 'ember-get-config';
import Ember from 'ember';
import extend from 'ember-es-adapter/utils/extend';

const defaultQuerySize = 20;

/**
* ElasticSearch Tools for interfacing
*
* @class EsTools
* @constructor
*/
class EsTools {

  constructor () {
    this.host = config.EsAdapter.host;
    this.namespace = config.EsAdapter.namespace;
  }

  /**
  * Gets the mapping from ElasticSearch in form of array.
  *
  * @method getMapping
  * @private
  * @return {Object} Object containing arrays of mappings.
  * e.g. {'post':[{mapping:'body', type:'string'}]}
  */
  getMapping() {
    if (!this.host || !this.namespace) {
      console.log('[EsMapper][getMapping]: Host or Namespace not defined.');
      return false;
    }

    let host = this.host,
        namespace = this.namespace;

    return new Ember.RSVP.Promise(function(resolve, reject) {
      fetch(host + '/'+ namespace + '/_mappings')
        .then((resp) => {
          let r = resp.json(),
              types = {};

          r.then((result) => {
              for (var i in result) {
                if (result[i]['mappings']) {
                  let _types = result[i]['mappings'];

                  for (var j in _types) {
                    if (_types[j]) {
                      let _properties = _types[j]['properties'];
                      let _propKeys = Object.keys(_properties);

                      types[j] = [];

                      for (var k=0; k < _propKeys.length; k++) {
                        types[j].push({
                          'mapping': _propKeys[k],
                          'type': _properties[_propKeys[k]].type
                        });
                      }

                      resolve(types);
                    }
                    else {
                      reject('[EsMapper][getMapping]: No Types Found.');
                    }
                  }
                }
                else {
                  reject('[EsMapper][getMapping]: No Mappings Found.');
                }
              }
            });

          });

    });
  }

  getTrue() {
    return true;
  }

  getLastId(index,field) {
    let host = this.host,
        namespace = this.namespace,
        queryString = "_search?query=match_all&size=1&fields=" + field + "&sort=" + field + ":desc",
        url = [host, namespace, index, queryString].join('/');

    return new Ember.RSVP.Promise(function(resolve, reject) {
      fetch(url)
        .then((resp) => {
          resp.json()
            .then((json) => {
              if (json && json.hits.hits.length) {
                resolve(parseInt(json.hits.hits[0]._id));
              }
              else {
                reject('[EsMapper][getLastId]: No Response.');
              }
            });
        });
    });
  }

}

/**
* ElasticSearch Tools for interfacing
*
* @class EsTools
* @constructor
*/
class QueryDSL {

  constructor (opts) {
    this.opts = JSON.parse(JSON.stringify(opts)) || null;
    this.sort = [];
    this.options = this._options(opts);
    this._defaultSortSet = false;

  }

  /**
  * Private:
  * Sets the options variable for the class.
  *
  * @method _options
  * @private
  * @param {Object} options Overrides for the class.
  * @return {Object} default = { 'sortType': 'desc', 'sort': '_score' };
  */
  _options(options) {
    options = options ? options : {};
    options.esParams = options.esParams ? options.esParams: {};

    let defaults = {
      'from': 0,
      'size': defaultQuerySize
    };

    options = extend(defaults, options, options.esParams);

    if (options.page) {
      options.from = this._getOffsetFromPage(options.page, options.size);
    }

    return options;
  }

  query() {
    this._query = { query: {} };
    return this;
  }

  match(options) {
    this._add('match', options);
    return this;
  }

  match_phrase(options) {
    this._add('match_phrase', options);
    return this;
  }

  multi_match(options) {
    this._add('multi_match', options);
    return this;
  }

  bool(kind) {
    this._addParent('bool', kind);
    return this;
  }

  getThis() {
    return this._query;
  }

  _add(type, options) {
    if (options == null) {
      options = {};
    }

    let params = {};
    params[type] = options;

    return this._query.query[type] = options;
  }

  _addParent(type, kind) {
    let params = {};
    params[type] = {};
    params[type][kind] = {};

    return this._query[type] = params;
  }

  /**
  * Private:
  * Convert page to offset for use with pagination

  * @method _getOffsetFromPage
  * @private
  * @param {Integer} page Page that request is on.
  * @param {Integer} size Size of pages (optional).
  * @return {Integer} Returns offset.
  */
  _getOffsetFromPage(page, size) {
    size = size ? size : defaultQuerySize;

    return page * size;
  }

  /**
  * Public:
  * Returns options from the class.
  *
  * @method getOptions
  * @return {Object} { 'sortType': 'desc', 'sort': '_score' }
  */
  getOptions() {
    return this.options;
  }

  /**
  * Private:
  * Generates the template for a "Bool" query.
  *   ```json
  *   {
  *     "query": {
  *       "bool": {
  *         "must": [],
  *         "filter": [],
  *         "must_not": [],
  *         "should": [],
  *       }
  *     }
  *   }
  *   ```
  *
  * @method _templateBoolQuery
  * @private
  * @return {Object} Returns the default structure for the query.
  */
  _templateBoolQuery() {
    return {
       "query": {
         "bool": {
           "must": [],
           "filter": [],
           "must_not": [],
           "should": []
         }
       }
    };
  }

  /**
  * Adds a sort param. Takes a string or object. These are stackable
  * so multiple sorts can be applied.
  *
  *   ```json
  *   Example use:
  *   let es, myQuery;
  *   es = new esQuery();
  *   es.addSort('title');
  *   es.addSort({'date' : { 'order': 'asc'}});
  *   ```
  *
  *   ```json
  *   Example Sorts
  *   `simple sort`
  *   "user"
  *
  *   `less simple sort`
  *   { "name": "asc" }
  *
  *   `complexish simple sort`
  *   { "post_date": { "order": "asc"} }
  *
  * @method addSort
  * @param {Object} sort Sort object/string to be added.
  */
  addSort(sort) {
    this.sort.push(sort);
  }

  /**
  * Adds a sort param.
  *
  * @method _addDefaultSort
  * @private
  */
  _addDefaultSort() {
    let options = this.options;
    let sort;

    if (options.sort) {
      if (options.sortType) {
        let defaultSort = {};

        defaultSort[options.sort] = options.sortType;
        sort = defaultSort;
      }
      else {
        sort = options.sort;
      }

      this._defaultSortSet = true;
      this.addSort(sort);
    }
  }

  /**
  * Public:
  * Adds a query to Bool. Allows for complex queries.
  *
  *   ```json
  *   Example objects:
  *
  *   `complex match`
  *   {
  *     "match": {
  *       "message": {
  *         "query": "to be or not to be",
  *         "operator": "and",
  *         "zero_terms_query": "all"
  *       }
  *     }
  *   }
  *
  *   `simple match`
  *   {
  *     "match": {
  *       "message": "this is a test"
  *     }
  *   }
  *
  *   `other queries`
  *   {
  *     "term": {
  *       "tag": "tech"
  *     }
  *   }
  *   ```
  *
  * @method addBool
  * @param {Object} query Query parameters
  * @param {String} type Type of Bool query should be applied to.
  *                 [must,filter,must_not,should]. Defaults to 'must'.
  */
  addBool(obj, type) {
    type = type ? type : 'must';

    this._addBool(obj, type);
  }

  /**
  * Private:
  * Adds a query to Bool. Secrely.
  *
  * @method _addBool
  * @private
  * @param {Object} query Query parameters
  * @param {String} type Type of Bool query should be applied to.
  *                 [must,filter,must_not,should]. Defaults to 'must'.
  */
  _addBool(obj, type) {
    let query = this.query.query;

    if (query.bool[type]) {
      if (typeof obj === 'object') {
        query.bool[type].push(obj);
      }
    }
  }

  /**
  * Public:
  * Adds a query to Bool with the type 'match'.
  *   ```json
  *   {
  *     "match": {
  *       "{field}": "{value}"
  *     }
  *   }
  *   ```
  *
  * @method addBoolMatchField
  * @param {String} field Field name to run query against.
  * @param {String} value Value of field.
  */
  addBoolMatchField(fieldName, value) {
    let bool = {
      "match": {}
    };

    bool.match[fieldName] = value;

    this._addBool(bool, 'must');
  }

  /**
  * Public:
  * Builds the return query.
  *
  * @method buildQuery
  * @return {Object} Returns full query object.
  */
  buildQuery() {
    if (!this._defaultSortSet) {
      this._addDefaultSort();
    }

    let sort = this.sort;
    let query = this.query;
    let { from, size } = this.options;

    return { query, sort, from, size };
  }

}

export {
  EsTools,
  QueryDSL
};
<|endoftext|>


<commit_before>import Ember from 'ember';
import Panel from 'furnace-forms/controls/panel';
export default function(object,silent) {
	var objectName=null;
	if(typeof object === 'string') {
		objectName=object;
	}
	else if(object instanceof Ember.Route) {
		objectName=object.routeName;
	}
	else if(Ember.ControllerMixin.detect(object)) {
		var tmpName = object.constructor.toString();
		var index=tmpName.indexOf(':');
		objectName=tmpName.substring(index+1,tmpName.indexOf(':',index+1)).replace(/\//g,'.');
	} else if(object instanceof Panel) {
		objectName=object.get('layoutName');
	} else if(object instanceof Ember.Component) {
		objectName=object.get('layoutName');
	} else if(object instanceof Ember.Object) {
		if(object.constructor.modelName!==undefined) {
			objectName=object.constructor.modelName;
		} else {
			objectName=object.constructor.typeKey;
		}
	}
//	else {
//		Ember.warn('Can not determine form for type '+(typeof object));
//		console.trace();
//	}

	if(!silent) {
		Ember.warn('Unable to determine form for type '+(typeof object),objectName,{id:'furnace-forms:name-lookup'});
	}
	return objectName;
}<commit_msg>Updated get-name to get form name for a model behind a proxy<commit_after>import Ember from 'ember';
import Panel from 'furnace-forms/controls/panel';
import { ProxyMixin } from 'furnace-forms/proxy';

function getObjectName(object) {
	var objectName=null;
	if(object.constructor.modelName!==undefined) {
		objectName=object.constructor.modelName;
	} else if(object.constructor.typeKey!==undefined) {
		objectName=object.constructor.typeKey;
	} else {
		var tmpName = object.constructor.toString();
		var index=tmpName.indexOf(':');
		objectName=tmpName.substring(index+1,tmpName.indexOf(':',index+1)).replace(/\//g,'.');
	}
	return objectName;
}

export default function(object,silent) {
	var objectName=null;
	if(typeof object === 'string') {
		objectName=object;
	}
	else if(object instanceof Ember.Route) {
		objectName=object.routeName;
	}
	else if(Ember.ControllerMixin.detect(object)) {
		var tmpName = object.constructor.toString();
		var index=tmpName.indexOf(':');
		objectName=tmpName.substring(index+1,tmpName.indexOf(':',index+1)).replace(/\//g,'.');
	} else if(object instanceof Panel) {
		objectName=object.get('layoutName');
	} else if(object instanceof Ember.Component) {
		objectName=object.get('layoutName').replace(/\//g,'.');
	} else if(object instanceof Ember.Object) {
		// FIXME: We might want to punch through a proxy proxying another proxy
		if(ProxyMixin.detect(object) && object.get('_content')) {
			objectName=getObjectName(object.get('_content'));
		}
		if(objectName===null) {
			objectName=getObjectName(object);
		}
	}
//	else {
//		Ember.warn('Can not determine form for type '+(typeof object));
//		console.trace();
//	}

	if(!silent) {
		Ember.warn('Unable to determine form for type '+(typeof object),objectName,{id:'furnace-forms:name-lookup'});
	}
	return objectName;
}<|endoftext|>


<commit_before>var gulp = require('gulp');
var less = require('gulp-less');

module.exports = function() {
    var src = gulp.src('./build/styles/common.less');
    var dest = gulp.dest('./build/styles');

    src.pipe(less()).pipe(dest).pipe(gulp.dest('./build/assets/publish'))
};
<commit_msg>Wrong path for publish css<commit_after>var gulp = require('gulp');
var less = require('gulp-less');

module.exports = function() {
    var src = gulp.src('./build/styles/common.less');
    var dest = gulp.dest('./build/styles');

    src.pipe(less()).pipe(dest).pipe(gulp.dest('./build/publish-assets'));
};
<|endoftext|>


<commit_before>
var gulp = require('gulp');
var sass = require('gulp-sass');
var cssmin = require('gulp-cssmin');
var concat = require('gulp-concat');
var autoprefixer = require('gulp-autoprefixer');

var sassPath = require('./_config.js').sass;
var errorLog = require('./_errorLog.js').errorLog;

gulp.task('scss' , function(){
	return gulp.src( sassPath.src )
		.pipe(sass())
		.on('error' , errorLog )
		.pipe(concat('hackgen.css'))
		.pipe(autoprefixer(['last 10 version']))
		.pipe(cssmin())
		.pipe(gulp.dest( sassPath.dst ));
});<commit_msg>@import is enough in scss, remove gulp-concat<commit_after>
var gulp = require('gulp');
var sass = require('gulp-sass');
var cssmin = require('gulp-cssmin');
var autoprefixer = require('gulp-autoprefixer');

var sassPath = require('./_config.js').sass;
var errorLog = require('./_errorLog.js').errorLog;

gulp.task('scss' , function(){
	return gulp.src( sassPath.src )
		.pipe(sass())
		.on('error' , errorLog )
		.pipe(autoprefixer(['last 10 version']))
		.pipe(cssmin())
		.pipe(gulp.dest( sassPath.dst ));
});
<|endoftext|>


<commit_before>// ==========================================================================
// Project:   SproutCore - JavaScript Application Framework
// Copyright: ©3006-2009 Apple, Inc. and contributors.
// License:   Licened under MIT license (see license.js)
// ==========================================================================

module("SC.ButtonView#render");

htmlbody('');

test("Render buttons in all states and with the regular and blank theme", function() {

  var iconURL= "http://www.freeiconsweb.com/Icons/16x16_people_icons/People_046.gif";
  // default button no properties
  var button = SC.ButtonView.design()
    .layout({ centerX:0, width: 130, top: 20, height: 18 })
    .prop('theme', 'blank');

  // default button with a title
  var button2 = SC.ButtonView.design()
    .layout({ centerX:0, width: 130, top: 48, height: 18 })
    .prop('title', 'title')
    .prop('theme', 'blank');

    // default button with a title
  var button3 = SC.ButtonView.design()
    .layout({ centerX:0, width: 130, top: 76, height: 18 })
    .prop('icon', iconURL)
    .prop('theme', 'blank');
  //default button with icon and title
  var button4 = SC.ButtonView.design()
    .layout({ centerX:0, width: 130, top: 104, height: 18 })
    .prop('title', 'title , icon')
    .prop('icon', 'http://www.freeiconsweb.com/Icons/16x16_people_icons/People_046.gif')
    .prop('theme', 'blank');
  //default button with icon and title disabled
  var button5 = SC.ButtonView.design()
    .layout({ centerX:0, width: 180, top: 132, height: 18 })
    .prop('title', 'title , icon , disabled')
    .prop('icon', iconURL)
    .prop('isEnabled', NO)
    .prop('theme', 'blank');
  //default button default
  var button6 = SC.ButtonView.design()
    .layout({ centerX:0, width: 130, top: 160, height: 18 })
    .prop('title', 'isDefault')
    .prop('icon', iconURL)
    .prop('isDefault', YES)
    .prop('theme', 'blank');
  //default button isSelected
  var button7 = SC.ButtonView.design()
    .layout({ centerX:0, width: 130, top: 188, height: 18 })
    .prop('title', 'isSelected')
    .prop('icon', iconURL)
    .prop('isSelected', YES)
    .prop('theme', 'blank');
  //toggle
  var button8 = SC.ButtonView.design()
    .layout({ centerX:0, width: 130, top: 216, height: 18 })
    .prop('title', 'toggle')
    .prop('icon', iconURL)
    .prop('buttonBehavior', SC.TOGGLE_BEHAVIOR)
    .prop('theme', 'blank');

  // create design
  var pane = SC.Pane.design()
    .layout({right: 20, top: 100 , height:250, width:400})
    .childView(button)
    .childView(button2)
    .childView(button3)
    .childView(button4)
    .childView(button5)
    .childView(button6)
    .childView(button7)
    .childView(button8);

  // instantiate pane...
  pane = pane.create();

  ok(!pane.get('isVisibleInWindow'), 'pane.isVisibleInWindow should be NO');
  for(var i=0; i<pane.childViews.length; i++){
    var v=pane.childViews[i];
    ok(!v.get('isVisibleInWindow'), 'view.isVisibleInWindow should be NO');
  }

  //append
  SC.RunLoop.begin();
  pane.append();
  SC.RunLoop.end();

  for(var i=0; i<pane.childViews.length; i++){
    var v=pane.childViews[i];
    ok(v.get('isVisibleInWindow'), 'view.isVisibleInWindow should be YES');
  }

  var v=pane.childViews[0];
  ok(!v.get('icon'), 'defaultBuuttonView. should not have an icon YES');
  ok(!v.get('title'), 'defaultBuuttonView. should not have a title YES');

  rawS3HTML='';
  rawFFHTML='';

  l=v.get('layer');
  var isInParentlayer=false;

    if(l.parentNode.innerHTML.indexOf(rawS3HTML)>=0 || l.parentNode.innerHTML.indexOf(rawFFHTML)>=0)
      isInParentlayer=true;
    ok(isInParentlayer, 'rawHTML is contained in the innerHTML of the parentNode');

});
<commit_msg>updated button unit test to use controlTestPane<commit_after>// ==========================================================================
// Project:   SproutCore - JavaScript Application Framework
// Copyright: ©2006-2009 Sprout Systems, Inc. and contributors.
//            portions copyright @2009 Apple, Inc.
// License:   Licened under MIT license (see license.js)
// ==========================================================================

/*global module test htmlbody ok equals same */

htmlbody('');

  var iconURL= "http://www.freeiconsweb.com/Icons/16x16_people_icons/People_046.gif";

var pane = SC.ControlTestPane.design()
  .add("basic", SC.ButtonView, {
  })

  .add("title", SC.ButtonView, {
     title: "Hello World"
  })

  .add("icon", SC.ButtonView, {
    icon: iconURL
  })

  .add("title,icon", SC.ButtonView, {
    title: "Hello World", icon: iconURL
  })

  .add("title,icon,disabled", SC.ButtonView, {
    title: "Hello World", icon: iconURL , isEnabled: NO
  })

  .add("title,icon,default", SC.ButtonView, {
    title: "Hello World", icon: iconURL , isDefault: YES
  })

  .add("title,icon,selected", SC.ButtonView, {
    title: "Hello World", icon: iconURL , isSelected: YES
  });

pane.show(); // add a test to show the test pane

module('SC.ButtonView ui', pane.standardSetup());

test("Check that all button are visible", function() {
  ok(pane.view('basic').get('isVisibleInWindow'), 'basic.isVisibleInWindow should be YES');
  ok(pane.view('title').get('isVisibleInWindow'), 'title.isVisibleInWindow should be YES');
  ok(pane.view('icon').get('isVisibleInWindow'), 'icon.isVisibleInWindow should be YES');
  ok(pane.view('title,icon').get('isVisibleInWindow'), 'title,icon.isVisibleInWindow should be YES');
  ok(pane.view('title,icon,disabled').get('isVisibleInWindow'), 'title,icon,disabled.isVisibleInWindow should be YES');
  ok(pane.view('title,icon,default').get('isVisibleInWindow'), 'title,icon,default.isVisibleInWindow should be YES');
  ok(pane.view('title,icon,selected').get('isVisibleInWindow'), 'title.icon,selected.isVisibleInWindow should be YES');
});

test("Check that all buttons have the right classes set", function() {
  var viewElem=pane.view('basic').$();
  ok(viewElem.hasClass('sc-view'), 'basic.hasClass(sc-view) should be YES');
  ok(viewElem.hasClass('sc-button-view'), 'basic.hasClass(sc-button-view) should be YES');
  ok(viewElem.hasClass('sc-regular-size'), 'basic.hasClass(sc-regular-size) should be YES');
  ok(!viewElem.hasClass('icon'), 'basic.hasClass(icon) should be NO');
  ok(!viewElem.hasClass('sel'), 'basic.hasClass(sel) should be NO');
  ok(!viewElem.hasClass('disabled'), 'basic.hasClass(disabled) should be NO');
  ok(!viewElem.hasClass('def'), 'basic.hasClass(def) should be NO');

  viewElem=pane.view('title').$();
  ok(viewElem.hasClass('sc-view'), 'title.hasClass(sc-view) should be YES');
  ok(viewElem.hasClass('sc-button-view'), 'title.hasClass(sc-button-view) should be YES');
  ok(viewElem.hasClass('sc-regular-size'), 'title.hasClass(sc-regular-size) should be YES');
  ok(!viewElem.hasClass('icon'), 'title.hasClass(icon) should be NO');
  ok(!viewElem.hasClass('sel'), 'title.hasClass(sel) should be NO');
  ok(!viewElem.hasClass('disabled'), 'title.hasClass(disabled) should be NO');
  ok(!viewElem.hasClass('def'), 'title.hasClass(def) should be NO');

  viewElem=pane.view('icon').$();
  ok(viewElem.hasClass('sc-view'), 'icon.hasClass(sc-view) should be YES');
  ok(viewElem.hasClass('sc-button-view'), 'icon.hasClass(sc-button-view) should be YES');
  ok(viewElem.hasClass('sc-regular-size'), 'icon.hasClass(sc-regular-size) should be YES');
  ok(viewElem.hasClass('icon'), 'icon.hasClass(icon) should be YES');
  ok(!viewElem.hasClass('sel'), 'icon.hasClass(sel) should be NO');
  ok(!viewElem.hasClass('disabled'), 'icon.hasClass(disabled) should be NO');
  ok(!viewElem.hasClass('def'), 'icon.hasClass(def) should be NO');

  viewElem=pane.view('title,icon').$();
  ok(viewElem.hasClass('sc-view'), 'title,icon.hasClass(sc-view) should be YES');
  ok(viewElem.hasClass('sc-button-view'), 'title,icon.hasClass(sc-button-view) should be YES');
  ok(viewElem.hasClass('sc-regular-size'), 'title,icon.hasClass(sc-regular-size) should be YES');
  ok(viewElem.hasClass('icon'), 'title,icon.hasClass(icon) should be YES');
  ok(!viewElem.hasClass('sel'), 'title,icon.hasClass(sel) should be NO');
  ok(!viewElem.hasClass('disabled'), 'title,icon.hasClass(disabled) should be NO');
  ok(!viewElem.hasClass('def'), 'title,icon.hasClass(def) should be NO');

  viewElem=pane.view('title,icon,disabled').$();
  ok(viewElem.hasClass('sc-view'), 'title,icon,disabled.hasClass(sc-view) should be YES');
  ok(viewElem.hasClass('sc-button-view'), 'title,icon,disabled.hasClass(sc-button-view) should be YES');
  ok(viewElem.hasClass('sc-regular-size'), 'title,icon,disabled.hasClass(sc-regular-size) should be YES');
  ok(viewElem.hasClass('icon'), 'title,icon,disabled.hasClass(icon) should be YES');
  ok(!viewElem.hasClass('sel'), 'title,icon,disabled.hasClass(sel) should be NO');
  ok(viewElem.hasClass('disabled'), 'title,icon,disabled.hasClass(disabled) should be YES');
  ok(!viewElem.hasClass('def'), 'title,icon,disabled.hasClass(def) should be NO');

  viewElem=pane.view('title,icon,default').$();
  ok(viewElem.hasClass('sc-view'), 'title,icon,default.hasClass(sc-view) should be YES');
  ok(viewElem.hasClass('sc-button-view'), 'title,icon,default.hasClass(sc-button-view) should be YES');
  ok(viewElem.hasClass('sc-regular-size'), 'title,icon,default.hasClass(sc-regular-size) should be YES');
  ok(viewElem.hasClass('icon'), 'title,icon,default.hasClass(icon) should be YES');
  ok(!viewElem.hasClass('sel'), 'title,icon,default.hasClass(sel) should be NO');
  ok(!viewElem.hasClass('disabled'), 'title,icon,default.hasClass(disabled) should be NO');
  ok(viewElem.hasClass('def'), 'title,icon,default.hasClass(def) should be YES');

  viewElem=pane.view('title,icon,selected').$();
   ok(viewElem.hasClass('sc-view'), 'title,icon,selected.hasClass(sc-view) should be YES');
   ok(viewElem.hasClass('sc-button-view'), 'title,icon,selected.hasClass(sc-button-view) should be YES');
   ok(viewElem.hasClass('sc-regular-size'), 'title,icon,selected.hasClass(sc-regular-size) should be YES');
   ok(viewElem.hasClass('icon'), 'title,icon,selected.hasClass(icon) should be YES');
   ok(viewElem.hasClass('sel'), 'title,icon,selected.hasClass(sel) should be YES');
   ok(!viewElem.hasClass('disabled'), 'title,icon,selected.hasClass(disabled) should be NO');
   ok(!viewElem.hasClass('def'), 'title,icon,selected.hasClass(def) should be NO');

});

test("Check that the title is set or not and if it is in the appropriate element", function() {
  var viewElem=pane.view('basic').$('span');
  equals(viewElem.text(), '', 'should not have a title');

  var viewElem=pane.view('title').$('span');
  equals(viewElem.text(), 'Hello World', 'should not have a title');

  var viewElem=pane.view('icon').$('span.label.img');
  ok((viewElem!=null), 'should have an image corresponding to an icon');

});

<|endoftext|>


<commit_before>function current_project() {
    return $('h2').text();
}

function save_done(btn, succeeded, error) {
    $(btn).text("Save");
    $(btn).removeClass("disabled");
    info = $("

");
    if (succeeded) {
        info.addClass("alert-success");
        info.html("Saved");
    } else {
        info.addClass("alert-danger");
        info.html("Error: " + error);
    }
    info.insertBefore($(btn));
}

function collect_properties(btn, check_required) {
    properties = {};
    $(btn).parent().parent().find(".project-property").each(function () {
        path = $(this).data('property-path');
        if (check_required && this.required && !this.value) {
            alert($(this).parent().find("label").html() + " is required!");
            $(this).focus();
            properties = false;
            return false;
        }
        if (this.type == "number") {
            val = parseInt(this.value);
            if (isNaN(val)) {
                alert("Invalid number for " + this.name);
                $(this).focus();
                properties = false;
                return false;
            }
        } else if (this.type == "checkbox") {
            if (this.checked) {
                val = true;
            } else {
                val = false;
            }
        } else {
            val = this.value;
        }
        properties[path] = val;
    });
    return properties;
}

function properties_save(btn) {
    if ($(btn).hasClass("disabled")) {
        return;
    }
    props = collect_properties(btn, true);
    if (!props) {
        return;
    }
    $(btn).addClass("disabled");
    $(btn).text("Saving...");
    $(btn).parent().find(".save-message").remove();
    patchew_api_do("set-project-properties",
                   { project: current_project(),
                     properties: props })
        .done(function (data) {
            save_done(btn, true);
        })
        .fail(function (data, text, error) {
            save_done(btn, false, error);
        });
}

function collect_items(btn) {
    $(btn).parent().parent().find(".map-item");
    return {};
}

function map_add_item(btn) {
    name = window.prompt("Please input a name");
    if (!name || name == 'null') {
        return;
    }
    container = $(btn).parent().parent();
    if (name in collect_items(btn)) {
        alert(test_name + " already exists.");
        return;
    }
    if (name.indexOf(".") >= 0) {
        alert("Invalid name, no dot is allowed.");
        return;
    }
    tmpl = container.find(".item-template").html();
    nt = $(tmpl);
    nt.find(".item-name").text(name);
    prefix = nt.data('property-prefix') + '.' + name;
    nt.data('property-prefix', prefix);
    nt.find(".project-property").each(function() {
        old = $(this).data('property-path');
        $(this).data('property-path', prefix + old);
    });
    nt.find(".panel-collapse").collapse("show");
    container.find("> .items").append(nt);
}

function map_delete_item(btn) {
    item = $(btn).parent().parent().parent();
    name = item.find(".item-name").text();
    prefix = item.data('property-prefix') + ".";
    if (!window.confirm("Really delete '" + name +"'?")) {
        return;
    }
    $(btn).addClass("disabled");
    $(btn).text("Deleting...");
    $(btn).parent().find(".delete-message").remove();
    patchew_api_do("delete-project-properties-by-prefix",
                   { project: current_project(),
                     prefix: prefix })
        .done(function (data) {
            item.remove();
        })
        .fail(function (data, text, error) {
            $(btn).removeClass("disabled");
            $(btn).text("Delete");
            info = $("

");
            info.html("Error: " + error);
            info.insertBefore($(btn));
        });
}
function enum_change(which) {
    val = $(which).val();
    desc = $(which).parent().find("#enum-desc-" + val).html();
    $(which).parent().find("#enum-desc").html(desc);
}
<commit_msg>mod: do not allow creating duplicate map items<commit_after>function current_project() {
    return $('h2').text();
}

function save_done(btn, succeeded, error) {
    $(btn).text("Save");
    $(btn).removeClass("disabled");
    info = $("

");
    if (succeeded) {
        info.addClass("alert-success");
        info.html("Saved");
    } else {
        info.addClass("alert-danger");
        info.html("Error: " + error);
    }
    info.insertBefore($(btn));
}

function collect_properties(btn, check_required) {
    properties = {};
    $(btn).parent().parent().find(".project-property").each(function () {
        path = $(this).data('property-path');
        if (check_required && this.required && !this.value) {
            alert($(this).parent().find("label").html() + " is required!");
            $(this).focus();
            properties = false;
            return false;
        }
        if (this.type == "number") {
            val = parseInt(this.value);
            if (isNaN(val)) {
                alert("Invalid number for " + this.name);
                $(this).focus();
                properties = false;
                return false;
            }
        } else if (this.type == "checkbox") {
            if (this.checked) {
                val = true;
            } else {
                val = false;
            }
        } else {
            val = this.value;
        }
        properties[path] = val;
    });
    return properties;
}

function properties_save(btn) {
    if ($(btn).hasClass("disabled")) {
        return;
    }
    props = collect_properties(btn, true);
    if (!props) {
        return;
    }
    $(btn).addClass("disabled");
    $(btn).text("Saving...");
    $(btn).parent().find(".save-message").remove();
    patchew_api_do("set-project-properties",
                   { project: current_project(),
                     properties: props })
        .done(function (data) {
            save_done(btn, true);
        })
        .fail(function (data, text, error) {
            save_done(btn, false, error);
        });
}

function collect_items(container) {
    return container.find("> .items > .item > .item-heading > .item-name").map(function() {
        return $(this).text();
    }).get();
}

function map_add_item(btn) {
    name = window.prompt("Please input a name");
    if (!name || name == 'null') {
        return;
    }
    container = $(btn).parent().parent();
    if (collect_items(container).includes(name)) {
        alert(name + " already exists.");
        return;
    }
    if (name.indexOf(".") >= 0) {
        alert("Invalid name, no dot is allowed.");
        return;
    }
    tmpl = container.find(".item-template").html();
    nt = $(tmpl);
    nt.find(".item-name").text(name);
    prefix = nt.data('property-prefix') + '.' + name;
    nt.data('property-prefix', prefix);
    nt.find(".project-property").each(function() {
        old = $(this).data('property-path');
        $(this).data('property-path', prefix + old);
    });
    nt.find(".panel-collapse").collapse("show");
    container.find("> .items").append(nt);
}

function map_delete_item(btn) {
    item = $(btn).parent().parent().parent();
    name = item.find(".item-name").text();
    prefix = item.data('property-prefix') + ".";
    if (!window.confirm("Really delete '" + name +"'?")) {
        return;
    }
    $(btn).addClass("disabled");
    $(btn).text("Deleting...");
    $(btn).parent().find(".delete-message").remove();
    patchew_api_do("delete-project-properties-by-prefix",
                   { project: current_project(),
                     prefix: prefix })
        .done(function (data) {
            item.remove();
        })
        .fail(function (data, text, error) {
            $(btn).removeClass("disabled");
            $(btn).text("Delete");
            info = $("

");
            info.html("Error: " + error);
            info.insertBefore($(btn));
        });
}
function enum_change(which) {
    val = $(which).val();
    desc = $(which).parent().find("#enum-desc-" + val).html();
    $(which).parent().find("#enum-desc").html(desc);
}
<|endoftext|>