diff --git a/planetstack/core/xoslib/static/js/vendor/backbone.syphon.js b/planetstack/core/xoslib/static/js/vendor/backbone.syphon.js
new file mode 100644
index 0000000..3cd1537
--- /dev/null
+++ b/planetstack/core/xoslib/static/js/vendor/backbone.syphon.js
@@ -0,0 +1,469 @@
+// Backbone.Syphon, v0.4.1
+// Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
+// Distributed under MIT license
+// http://github.com/derickbailey/backbone.syphon
+Backbone.Syphon = (function(Backbone, $, _){
+  var Syphon = {};
+
+  // Ignore Element Types
+  // --------------------
+
+  // Tell Syphon to ignore all elements of these types. You can
+  // push new types to ignore directly in to this array.
+  Syphon.ignoredTypes = ["button", "submit", "reset", "fieldset"];
+
+  // Syphon
+  // ------
+
+  // Get a JSON object that represents
+  // all of the form inputs, in this view.
+  // Alternately, pass a form element directly
+  // in place of the view.
+  Syphon.serialize = function(view, options){
+    var data = {};
+
+    // Build the configuration
+    var config = buildConfig(options);
+
+    // Get all of the elements to process
+    var elements = getInputElements(view, config);
+
+    // Process all of the elements
+    _.each(elements, function(el){
+      var $el = $(el);
+      var type = getElementType($el); 
+
+      // Get the key for the input
+      var keyExtractor = config.keyExtractors.get(type);
+      var key = keyExtractor($el);
+
+      // Get the value for the input
+      var inputReader = config.inputReaders.get(type);
+      var value = inputReader($el);
+
+      // Get the key assignment validator and make sure
+      // it's valid before assigning the value to the key
+      var validKeyAssignment = config.keyAssignmentValidators.get(type);
+      if (validKeyAssignment($el, key, value)){
+        var keychain = config.keySplitter(key);
+        data = assignKeyValue(data, keychain, value);
+      }
+    });
+
+    // Done; send back the results.
+    return data;
+  };
+  
+  // Use the given JSON object to populate
+  // all of the form inputs, in this view.
+  // Alternately, pass a form element directly
+  // in place of the view.
+  Syphon.deserialize = function(view, data, options){
+    // Build the configuration
+    var config = buildConfig(options);
+
+    // Get all of the elements to process
+    var elements = getInputElements(view, config);
+
+    // Flatten the data structure that we are deserializing
+    var flattenedData = flattenData(config, data);
+
+    // Process all of the elements
+    _.each(elements, function(el){
+      var $el = $(el);
+      var type = getElementType($el); 
+
+      // Get the key for the input
+      var keyExtractor = config.keyExtractors.get(type);
+      var key = keyExtractor($el);
+
+      // Get the input writer and the value to write
+      var inputWriter = config.inputWriters.get(type);
+      var value = flattenedData[key];
+
+      // Write the value to the input
+      inputWriter($el, value);
+    });
+  };
+
+  // Helpers
+  // -------
+
+  // Retrieve all of the form inputs
+  // from the form
+  var getInputElements = function(view, config){
+    var form = getForm(view);
+    var elements = form.elements;
+
+    elements = _.reject(elements, function(el){
+      var reject;
+      var type = getElementType(el);
+      var extractor = config.keyExtractors.get(type);
+      var identifier = extractor($(el));
+     
+      var foundInIgnored = _.include(config.ignoredTypes, type);
+      var foundInInclude = _.include(config.include, identifier);
+      var foundInExclude = _.include(config.exclude, identifier);
+
+      if (foundInInclude){
+        reject = false;
+      } else {
+        if (config.include){
+          reject = true;
+        } else {
+          reject = (foundInExclude || foundInIgnored);
+        }
+      }
+
+      return reject;
+    });
+
+    return elements;
+  };
+
+  // Determine what type of element this is. It
+  // will either return the `type` attribute of
+  // an `<input>` element, or the `tagName` of
+  // the element when the element is not an `<input>`.
+  var getElementType = function(el){
+    var typeAttr;
+    var $el = $(el);
+    var tagName = $el[0].tagName;
+    var type = tagName;
+
+    if (tagName.toLowerCase() === "input"){
+      typeAttr = $el.attr("type");
+      if (typeAttr){
+        type = typeAttr;
+      } else {
+        type = "text";
+      }
+    }
+    
+    // Always return the type as lowercase
+    // so it can be matched to lowercase
+    // type registrations.
+    return type.toLowerCase();
+  };
+  
+  // If a form element is given, just return it. 
+  // Otherwise, get the form element from the view.
+  var getForm = function(viewOrForm){
+    if (_.isUndefined(viewOrForm.$el) && viewOrForm.tagName.toLowerCase() === 'form'){
+      return viewOrForm;
+    } else {
+      return viewOrForm.$el.is("form") ? viewOrForm.el : viewOrForm.$("form")[0];
+    }
+  };
+
+  // Build a configuration object and initialize
+  // default values.
+  var buildConfig = function(options){
+    var config = _.clone(options) || {};
+    
+    config.ignoredTypes = _.clone(Syphon.ignoredTypes);
+    config.inputReaders = config.inputReaders || Syphon.InputReaders;
+    config.inputWriters = config.inputWriters || Syphon.InputWriters;
+    config.keyExtractors = config.keyExtractors || Syphon.KeyExtractors;
+    config.keySplitter = config.keySplitter || Syphon.KeySplitter;
+    config.keyJoiner = config.keyJoiner || Syphon.KeyJoiner;
+    config.keyAssignmentValidators = config.keyAssignmentValidators || Syphon.KeyAssignmentValidators;
+    
+    return config;
+  };
+
+  // Assigns `value` to a parsed JSON key. 
+  //
+  // The first parameter is the object which will be
+  // modified to store the key/value pair.
+  //
+  // The second parameter accepts an array of keys as a 
+  // string with an option array containing a 
+  // single string as the last option.
+  //
+  // The third parameter is the value to be assigned.
+  //
+  // Examples:
+  //
+  // `["foo", "bar", "baz"] => {foo: {bar: {baz: "value"}}}`
+  // 
+  // `["foo", "bar", ["baz"]] => {foo: {bar: {baz: ["value"]}}}`
+  // 
+  // When the final value is an array with a string, the key
+  // becomes an array, and values are pushed in to the array,
+  // allowing multiple fields with the same name to be 
+  // assigned to the array.
+  var assignKeyValue = function(obj, keychain, value) {
+    if (!keychain){ return obj; }
+
+    var key = keychain.shift();
+
+    // build the current object we need to store data
+    if (!obj[key]){
+      obj[key] = _.isArray(key) ? [] : {};
+    }
+
+    // if it's the last key in the chain, assign the value directly
+    if (keychain.length === 0){
+      if (_.isArray(obj[key])){
+        obj[key].push(value);
+      } else {
+        obj[key] = value;
+      }
+    }
+
+    // recursive parsing of the array, depth-first
+    if (keychain.length > 0){
+      assignKeyValue(obj[key], keychain, value);
+    }
+    
+    return obj;
+  };
+
+  // Flatten the data structure in to nested strings, using the
+  // provided `KeyJoiner` function.
+  //
+  // Example:
+  //
+  // This input:
+  //
+  // ```js
+  // {
+  //   widget: "wombat",
+  //   foo: {
+  //     bar: "baz",
+  //     baz: {
+  //       quux: "qux"
+  //     },
+  //     quux: ["foo", "bar"]
+  //   }
+  // }
+  // ```
+  //
+  // With a KeyJoiner that uses [ ] square brackets, 
+  // should produce this output:
+  //
+  // ```js
+  // {
+  //  "widget": "wombat",
+  //  "foo[bar]": "baz",
+  //  "foo[baz][quux]": "qux",
+  //  "foo[quux]": ["foo", "bar"]
+  // }
+  // ```
+  var flattenData = function(config, data, parentKey){
+    var flatData = {};
+
+    _.each(data, function(value, keyName){
+      var hash = {};
+
+      // If there is a parent key, join it with
+      // the current, child key.
+      if (parentKey){
+        keyName = config.keyJoiner(parentKey, keyName);
+      }
+
+      if (_.isArray(value)){
+        keyName += "[]";
+        hash[keyName] = value;
+      } else if (_.isObject(value)){
+        hash = flattenData(config, value, keyName);
+      } else {
+        hash[keyName] = value;
+      }
+
+      // Store the resulting key/value pairs in the
+      // final flattened data object
+      _.extend(flatData, hash);
+    });
+
+    return flatData;
+  };
+
+  return Syphon;
+})(Backbone, jQuery, _);
+
+// Type Registry
+// -------------
+
+// Type Registries allow you to register something to
+// an input type, and retrieve either the item registered
+// for a specific type or the default registration
+Backbone.Syphon.TypeRegistry = function(){
+  this.registeredTypes = {};
+};
+
+// Borrow Backbone's `extend` keyword for our TypeRegistry
+Backbone.Syphon.TypeRegistry.extend = Backbone.Model.extend;
+
+_.extend(Backbone.Syphon.TypeRegistry.prototype, {
+
+  // Get the registered item by type. If nothing is
+  // found for the specified type, the default is
+  // returned.
+  get: function(type){
+    var item = this.registeredTypes[type];
+
+    if (!item){
+      item = this.registeredTypes["default"];
+    }
+
+    return item;
+  },
+
+  // Register a new item for a specified type
+  register: function(type, item){
+    this.registeredTypes[type] = item;
+  },
+
+  // Register a default item to be used when no
+  // item for a specified type is found
+  registerDefault: function(item){
+    this.registeredTypes["default"] = item;
+  },
+
+  // Remove an item from a given type registration
+  unregister: function(type){
+    if (this.registeredTypes[type]){
+      delete this.registeredTypes[type];
+    }
+  }
+});
+
+
+
+
+// Key Extractors
+// --------------
+
+// Key extractors produce the "key" in `{key: "value"}`
+// pairs, when serializing.
+Backbone.Syphon.KeyExtractorSet = Backbone.Syphon.TypeRegistry.extend();
+
+// Built-in Key Extractors
+Backbone.Syphon.KeyExtractors = new Backbone.Syphon.KeyExtractorSet();
+
+// The default key extractor, which uses the
+// input element's "id" attribute
+Backbone.Syphon.KeyExtractors.registerDefault(function($el){
+  return $el.prop("name");
+});
+
+
+// Input Readers
+// -------------
+
+// Input Readers are used to extract the value from
+// an input element, for the serialized object result
+Backbone.Syphon.InputReaderSet = Backbone.Syphon.TypeRegistry.extend();
+
+// Built-in Input Readers
+Backbone.Syphon.InputReaders = new Backbone.Syphon.InputReaderSet();
+
+// The default input reader, which uses an input
+// element's "value"
+Backbone.Syphon.InputReaders.registerDefault(function($el){
+  return $el.val();
+});
+
+// Checkbox reader, returning a boolean value for
+// whether or not the checkbox is checked.
+Backbone.Syphon.InputReaders.register("checkbox", function($el){
+  var checked = $el.prop("checked");
+  return checked;
+});
+
+
+// Input Writers
+// -------------
+
+// Input Writers are used to insert a value from an
+// object into an input element.
+Backbone.Syphon.InputWriterSet = Backbone.Syphon.TypeRegistry.extend();
+
+// Built-in Input Writers
+Backbone.Syphon.InputWriters = new Backbone.Syphon.InputWriterSet();
+
+// The default input writer, which sets an input
+// element's "value"
+Backbone.Syphon.InputWriters.registerDefault(function($el, value){
+  $el.val(value);
+});
+
+// Checkbox writer, set whether or not the checkbox is checked
+// depending on the boolean value.
+Backbone.Syphon.InputWriters.register("checkbox", function($el, value){
+  $el.prop("checked", value);
+});
+
+// Radio button writer, set whether or not the radio button is
+// checked.  The button should only be checked if it's value
+// equals the given value.
+Backbone.Syphon.InputWriters.register("radio", function($el, value){
+  $el.prop("checked", $el.val() === value);
+});
+
+// Key Assignment Validators
+// -------------------------
+
+// Key Assignment Validators are used to determine whether or not a
+// key should be assigned to a value, after the key and value have been
+// extracted from the element. This is the last opportunity to prevent
+// bad data from getting serialized to your object.
+
+Backbone.Syphon.KeyAssignmentValidatorSet = Backbone.Syphon.TypeRegistry.extend();
+
+// Build-in Key Assignment Validators
+Backbone.Syphon.KeyAssignmentValidators = new Backbone.Syphon.KeyAssignmentValidatorSet();
+
+// Everything is valid by default
+Backbone.Syphon.KeyAssignmentValidators.registerDefault(function(){ return true; });
+
+// But only the "checked" radio button for a given
+// radio button group is valid
+Backbone.Syphon.KeyAssignmentValidators.register("radio", function($el, key, value){ 
+  return $el.prop("checked");
+});
+
+
+// Backbone.Syphon.KeySplitter
+// ---------------------------
+
+// This function is used to split DOM element keys in to an array
+// of parts, which are then used to create a nested result structure.
+// returning `["foo", "bar"]` results in `{foo: { bar: "value" }}`.
+//
+// Override this method to use a custom key splitter, such as:
+// `<input name="foo.bar.baz">`, `return key.split(".")`
+Backbone.Syphon.KeySplitter = function(key){
+  var matches = key.match(/[^\[\]]+/g);
+
+  if (key.indexOf("[]") === key.length - 2){
+    lastKey = matches.pop();
+    matches.push([lastKey]);
+  }
+
+  return matches;
+}
+
+
+// Backbone.Syphon.KeyJoiner
+// -------------------------
+
+// Take two segments of a key and join them together, to create the
+// de-normalized key name, when deserializing a data structure back
+// in to a form.
+//
+// Example: 
+//
+// With this data strucutre `{foo: { bar: {baz: "value", quux: "another"} } }`,
+// the key joiner will be called with these parameters, and assuming the
+// join happens with "[ ]" square brackets, the specified output:
+// 
+// `KeyJoiner("foo", "bar")` //=> "foo[bar]"
+// `KeyJoiner("foo[bar]", "baz")` //=> "foo[bar][baz]"
+// `KeyJoiner("foo[bar]", "quux")` //=> "foo[bar][quux]"
+
+Backbone.Syphon.KeyJoiner = function(parentKey, childKey){
+  return parentKey + "[" + childKey + "]";
+}
