diff --git a/static/js/framework/framework-menu.js b/static/js/framework/framework-menu.js
new file mode 100644
index 0000000..35bbebc
--- /dev/null
+++ b/static/js/framework/framework-menu.js
@@ -0,0 +1,566 @@
+/* Copyright 2016 The Chromium Authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://developers.google.com/open-source/licenses/bsd
+ */
+
+/**
+ * @fileoverview This file represents a standalone, reusable drop down menu
+ * widget that can be attached to any element on a given page. It supports
+ * multiple instances of the widget on a page. It has no dependencies. Usage
+ * is as simple as creating a new Menu object and supplying it with a target
+ * element.
+ */
+
+/**
+ * The entry point and constructor for the Menu object. Creating
+ * a valid instance of this object will insert a drop down menu
+ * near the element supplied as the target, attach all the necessary
+ * events and insert the necessary elements on the page.
+ *
+ * @param {Element} target the target element on the page to which
+ *     the drop down menu will be placed near.
+ * @param {Function=} opt_onShow function to execute every time the
+ *     menu is made visible, most likely through a click on the target.
+ * @constructor
+ */
+var Menu = function(target, opt_onShow) {
+  this.iid = Menu.instance.length;
+  Menu.instance[this.iid] = this;
+  this.target = target;
+  this.onShow = opt_onShow || null;
+
+  // An optional trigger element on the page that can be used to trigger
+  // the drop-down. Currently hard-coded to be the same as the target element.
+  this.trigger = target;
+  this.items = [];
+  this.onOpenEvents = [];
+  this.menu = this.createElement('div', 'menuDiv instance' + this.iid);
+  this.targetId = this.target.getAttribute('id');
+  let menuId = (this.targetId != null) ?
+    'menuDiv-' + this.targetId : 'menuDiv-instance' + this.iid;
+  this.menu.setAttribute('id', menuId);
+  this.menu.role = 'listbox';
+  this.hide();
+  this.addCategory('default');
+  this.addEvent(this.trigger, 'click', this.toggle.bind(this));
+  this.addEvent(window, 'resize', this.adjustSizeAndLocation.bind(this));
+
+  // Hide the menu if a user clicks outside the menu widget
+  this.addEvent(document, 'click', this.hide.bind(this));
+  this.addEvent(this.menu, 'click', this.stopPropagation());
+  this.addEvent(this.trigger, 'click', this.stopPropagation());
+};
+
+// A reference to the element or node that the drop down
+// will appear next to
+Menu.prototype.target = null;
+
+// Element ID of the target. ID will be assigned to the newly created
+// menu div based on the target ID. A default ID will be
+// assigned If there is no ID on the target.
+Menu.prototype.targetId = null;
+
+/**
+ * A reference to the element or node that will trigger
+ * the drop down to appear. If not specified, this value
+ * will be the same as <Menu Instance>.target
+ * @type {Element}
+ */
+Menu.prototype.trigger = null;
+
+// A reference to the event type that will "open" the
+// menu div. By default this is the (on)click method.
+Menu.prototype.triggerType = null;
+
+// A reference to the element that will appear when the
+// trigger is clicked.
+Menu.prototype.menu = null;
+
+/**
+ * Function to execute every time the menu is made shown.
+ * @type {Function}
+ */
+Menu.prototype.onShow = null;
+
+// A list of category divs. By default these categories
+// are set to display none until at least one element
+// is placed within them.
+Menu.prototype.categories = null;
+
+// An id used to track timed intervals
+Menu.prototype.thread = -1;
+
+// The static instance id (iid) denoting which menu in the
+// list of Menu.instance items is this instantiated object.
+Menu.prototype.iid = -1;
+
+// A counter to indicate the number of items added with
+// addItem(). After 5 items, a height is set on the menu
+// and a scroll bar will appear.
+Menu.prototype.items = null;
+
+// A flag to detect whether or not a scroll bar has been added
+Menu.prototype.scrolls = false;
+
+// onOpen event handlers; each function in this list will
+// be executed and passed the executing instance as a
+// parameter before the menu is to be displayed.
+Menu.prototype.onOpenEvents = null;
+
+/**
+ * An extended short-cut for document.createElement(); this
+ * method allows the creation of an element, the assignment
+ * of one or more class names and the ability to set the
+ * content of the created element all with one function call.
+ * @param {string} element name of the element to create. Examples would
+ *     be 'div' or 'a'.
+ * @param {string} opt_className an optional string to assign to the
+ *     newly created element's className property.
+ * @param {string|Element} opt_content either a snippet of HTML or a HTML
+ *     element that is to be appended to the newly created element.
+ * @return {Element} a reference to the newly created element.
+ */
+Menu.prototype.createElement = function(element, opt_className, opt_content) {
+  let div = document.createElement(element);
+  div.className = opt_className;
+  if (opt_content) {
+    this.append(opt_content, div);
+  }
+  return div;
+};
+
+/**
+ * Uses a fairly browser agnostic approach to applying a callback to
+ * an element on the page.
+ *
+ * @param {Element|EventTarget} element a reference to an element on the page to
+ *     which to attach and event.
+ * @param {string} eventType a browser compatible event type as a string
+ *     without the sometimes assumed on- prefix. Examples: 'click',
+ *     'mousedown', 'mouseover', etc...
+ * @param {Function} callback a function reference to invoke when the
+ *     the event occurs.
+ */
+Menu.prototype.addEvent = function(element, eventType, callback) {
+  if (element.addEventListener) {
+    element.addEventListener(eventType, callback, false);
+  } else {
+    try {
+      element.attachEvent('on' + eventType, callback);
+    } catch (e) {
+      element['on' + eventType] = callback;
+    }
+  }
+};
+
+/**
+ * Similar to addEvent, this provides a specialied handler for onOpen
+ * events that apply to this instance of the Menu class. The supplied
+ * callbacks are appended to an internal array and called in order
+ * every time the menu is opened. The array can be accessed via
+ * menuInstance.onOpenEvents.
+ */
+Menu.prototype.addOnOpen = function(eventCallback) {
+  let eventIndex = this.onOpenEvents.length;
+  this.onOpenEvents.push(eventCallback);
+  return eventIndex;
+};
+
+/**
+ * This method will create a div with the classes .menuCategory and the
+ * name of the category as supplied in the first parameter. It then, if
+ * a title is supplied, creates a title div and appends it as well. The
+ * optional title is styled with the .categoryTitle and category name
+ * class.
+ *
+ * Categories are stored within the menu object instance for programmatic
+ * manipulation in the array, menuInstance.categories. Note also that this
+ * array is doubly linked insofar as that the category div can be accessed
+ * via it's index in the array as well as by instance.categories[category]
+ * where category is the string name supplied when creating the category.
+ *
+ * @param {string} category the string name used to create the category;
+ *     used as both a class name and a key into the internal array. It
+ *     must be a valid JavaScript variable name.
+ * @param {string|Element} opt_title this optional field is used to visibly
+ *     denote the category title. It can be either HTML or an element.
+ * @return {Element} the newly created div.
+ */
+Menu.prototype.addCategory = function(category, opt_title) {
+  this.categories = this.categories || [];
+  let categoryDiv = this.createElement('div', 'menuCategory ' + category);
+  categoryDiv._categoryName = category;
+  if (opt_title) {
+    let categoryTitle = this.createElement('b', 'categoryTitle ' +
+          category, opt_title);
+    categoryTitle.style.display = 'block';
+    this.append(categoryTitle);
+    categoryDiv._categoryTitle = categoryTitle;
+  }
+  this.append(categoryDiv);
+  this.categories[this.categories.length] = this.categories[category] =
+      categoryDiv;
+
+  return categoryDiv;
+};
+
+/**
+ * This method removes the contents of a given category but does not
+ * remove the category itself.
+ */
+Menu.prototype.emptyCategory = function(category) {
+  if (!this.categories[category]) {
+    return;
+  }
+  let div = this.categories[category];
+  for (let i = div.childNodes.length - 1; i >= 0; i--) {
+    div.removeChild(div.childNodes[i]);
+  }
+};
+
+/**
+ * This function is the most drastic of the cleansing functions; it removes
+ * all categories and all menu items and all HTML snippets that have been
+ * added to this instance of the Menu class.
+ */
+Menu.prototype.clear = function() {
+  for (var i = 0; i < this.categories.length; i++) {
+    // Prevent memory leaks
+    this.categories[this.categories[i]._categoryName] = null;
+  }
+  this.items.splice(0, this.items.length);
+  this.categories.splice(0, this.categories.length);
+  this.categories = [];
+  this.items = [];
+  for (var i = this.menu.childNodes.length - 1; i >= 0; i--) {
+    this.menu.removeChild(this.menu.childNodes[i]);
+  }
+};
+
+/**
+ * Passed an instance of a menu item, it will be removed from the menu
+ * object, including any residual array links and possible memory leaks.
+ * @param {Element} item a reference to the menu item to remove.
+ * @return {Element} returns the item removed.
+ */
+Menu.prototype.removeItem = function(item) {
+  let result = null;
+  for (let i = 0; i < this.items.length; i++) {
+    if (this.items[i] == item) {
+      result = this.items[i];
+      this.items.splice(i, 1);
+    }
+    // Renumber
+    this.items[i].item._index = i;
+  }
+  return result;
+};
+
+/**
+ * Removes a category from the menu element and all of its children thus
+ * allowing the Element to be collected by the browsers VM.
+ * @param {string} category the name of the category to retrieve and remove.
+ */
+Menu.prototype.removeCategory = function(category) {
+  let div = this.categories[category];
+  if (!div || !div.parentNode) {
+    return;
+  }
+  if (div._categoryTitle) {
+    div._categoryTitle.parentNode.removeChild(div._categoryTitle);
+  }
+  div.parentNode.removeChild(div);
+  for (var i = 0; i < this.categories.length; i++) {
+    if (this.categories[i] === div) {
+      this.categories[this.categories[i]._categoryName] = null;
+      this.categories.splice(i, 1);
+      return;
+    }
+  }
+  for (var i = 0; i < div.childNodes.length; i++) {
+    if (div.childNodes[i]._index) {
+      this.items.splice(div.childNodes[i]._index, 1);
+    } else {
+      this.removeItem(div.childNodes[i]);
+    }
+  }
+};
+
+/**
+ * This heart of the menu population scheme, the addItem function creates
+ * a combination of elements that visually form up a menu item. If no
+ * category is supplied, the default category is used. The menu item is
+ * an <a> tag with the class .menuItem. The menu item is directly styled
+ * as a block element. Other than that, all styling should be done via a
+ * external CSS definition.
+ *
+ * @param {string|Element} html_or_element a string of HTML text or a
+ *     HTML element denoting the contents of the menu item.
+ * @param {string} opt_href the href of the menu item link. This is
+ *     the most direct way of defining the menu items function.
+ *     [Default: '#'].
+ * @param {string} opt_category the category string name of the category
+ *     to append the menu item to. If the category doesn't exist, one will
+ *     be created. [Default: 'default'].
+ * @param {string} opt_title used when creating a new category and is
+ *     otherwise ignored completely. It is also ignored when supplied if
+ *     the named category already exists.
+ * @return {Element} returns the element that was created.
+ */
+Menu.prototype.addItem = function(html_or_element, opt_href, opt_category,
+  opt_title) {
+  let category = opt_category ? (this.categories[opt_category] ||
+                                 this.addCategory(opt_category, opt_title)) :
+    this.categories['default'];
+  let menuHref = (opt_href == undefined ? '#' : opt_href);
+  let menuItem = undefined;
+  if (menuHref) {
+    menuItem = this.createElement('a', 'menuItem', html_or_element);
+  } else {
+    menuItem = this.createElement('span', 'menuText', html_or_element);
+  }
+  let itemText = typeof html_or_element == 'string' ? html_or_element :
+    html_or_element.textContent || 'ERROR';
+
+  menuItem.style.display = 'block';
+  if (menuHref) {
+    menuItem.setAttribute('href', menuHref);
+  }
+  menuItem._index = this.items.length;
+  menuItem.role = 'option';
+  this.append(menuItem, category);
+  this.items[this.items.length] = {item: menuItem, text: itemText};
+
+  return menuItem;
+};
+
+/**
+ * Adds a visual HTML separator to the menu, optionally creating a
+ * category as per addItem(). See above.
+ * @param {string} opt_category the category string name of the category
+ *     to append the menu item to. If the category doesn't exist, one will
+ *     be created. [Default: 'default'].
+ * @param {string} opt_title used when creating a new category and is
+ *     otherwise ignored completely. It is also ignored when supplied if
+ *     the named category already exists.
+ */
+Menu.prototype.addSeparator = function(opt_category, opt_title) {
+  let category = opt_category ? (this.categories[opt_category] ||
+                                 this.addCategory(opt_category, opt_title)) :
+    this.categories['default'];
+  let hr = this.createElement('hr', 'menuSeparator');
+  this.append(hr, category);
+};
+
+/**
+ * This method performs all the dirty work of positioning the menu. It is
+ * responsible for dynamic sizing, insertion and deletion of scroll bars
+ * and calculation of offscreen width considerations.
+ */
+Menu.prototype.adjustSizeAndLocation = function() {
+  let style = this.menu.style;
+  style.position = 'absolute';
+
+  let firstCategory = null;
+  for (let i = 0; i < this.categories.length; i++) {
+    this.categories[i].className = this.categories[i].className.
+      replace(/ first/, '');
+    if (this.categories[i].childNodes.length == 0) {
+      this.categories[i].style.display = 'none';
+    } else {
+      this.categories[i].style.display = '';
+      if (!firstCategory) {
+        firstCategory = this.categories[i];
+        firstCategory.className += ' first';
+      }
+    }
+  }
+
+  let alreadyVisible = style.display != 'none' &&
+      style.visibility != 'hidden';
+  let docElemWidth = document.documentElement.clientWidth;
+  let docElemHeight = document.documentElement.clientHeight;
+  let pageSize = {
+    w: (window.innerWidth || docElemWidth && docElemWidth > 0 ?
+      docElemWidth : document.body.clientWidth) || 1,
+    h: (window.innerHeight || docElemHeight && docElemHeight > 0 ?
+      docElemHeight : document.body.clientHeight) || 1,
+  };
+  let targetPos = this.find(this.target);
+  let targetSize = {w: this.target.offsetWidth,
+    h: this.target.offsetHeight};
+  let menuSize = {w: this.menu.offsetWidth, h: this.menu.offsetHeight};
+
+  if (!alreadyVisible) {
+    let oldVisibility = style.visibility;
+    let oldDisplay = style.display;
+    style.visibility = 'hidden';
+    style.display = '';
+    style.height = '';
+    style.width = '';
+    menuSize = {w: this.menu.offsetWidth, h: this.menu.offsetHeight};
+    style.display = oldDisplay;
+    style.visibility = oldVisibility;
+  }
+
+  let addScroll = (this.menu.offsetHeight / pageSize.h) > 0.8;
+  if (addScroll) {
+    menuSize.h = parseInt((pageSize.h * 0.8), 10);
+    style.height = menuSize.h + 'px';
+    style.overflowX = 'hidden';
+    style.overflowY = 'auto';
+  } else {
+    style.height = style.overflowY = style.overflowX = '';
+  }
+
+  style.top = (targetPos.y + targetSize.h) + 'px';
+  style.left = targetPos.x + 'px';
+
+  if (menuSize.w < 175) {
+    style.width = '175px';
+  }
+
+  if (addScroll) {
+    style.width = parseInt(style.width, 10) + 13 + 'px';
+  }
+
+  if ((targetPos.x + menuSize.w) > pageSize.w) {
+    style.left = targetPos.x - (menuSize.w - targetSize.w) + 'px';
+  }
+};
+
+
+/**
+ * This function is used heavily, internally. It appends text
+ * or the supplied element via appendChild(). If
+ * the opt_target variable is present, the supplied element will be
+ * the container rather than the menu div for this instance.
+ *
+ * @param {string|Element} text_or_element the html or element to insert
+ *     into opt_target.
+ * @param {Element} opt_target the target element it should be appended to.
+ *
+ */
+Menu.prototype.append = function(text_or_element, opt_target) {
+  let element = opt_target || this.menu;
+  if (typeof opt_target == 'string' && this.categories[opt_target]) {
+    element = this.categories[opt_target];
+  }
+  if (typeof text_or_element == 'string') {
+    element.textContent += text_or_element;
+  } else {
+    element.appendChild(text_or_element);
+  }
+};
+
+/**
+ * Displays the menu (such as upon mouseover).
+ */
+Menu.prototype.over = function() {
+  if (this.menu.style.display != 'none') {
+    this.show();
+  }
+  if (this.thread != -1) {
+    clearTimeout(this.thread);
+    this.thread = -1;
+  }
+};
+
+/**
+ * Hides the menu (such as upon mouseout).
+ */
+Menu.prototype.out = function() {
+  if (this.thread != -1) {
+    clearTimeout(this.thread);
+    this.thread = -1;
+  }
+  this.thread = setTimeout(this.hide.bind(this), 400);
+};
+
+/**
+ * Stops event propagation.
+ */
+Menu.prototype.stopPropagation = function() {
+  return (function(e) {
+    if (!e) {
+      e = window.event;
+    }
+    e.cancelBubble = true;
+    if (e.stopPropagation) {
+      e.stopPropagation();
+    }
+  });
+};
+
+/**
+ * Toggles the menu between hide/show.
+ */
+Menu.prototype.toggle = function(event) {
+  event.preventDefault();
+  if (this.menu.style.display == 'none') {
+    this.show();
+  } else {
+    this.hide();
+  }
+};
+
+/**
+ * Makes the menu visible, then calls the user-supplied onShow callback.
+ */
+Menu.prototype.show = function() {
+  if (this.menu.style.display != '') {
+    for (var i = 0; i < this.onOpenEvents.length; i++) {
+      this.onOpenEvents[i].call(null, this);
+    }
+
+    // Invisibly show it first
+    this.menu.style.visibility = 'hidden';
+    this.menu.style.display = '';
+    this.adjustSizeAndLocation();
+    if (this.trigger.nodeName && this.trigger.nodeName == 'A') {
+      this.trigger.blur();
+    }
+    this.menu.style.visibility = 'visible';
+
+    // Hide other menus
+    for (var i = 0; i < Menu.instance.length; i++) {
+      let menuInstance = Menu.instance[i];
+      if (menuInstance != this) {
+        menuInstance.hide();
+      }
+    }
+
+    if (this.onShow) {
+      this.onShow();
+    }
+  }
+};
+
+/**
+ * Makes the menu invisible.
+ */
+Menu.prototype.hide = function() {
+  this.menu.style.display = 'none';
+};
+
+Menu.prototype.find = function(element) {
+  let curleft = 0, curtop = 0;
+  if (element.offsetParent) {
+    do {
+      curleft += element.offsetLeft;
+      curtop += element.offsetTop;
+    }
+    while ((element = element.offsetParent) && (element.style &&
+          element.style.position != 'relative' &&
+          element.style.position != 'absolute'));
+  }
+  return {x: curleft, y: curtop};
+};
+
+/**
+ * A static array of object instances for global reference.
+ * @type {Array.<Menu>}
+ */
+Menu.instance = [];
