Adds backbone extensions to vendor.
authordsc <dsc@wikimedia.org>
Mon, 19 Mar 2012 10:02:31 +0000 (03:02 -0700)
committerdsc <dsc@wikimedia.org>
Mon, 19 Mar 2012 10:02:31 +0000 (03:02 -0700)
static/vendor/backbone.nested-1.1.0.js
static/vendor/backbone.nested-1.1.0.min.js
static/vendor/synapse-0.4.2.js [new file with mode: 0644]
static/vendor/synapse-0.4.2.min.js [new file with mode: 0644]
static/vendor/synapse.js [new symlink]
static/vendor/synapse.min.js [new symlink]

index 3002834..1905c4f 100644 (file)
@@ -30,9 +30,9 @@
       }
 
       // check if the result is an Object, Array, etc.
-      if (!opts.silent && _.isObject(result) && window.console){
-        window.console.log("Backbone-Nested syntax is preferred for accesing values of attribute '" + attrStrOrPath + "'.");
-      }
+      // if (!opts.silent && _.isObject(result) && window.console){
+      //   window.console.log("Backbone-Nested syntax is preferred for accesing values of attribute '" + attrStrOrPath + "'.");
+      // }
       // else it's a leaf
 
       return result;
index c1f8a53..1dcd96a 100644 (file)
@@ -5,4 +5,4 @@
  *
  * Copyright (c) 2011-2012 Aidan Feldman
  * MIT Licensed (LICENSE)
- *//*global Backbone, _, $ */(function(){"use strict",Backbone.NestedModel=Backbone.Model.extend({get:function(a,b){b=b||{};var c=Backbone.NestedModel.attrPath(a),d=c[0],e=Backbone.NestedModel.__super__.get.call(this,d);for(var f=1;f<c.length;f++){if(!e)break;d=c[f],e=e[d]}return!b.silent&&_.isObject(e)&&window.console&&window.console.log("Backbone-Nested syntax is preferred for accesing values of attribute '"+a+"'."),e},has:function(a){var b=this.get(a,{silent:!0});return b!==null&&!_.isUndefined(b)},set:function(a,b,c){var d;_.isObject(a)||a==null?(d=a,c=b):(d={},d[a]=b),c=c||{};var e=Backbone.NestedModel.deepClone(this.attributes),f,g,h;for(var i in d)g=Backbone.NestedModel.attrPath(i),h=Backbone.NestedModel.createAttrObj(g,d[i]),this._mergeAttrs(e,h,c);return Backbone.NestedModel.__super__.set.call(this,e,c)},unset:function(a,b){return b=_.extend({},b,{unset:!0}),this.set(a,null,b),this},add:function(a,b,c){var d=this.get(a,{silent:!0});this.set(a+"["+d.length+"]",b,c)},remove:function(a,b){b=b||{};var c=Backbone.NestedModel.attrPath(a),d=_.initial(c),e=this.get(d,{silent:!0}),f=_.last(c);if(!_.isArray(e))throw new Error("remove() must be called on a nested array");var g=!b.silent&&e.length>f+1,h=e[f];return e.splice(f,1),this.set(a,e,b),g&&this.trigger("remove:"+Backbone.NestedModel.createAttrStr(d),this,h),this},toJSON:function(){var a=Backbone.NestedModel.__super__.toJSON.apply(this);return Backbone.NestedModel.deepClone(a)},_mergeAttrs:function(a,b,c,d){return d=d||[],_.each(b,function(b,e){e==="-1"&&(e=a.length);var f=a[e],g=d.concat([e]),h,i=_.isObject(b)&&_.any(b,function(a,b){return b==="-1"||_.isNumber(b)});i&&!_.isArray(f)&&(f=a[e]=[]);if(e in a&&_.isObject(b)&&_.isObject(f))f=a[e]=this._mergeAttrs(f,b,c,g);else{var j=f;f=a[e]=b,_.isArray(a)&&!c.silent&&(h=Backbone.NestedModel.createAttrStr(d),!j&&f?this.trigger("add:"+h,this,f):j&&!f&&this.trigger("remove:"+h,this,j))}!c.silent&&g.length>1&&(h=Backbone.NestedModel.createAttrStr(g),this.trigger("change:"+h,this,f))},this),a}},{attrPath:function(a){var b;return _.isString(a)?(a=a.replace(/\[\]/g,"[-1]"),b=a===""?[""]:a.match(/[^\.\[\]]+/g),b=_.map(b,function(a){return a.match(/^\d+$/)?parseInt(a,10):a})):b=a,b},createAttrObj:function(a,b){var c=this.attrPath(a),d;switch(c.length){case 0:throw"no valid attributes: '"+a+"'";case 1:d=b;break;default:var e=_.rest(c);d=this.createAttrObj(e,b)}var f=c[0],g=_.isNumber(f)?[]:{};return g[f]=d,g},createAttrStr:function(a){var b=a[0];return _.each(_.rest(a),function(a){b+=_.isNumber(a)?"["+a+"]":"."+a}),b},deepClone:function(a){return $.extend(!0,{},a)}})})();
\ No newline at end of file
+ *//*global Backbone, _, $ */(function(){"use strict",Backbone.NestedModel=Backbone.Model.extend({get:function(a,b){b=b||{};var c=Backbone.NestedModel.attrPath(a),d=c[0],e=Backbone.NestedModel.__super__.get.call(this,d);for(var f=1;f<c.length;f++){if(!e)break;d=c[f],e=e[d]}return e},has:function(a){var b=this.get(a,{silent:!0});return b!==null&&!_.isUndefined(b)},set:function(a,b,c){var d;_.isObject(a)||a==null?(d=a,c=b):(d={},d[a]=b),c=c||{};var e=Backbone.NestedModel.deepClone(this.attributes),f,g,h;for(var i in d)g=Backbone.NestedModel.attrPath(i),h=Backbone.NestedModel.createAttrObj(g,d[i]),this._mergeAttrs(e,h,c);return Backbone.NestedModel.__super__.set.call(this,e,c)},unset:function(a,b){return b=_.extend({},b,{unset:!0}),this.set(a,null,b),this},add:function(a,b,c){var d=this.get(a,{silent:!0});this.set(a+"["+d.length+"]",b,c)},remove:function(a,b){b=b||{};var c=Backbone.NestedModel.attrPath(a),d=_.initial(c),e=this.get(d,{silent:!0}),f=_.last(c);if(!_.isArray(e))throw new Error("remove() must be called on a nested array");var g=!b.silent&&e.length>f+1,h=e[f];return e.splice(f,1),this.set(a,e,b),g&&this.trigger("remove:"+Backbone.NestedModel.createAttrStr(d),this,h),this},toJSON:function(){var a=Backbone.NestedModel.__super__.toJSON.apply(this);return Backbone.NestedModel.deepClone(a)},_mergeAttrs:function(a,b,c,d){return d=d||[],_.each(b,function(b,e){e==="-1"&&(e=a.length);var f=a[e],g=d.concat([e]),h,i=_.isObject(b)&&_.any(b,function(a,b){return b==="-1"||_.isNumber(b)});i&&!_.isArray(f)&&(f=a[e]=[]);if(e in a&&_.isObject(b)&&_.isObject(f))f=a[e]=this._mergeAttrs(f,b,c,g);else{var j=f;f=a[e]=b,_.isArray(a)&&!c.silent&&(h=Backbone.NestedModel.createAttrStr(d),!j&&f?this.trigger("add:"+h,this,f):j&&!f&&this.trigger("remove:"+h,this,j))}!c.silent&&g.length>1&&(h=Backbone.NestedModel.createAttrStr(g),this.trigger("change:"+h,this,f))},this),a}},{attrPath:function(a){var b;return _.isString(a)?(a=a.replace(/\[\]/g,"[-1]"),b=a===""?[""]:a.match(/[^\.\[\]]+/g),b=_.map(b,function(a){return a.match(/^\d+$/)?parseInt(a,10):a})):b=a,b},createAttrObj:function(a,b){var c=this.attrPath(a),d;switch(c.length){case 0:throw"no valid attributes: '"+a+"'";case 1:d=b;break;default:var e=_.rest(c);d=this.createAttrObj(e,b)}var f=c[0],g=_.isNumber(f)?[]:{};return g[f]=d,g},createAttrStr:function(a){var b=a[0];return _.each(_.rest(a),function(a){b+=_.isNumber(a)?"["+a+"]":"."+a}),b},deepClone:function(a){return $.extend(!0,{},a)}})})();
\ No newline at end of file
diff --git a/static/vendor/synapse-0.4.2.js b/static/vendor/synapse-0.4.2.js
new file mode 100644 (file)
index 0000000..2c4f183
--- /dev/null
@@ -0,0 +1,989 @@
+
+
+(function(root, factory) {
+  if (typeof exports !== 'undefined') {
+    return factory(root, exports);
+  } else if (typeof define === 'function' && define.amd) {
+    return define('synapse/core', ['exports'], function(exports) {
+      return factory(root, exports);
+    });
+  } else {
+    return root.SynapseCore = factory(root, {});
+  }
+})(this, function(root, core) {
+  var channels;
+  channels = {};
+  return {
+    toString: Object.prototype.toString,
+    getType: function(object) {
+      return this.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
+    },
+    isObject: function(object) {
+      return this.getType(object) === 'Object';
+    },
+    isArray: function(object) {
+      return this.getType(object) === 'Array';
+    },
+    isFunction: function(object) {
+      return this.getType(object) === 'Function';
+    },
+    isString: function(object) {
+      return this.getType(object) === 'String';
+    },
+    isBoolean: function(object) {
+      return this.getType(object) === 'Boolean';
+    }
+  };
+});
+
+var __slice = Array.prototype.slice;
+
+(function(root, factory) {
+  if (typeof exports !== 'undefined') {
+    return factory(root, exports, require('synapse/core'));
+  } else if (typeof define === 'function' && define.amd) {
+    return define('synapse', ['synapse/core', 'exports'], function(core, exports) {
+      return factory(root, exports, core);
+    });
+  } else {
+    return root.Synapse = factory(root, {}, root.SynapseCore);
+  }
+})(this, function(root, Synapse, core) {
+  var connect, connectOne, defaultConnectOptions, detectEvent, detectInterface, detectOtherInterface, limitedApi, objectGuid, offEvent, onEvent, synapseHooks, synapseObjects, triggerEvent;
+  objectGuid = 1;
+  synapseObjects = {};
+  synapseHooks = [];
+  limitedApi = ['observe', 'notify', 'syncWith', 'stopObserving', 'pauseObserving', 'resumeObserving', 'stopNotifying', 'pauseNotifying', 'resumeNotifying'];
+  Synapse = (function() {
+
+    Synapse.prototype.version = '0.4.2';
+
+    function Synapse(object) {
+      var hook, method, raw, wrapped, _fn, _i, _j, _len, _len2,
+        _this = this;
+      if (object instanceof Synapse) return object;
+      if (this.constructor !== Synapse) {
+        wrapped = new Synapse(object);
+        raw = wrapped.raw;
+        _fn = function(method) {
+          return raw[method] = function() {
+            wrapped[method].apply(wrapped, arguments);
+            return this;
+          };
+        };
+        for (_i = 0, _len = limitedApi.length; _i < _len; _i++) {
+          method = limitedApi[_i];
+          _fn(method);
+        }
+        return raw;
+      }
+      for (_j = 0, _len2 = synapseHooks.length; _j < _len2; _j++) {
+        hook = synapseHooks[_j];
+        if (hook.checkObjectType(object)) break;
+        hook = null;
+      }
+      if (!hook) {
+        throw new Error("No hook exists for " + (core.getType(object)) + " types");
+      }
+      this.raw = (typeof hook.coerceObject === "function" ? hook.coerceObject(object) : void 0) || object;
+      this.hook = hook;
+      this.guid = objectGuid++;
+      this._observing = {};
+      this._notifying = {};
+      synapseObjects[this.guid] = this;
+    }
+
+    Synapse.prototype.get = function() {
+      var _ref;
+      return (_ref = this.hook).getHandler.apply(_ref, [this.raw].concat(__slice.call(arguments)));
+    };
+
+    Synapse.prototype.set = function() {
+      var _ref;
+      (_ref = this.hook).setHandler.apply(_ref, [this.raw].concat(__slice.call(arguments)));
+      return this;
+    };
+
+    Synapse.prototype.observe = function() {
+      var args, other;
+      other = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
+      other = new Synapse(other);
+      connect.apply(null, [other, this].concat(__slice.call(args)));
+      return this;
+    };
+
+    Synapse.prototype.notify = function() {
+      var args, other;
+      other = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
+      other = new Synapse(other);
+      connect.apply(null, [this, other].concat(__slice.call(args)));
+      return this;
+    };
+
+    Synapse.prototype.syncWith = function(other) {
+      other = new Synapse(other);
+      this.observe(other).notify(other);
+      return this;
+    };
+
+    Synapse.prototype.stopObserving = function(other) {
+      var channels, observerInterface, subject, subjectGuid, thread;
+      if (!other) {
+        for (subjectGuid in this._observing) {
+          channels = this._observing[subjectGuid];
+          subject = synapseObjects[subjectGuid];
+          for (observerInterface in channels) {
+            thread = channels[observerInterface];
+            offEvent(subject, thread.event, thread.handler);
+          }
+          this._observing = {
+            _open: true
+          };
+        }
+      } else {
+        channels = this._observing[other.guid];
+        for (observerInterface in channels) {
+          thread = channels[observerInterface];
+          offEvent(other, thread.event, thread.handler);
+        }
+        this._observing[other.guid] = {
+          _open: true
+        };
+      }
+      return this;
+    };
+
+    Synapse.prototype.pauseObserving = function(other) {
+      var channels, subjectGuid;
+      if (!other) {
+        for (subjectGuid in this._observing) {
+          channels = this._observing[subjectGuid];
+          channels._open = false;
+        }
+      } else {
+        channels = this._observing[other.guid];
+        channels._open = false;
+      }
+      return this;
+    };
+
+    Synapse.prototype.resumeObserving = function(other) {
+      var channels, subjectGuid;
+      if (other) {
+        if ((channels = this._observing[other.guid])) channels._open = true;
+      } else {
+        for (subjectGuid in this._observing) {
+          this._observing[subjectGuid]._open = true;
+        }
+      }
+      return this;
+    };
+
+    Synapse.prototype.stopNotifying = function(other) {
+      var channels, observer, observerGuid, observerInterface, thread;
+      if (!other) {
+        for (observerGuid in this._notifying) {
+          channels = this._notifying[observerGuid];
+          observer = synapseObjects[observerGuid];
+          for (observerInterface in channels) {
+            thread = channels[observerInterface];
+            offEvent(this, thread.event, thread.handler);
+          }
+          this._notifying = {
+            _open: true
+          };
+        }
+      } else {
+        channels = this._notifying[other.guid];
+        for (observerInterface in channels) {
+          thread = channels[observerInterface];
+          offEvent(this, thread.event, thread.handler);
+        }
+        this._notifying[other.guid] = {
+          _open: true
+        };
+      }
+      return this;
+    };
+
+    Synapse.prototype.pauseNotifying = function(other) {
+      var channels, observerGuid;
+      if (!other) {
+        for (observerGuid in this._notifying) {
+          channels = this._notifying[observerGuid];
+          channels._open = false;
+        }
+      } else {
+        channels = this._notifying[other.guid];
+        channels._open = false;
+      }
+      return this;
+    };
+
+    Synapse.prototype.resumeNotifying = function(other) {
+      var channels, observerGuid;
+      if (other) {
+        if ((channels = this._notifying[other.guid])) channels._open = true;
+      } else {
+        for (observerGuid in this._notifying) {
+          this._notifying[observerGuid]._open = true;
+        }
+      }
+      return this;
+    };
+
+    return Synapse;
+
+  })();
+  Synapse.addHooks = function() {
+    return synapseHooks.push.apply(synapseHooks, arguments);
+  };
+  Synapse.clearHooks = function() {
+    return synapseHooks = [];
+  };
+  detectEvent = function() {
+    var args, object, value, _ref;
+    object = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
+    if ((value = (_ref = object.hook).detectEvent.apply(_ref, [object.raw].concat(__slice.call(args))))) {
+      return value;
+    }
+    throw new Error("" + object.hook.typeName + " types do not support events");
+  };
+  onEvent = function() {
+    var args, object, value, _base;
+    object = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
+    if ((value = typeof (_base = object.hook).onEventHandler === "function" ? _base.onEventHandler.apply(_base, [object.raw].concat(__slice.call(args))) : void 0)) {
+      return object;
+    }
+    throw new Error("" + object.hook.typeName + " types do not support events");
+  };
+  offEvent = function() {
+    var args, object, value, _base;
+    object = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
+    if ((value = typeof (_base = object.hook).offEventHandler === "function" ? _base.offEventHandler.apply(_base, [object.raw].concat(__slice.call(args))) : void 0)) {
+      return object;
+    }
+    throw new Error("" + object.hook.typeName + " types do not support events");
+  };
+  triggerEvent = function() {
+    var args, object, value, _base;
+    object = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
+    if ((value = typeof (_base = object.hook).triggerEventHandler === "function" ? _base.triggerEventHandler.apply(_base, [object.raw].concat(__slice.call(args))) : void 0)) {
+      return object;
+    }
+    throw new Error("" + object.hook.typeName + " types do not support events");
+  };
+  detectInterface = function(object) {
+    var _base;
+    return typeof (_base = object.hook).detectInterface === "function" ? _base.detectInterface(object.raw) : void 0;
+  };
+  detectOtherInterface = function(object) {
+    var _base;
+    return typeof (_base = object.hook).detectOtherInterface === "function" ? _base.detectOtherInterface(object.raw) : void 0;
+  };
+  defaultConnectOptions = {
+    event: null,
+    subjectInterface: null,
+    observerInterface: null,
+    converter: null,
+    triggerOnBind: true
+  };
+  connectOne = function(subject, observer, options) {
+    var channel, converter, event, events, handler, key, observerChannels, observerInterface, subjectChannels, subjectInterface, triggerOnBind, value, _i, _len;
+    for (key in defaultConnectOptions) {
+      value = defaultConnectOptions[key];
+      if (!(options[key] != null)) options[key] = value;
+    }
+    if ((converter = options.converter) && !core.isFunction(converter)) {
+      converter = observer.object[converter];
+    }
+    if (!(subjectInterface = options.subjectInterface)) {
+      if (!(subjectInterface = detectInterface(subject) || detectOtherInterface(observer)) && !converter) {
+        throw new Error("An interface for " + subject.hook.typeName + " objects could not be detected");
+      }
+    }
+    if (!(observerInterface = options.observerInterface)) {
+      if (!(observerInterface = detectInterface(observer) || detectOtherInterface(subject))) {
+        throw new Error("An interface for " + observer.hook.typeName + " objects could not be detected");
+      }
+    }
+    if (!(events = options.event)) events = detectEvent(subject, subjectInterface);
+    if (!core.isArray(events)) events = [events];
+    triggerOnBind = options.triggerOnBind;
+    for (_i = 0, _len = events.length; _i < _len; _i++) {
+      event = events[_i];
+      handler = function() {
+        if (observer._observing[subject.guid]._open === true && subject._notifying[observer.guid]._open === true) {
+          value = subject.get(subjectInterface);
+          if (converter) value = converter(value);
+          return observer.set(observerInterface, value);
+        }
+      };
+      if (!(observerChannels = observer._observing[subject.guid])) {
+        observerChannels = observer._observing[subject.guid] = {
+          _open: true
+        };
+      }
+      if (!(subjectChannels = subject._notifying[observer.guid])) {
+        subjectChannels = subject._notifying[observer.guid] = {
+          _open: true
+        };
+      }
+      channel = {
+        event: event,
+        handler: handler
+      };
+      observerChannels[observerInterface] = channel;
+      subjectChannels[observerInterface] = channel;
+      onEvent(subject, event, handler);
+      if (triggerOnBind) triggerEvent(subject, event);
+    }
+  };
+  connect = function() {
+    var arg0, arg1, args, observer, opt, options, subject, _i, _len;
+    subject = arguments[0], observer = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
+    options = args;
+    arg0 = args[0];
+    arg1 = args[1];
+    if (core.isFunction(arg0)) {
+      options = {
+        converter: arg0
+      };
+    } else if (core.isArray(arg0) || !core.isObject(arg0)) {
+      options = {
+        subjectInterface: arg0,
+        observerInterface: arg1
+      };
+    }
+    if (!core.isArray(options)) options = [options];
+    for (_i = 0, _len = options.length; _i < _len; _i++) {
+      opt = options[_i];
+      connectOne(subject, observer, opt);
+    }
+  };
+  return Synapse;
+});
+
+
+(function(root, factory) {
+  if (typeof exports !== 'undefined') {
+    return factory(root, exports, require('synapse/core'));
+  } else if (typeof define === 'function' && define.amd) {
+    return define('synapse/hooks/object', ['synapse/core', 'exports'], function(core, exports) {
+      return factory(root, exports, core);
+    });
+  } else {
+    return root.ObjectHook = factory(root, {}, root.SynapseCore);
+  }
+})(this, function(root, ObjectHook, core) {
+  return {
+    typeName: 'Plain Object',
+    checkObjectType: function(object) {
+      return core.isObject(object);
+    },
+    getHandler: function(object, key) {
+      if (core.isFunction(object[key])) {
+        return object[key]();
+      } else {
+        return object[key];
+      }
+    },
+    setHandler: function(object, key, value) {
+      if (core.isFunction(object[key])) {
+        return object[key](value);
+      } else {
+        return object[key] = value;
+      }
+    }
+  };
+});
+
+var __slice = Array.prototype.slice;
+
+(function(root, factory) {
+  if (typeof define === 'function' && define.amd) {
+    return define('synapse/hooks/jquery', ['synapse/core', 'jquery', 'exports'], function(core, $, exports) {
+      return factory(root, exports, core, $);
+    });
+  } else if (typeof exports === 'undefined') {
+    return root.jQueryHook = factory(root, {}, root.SynapseCore, root.jQuery);
+  }
+})(this, function(root, jQueryHook, core, $) {
+  var domEvents, elementBindAttributes, elementInterfaces, interfaces;
+  interfaces = (function() {
+    return {
+      registry: {},
+      register: function(config) {
+        return this.registry[config.name] = config;
+      },
+      unregister: function(name) {
+        return delete this.registry[name];
+      },
+      get: function() {
+        var args, iface, key, name, object, _ref;
+        object = arguments[0], name = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
+        _ref = name.split('.'), name = _ref[0], key = _ref[1];
+        if (key != null) args = [key].concat(args);
+        if ((iface = this.registry[name])) return iface.get.apply(object, args);
+      },
+      set: function() {
+        var args, iface, key, name, object, _ref;
+        object = arguments[0], name = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
+        _ref = name.split('.'), name = _ref[0], key = _ref[1];
+        if (key != null) args = [key].concat(args);
+        if ((iface = this.registry[name])) return iface.set.apply(object, args);
+      }
+    };
+  })();
+  (function() {
+    var getAttribute, getCss, getProperty, setAttribute, setCss, setProperty;
+    getProperty = function(key) {
+      if (this.prop != null) return this.prop(key);
+      return getAttribute.call(this, key);
+    };
+    setProperty = function(key, value) {
+      if (this.prop != null) {
+        if (typeof key === 'object') return this.prop(key);
+        return this.prop(key, value);
+      }
+      return setAttribute.call(this, key, value);
+    };
+    getAttribute = function(key) {
+      return this.attr(key);
+    };
+    setAttribute = function(key, value) {
+      if (core.isObject(key)) {
+        return this.attr(key);
+      } else {
+        return this.attr(key, value);
+      }
+    };
+    getCss = function(key) {
+      return this.css(key);
+    };
+    setCss = function(key, value) {
+      if (core.isObject(key)) {
+        return this.css(key);
+      } else {
+        return this.css(key, value);
+      }
+    };
+    interfaces.register({
+      name: 'text',
+      get: function() {
+        return this.text();
+      },
+      set: function(value) {
+        return this.text((value != null ? value : '').toString());
+      }
+    });
+    interfaces.register({
+      name: 'html',
+      get: function() {
+        return this.html();
+      },
+      set: function(value) {
+        return this.html((value != null ? value : '').toString());
+      }
+    });
+    interfaces.register({
+      name: 'value',
+      get: function() {
+        return this.val();
+      },
+      set: function(value) {
+        return this.val(value != null ? value : '');
+      }
+    });
+    interfaces.register({
+      name: 'enabled',
+      get: function() {
+        return !getProperty.call(this, 'disabled');
+      },
+      set: function(value) {
+        if (core.isArray(value) && value.length === 0) value = false;
+        return setProperty.call(this, 'disabled', !Boolean(value));
+      }
+    });
+    interfaces.register({
+      name: 'disabled',
+      get: function() {
+        return getProperty.call(this, 'disabled');
+      },
+      set: function(value) {
+        if (core.isArray(value) && value.length === 0) value = false;
+        return setProperty.call(this, 'disabled', Boolean(value));
+      }
+    });
+    interfaces.register({
+      name: 'checked',
+      get: function() {
+        return getProperty.call(this, 'checked');
+      },
+      set: function(value) {
+        if (core.isArray(value) && value.length === 0) value = false;
+        return setProperty.call(this, 'checked', Boolean(value));
+      }
+    });
+    interfaces.register({
+      name: 'visible',
+      get: function() {
+        return getCss.call(this, 'display') === !'none';
+      },
+      set: function(value) {
+        if (core.isArray(value) && value.length === 0) value = false;
+        if (Boolean(value)) {
+          return this.show();
+        } else {
+          return this.hide();
+        }
+      }
+    });
+    interfaces.register({
+      name: 'hidden',
+      get: function() {
+        return getCss.call(this, 'display') === 'none';
+      },
+      set: function(value) {
+        if (core.isArray(value) && value.length === 0) value = false;
+        if (Boolean(value)) {
+          return this.hide();
+        } else {
+          return this.show();
+        }
+      }
+    });
+    interfaces.register({
+      name: 'prop',
+      get: function(key) {
+        return getProperty.call(this, key);
+      },
+      set: function(key, value) {
+        return setProperty.call(this, key, value);
+      }
+    });
+    interfaces.register({
+      name: 'attr',
+      get: function(key) {
+        return getAttribute.call(this, key);
+      },
+      set: function(key, value) {
+        return setAttribute.call(this, key, value);
+      }
+    });
+    interfaces.register({
+      name: 'css',
+      get: function(key) {
+        return getCss.call(this, key);
+      },
+      set: function(key, value) {
+        return setCss.call(this, key, value);
+      }
+    });
+    interfaces.register({
+      name: 'data',
+      get: function(key) {
+        return this.data(key);
+      },
+      set: function(key, value) {
+        return this.data(key, value);
+      }
+    });
+    return interfaces.register({
+      name: 'class',
+      get: function(key) {
+        return this.hasClass(key);
+      },
+      set: function(key, value) {
+        return this.toggleClass(key, Boolean(value));
+      }
+    });
+  })();
+  domEvents = [['a,button,[type=button],[type=reset]', 'click'], ['select,[type=checkbox],[type=radio],textarea', 'change'], ['[type=submit]', 'submit'], ['input', 'keyup']];
+  elementInterfaces = [['[type=checkbox],[type=radio]', 'checked'], ['input,textarea,select', 'value']];
+  elementBindAttributes = ['name', 'role', 'data-bind'];
+  return {
+    typeName: 'jQuery',
+    domEvents: domEvents,
+    elementBindAttributes: elementBindAttributes,
+    elementInterfaces: elementInterfaces,
+    interfaces: interfaces,
+    checkObjectType: function(object) {
+      return object instanceof $ || object.nodeType === 1 || core.isString(object);
+    },
+    coerceObject: function(object) {
+      return $(object);
+    },
+    getHandler: function(object, key) {
+      var value;
+      value = interfaces.get(object, key);
+      if (value && object.is('[type=number]')) {
+        if (value.indexOf('.') > -1) {
+          return parseFloat(value);
+        } else {
+          return parseInt(value);
+        }
+      }
+      return value;
+    },
+    setHandler: function(object, key, value) {
+      return interfaces.set(object, key, value);
+    },
+    onEventHandler: function(object, event, handler) {
+      return object.bind(event, handler);
+    },
+    offEventHandler: function(object, event, handler) {
+      return object.unbind(event, handler);
+    },
+    triggerEventHandler: function(object, event) {
+      return object.trigger(event);
+    },
+    detectEvent: function(object) {
+      var event, item, selector, _i, _len;
+      for (_i = 0, _len = domEvents.length; _i < _len; _i++) {
+        item = domEvents[_i];
+        selector = item[0], event = item[1];
+        if (object.is(selector)) return event;
+      }
+    },
+    detectInterface: function(object) {
+      var iface, item, selector, _i, _len;
+      for (_i = 0, _len = elementInterfaces.length; _i < _len; _i++) {
+        item = elementInterfaces[_i];
+        selector = item[0], iface = item[1];
+        if (object.is(selector)) return iface;
+      }
+      return 'text';
+    },
+    detectOtherInterface: function(object) {
+      var attr, value, _i, _len;
+      for (_i = 0, _len = elementBindAttributes.length; _i < _len; _i++) {
+        attr = elementBindAttributes[_i];
+        if ((value = object.attr(attr))) return value;
+      }
+    }
+  };
+});
+
+
+(function(root, factory) {
+  if (typeof exports !== 'undefined') {
+    return factory(root, exports, require('synapse/core'), require('backbone'));
+  } else if (typeof define === 'function' && define.amd) {
+    return define('synapse/hooks/backbone-model', ['synapse/core', 'backbone', 'exports'], function(core, Backbone, exports) {
+      return factory(root, exports, core, Backbone);
+    });
+  } else {
+    return root.BackboneModelHook = factory(root, {}, root.SynapseCore, root.Backbone);
+  }
+})(this, function(root, BackboneModelHook, core) {
+  return {
+    typeName: 'Backbone Model',
+    checkObjectType: function(object) {
+      return object instanceof Backbone.Model;
+    },
+    getHandler: function(object, key) {
+      if (core.isFunction(object[key])) {
+        return object[key]();
+      } else {
+        return object.get(key);
+      }
+    },
+    setHandler: function(object, key, value) {
+      var attrs;
+      if (core.isFunction(object[key])) {
+        return object[key](value);
+      } else {
+        attrs = {};
+        attrs[key] = value;
+        return object.set(attrs);
+      }
+    },
+    onEventHandler: function(object, event, handler) {
+      return object.bind(event, handler);
+    },
+    offEventHandler: function(object, event, handler) {
+      return object.unbind(event, handler);
+    },
+    triggerEventHandler: function(object, event) {
+      return object.trigger(event);
+    },
+    detectEvent: function(object, iface) {
+      if (iface && !object[iface]) return "change:" + iface;
+      return 'change';
+    }
+  };
+});
+
+var __slice = Array.prototype.slice;
+
+(function(root, factory) {
+  if (typeof define === 'function' && define.amd) {
+    return define('synapse/hooks/backbone-view', ['synapse/core', 'backbone', 'exports'], function(core, Backbone, exports) {
+      return factory(root, exports, core, Backbone);
+    });
+  } else if (typeof exports === 'undefined') {
+    return root.BackboneViewHook = factory(root, {}, root.SynapseCore, root.Backbone);
+  }
+})(this, function(root, BackboneViewHook, core) {
+  var domEvents, elementBindAttributes, elementInterfaces, interfaces;
+  interfaces = (function() {
+    return {
+      registry: {},
+      register: function(config) {
+        return this.registry[config.name] = config;
+      },
+      unregister: function(name) {
+        return delete this.registry[name];
+      },
+      get: function() {
+        var args, iface, key, name, object, _ref;
+        object = arguments[0], name = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
+        _ref = name.split('.'), name = _ref[0], key = _ref[1];
+        if (key != null) args = [key].concat(args);
+        if ((iface = this.registry[name])) return iface.get.apply(object, args);
+      },
+      set: function() {
+        var args, iface, key, name, object, _ref;
+        object = arguments[0], name = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
+        _ref = name.split('.'), name = _ref[0], key = _ref[1];
+        if (key != null) args = [key].concat(args);
+        if ((iface = this.registry[name])) return iface.set.apply(object, args);
+      }
+    };
+  })();
+  (function() {
+    var getAttribute, getCss, getProperty, setAttribute, setCss, setProperty;
+    getProperty = function(key) {
+      if (this.prop != null) return this.prop(key);
+      return getAttribute.call(this, key);
+    };
+    setProperty = function(key, value) {
+      if (this.prop != null) {
+        if (typeof key === 'object') return this.prop(key);
+        return this.prop(key, value);
+      }
+      return setAttribute.call(this, key, value);
+    };
+    getAttribute = function(key) {
+      return this.attr(key);
+    };
+    setAttribute = function(key, value) {
+      if (core.isObject(key)) {
+        return this.attr(key);
+      } else {
+        return this.attr(key, value);
+      }
+    };
+    getCss = function(key) {
+      return this.css(key);
+    };
+    setCss = function(key, value) {
+      if (core.isObject(key)) {
+        return this.css(key);
+      } else {
+        return this.css(key, value);
+      }
+    };
+    interfaces.register({
+      name: 'text',
+      get: function() {
+        return this.text();
+      },
+      set: function(value) {
+        return this.text((value != null ? value : '').toString());
+      }
+    });
+    interfaces.register({
+      name: 'html',
+      get: function() {
+        return this.html();
+      },
+      set: function(value) {
+        return this.html((value != null ? value : '').toString());
+      }
+    });
+    interfaces.register({
+      name: 'value',
+      get: function() {
+        return this.val();
+      },
+      set: function(value) {
+        return this.val(value != null ? value : '');
+      }
+    });
+    interfaces.register({
+      name: 'enabled',
+      get: function() {
+        return !getProperty.call(this, 'disabled');
+      },
+      set: function(value) {
+        if (core.isArray(value) && value.length === 0) value = false;
+        return setProperty.call(this, 'disabled', !Boolean(value));
+      }
+    });
+    interfaces.register({
+      name: 'disabled',
+      get: function() {
+        return getProperty.call(this, 'disabled');
+      },
+      set: function(value) {
+        if (core.isArray(value) && value.length === 0) value = false;
+        return setProperty.call(this, 'disabled', Boolean(value));
+      }
+    });
+    interfaces.register({
+      name: 'checked',
+      get: function() {
+        return getProperty.call(this, 'checked');
+      },
+      set: function(value) {
+        if (core.isArray(value) && value.length === 0) value = false;
+        return setProperty.call(this, 'checked', Boolean(value));
+      }
+    });
+    interfaces.register({
+      name: 'visible',
+      get: function() {
+        return getCss.call(this, 'display') === !'none';
+      },
+      set: function(value) {
+        if (core.isArray(value) && value.length === 0) value = false;
+        if (Boolean(value)) {
+          return this.show();
+        } else {
+          return this.hide();
+        }
+      }
+    });
+    interfaces.register({
+      name: 'hidden',
+      get: function() {
+        return getCss.call(this, 'display') === 'none';
+      },
+      set: function(value) {
+        if (core.isArray(value) && value.length === 0) value = false;
+        if (Boolean(value)) {
+          return this.hide();
+        } else {
+          return this.show();
+        }
+      }
+    });
+    interfaces.register({
+      name: 'prop',
+      get: function(key) {
+        return getProperty.call(this, key);
+      },
+      set: function(key, value) {
+        return setProperty.call(this, key, value);
+      }
+    });
+    interfaces.register({
+      name: 'attr',
+      get: function(key) {
+        return getAttribute.call(this, key);
+      },
+      set: function(key, value) {
+        return setAttribute.call(this, key, value);
+      }
+    });
+    interfaces.register({
+      name: 'css',
+      get: function(key) {
+        return getCss.call(this, key);
+      },
+      set: function(key, value) {
+        return setCss.call(this, key, value);
+      }
+    });
+    interfaces.register({
+      name: 'data',
+      get: function(key) {
+        return this.data(key);
+      },
+      set: function(key, value) {
+        return this.data(key, value);
+      }
+    });
+    return interfaces.register({
+      name: 'class',
+      get: function(key) {
+        return this.hasClass(key);
+      },
+      set: function(key, value) {
+        return this.toggleClass(key, Boolean(value));
+      }
+    });
+  })();
+  domEvents = [['a,button,[type=button],[type=reset]', 'click'], ['select,[type=checkbox],[type=radio],textarea', 'change'], ['[type=submit]', 'submit'], ['input', 'keyup']];
+  elementInterfaces = [['[type=checkbox],[type=radio]', 'checked'], ['input,textarea,select', 'value']];
+  elementBindAttributes = ['name', 'role', 'data-bind'];
+  return {
+    typeName: 'Backbone View',
+    domEvents: domEvents,
+    elementBindAttributes: elementBindAttributes,
+    elementInterfaces: elementInterfaces,
+    interfaces: interfaces,
+    checkObjectType: function(object) {
+      return object instanceof Backbone.View;
+    },
+    getHandler: function(object, key) {
+      var el, value;
+      el = object.$(object.el);
+      if (core.isFunction(object[key])) {
+        value = object[key]();
+      } else {
+        value = interfaces.get(el, key);
+      }
+      if (value && el.is('[type=number]')) {
+        if (value.indexOf('.') > -1) {
+          return parseFloat(value);
+        } else {
+          return parseInt(value);
+        }
+      }
+      return value;
+    },
+    setHandler: function(object, key, value) {
+      if (core.isFunction(object[key])) return object[key](value);
+      return interfaces.set(object.$(object.el), key, value);
+    },
+    onEventHandler: function(object, event, handler) {
+      return object.$(object.el).bind(event, handler);
+    },
+    offEventHandler: function(object, event, handler) {
+      return object.$(object.el).unbind(event, handler);
+    },
+    triggerEventHandler: function(object, event) {
+      return object.$(object.el).trigger(event);
+    },
+    detectEvent: function(object) {
+      var el, event, item, selector, _i, _len;
+      el = object.$(object.el);
+      for (_i = 0, _len = domEvents.length; _i < _len; _i++) {
+        item = domEvents[_i];
+        selector = item[0], event = item[1];
+        if (el.is(selector)) return event;
+      }
+    },
+    detectInterface: function(object) {
+      var el, iface, item, selector, _i, _len;
+      el = object.$(object.el);
+      for (_i = 0, _len = elementInterfaces.length; _i < _len; _i++) {
+        item = elementInterfaces[_i];
+        selector = item[0], iface = item[1];
+        if (el.is(selector)) return iface;
+      }
+      return 'text';
+    },
+    detectOtherInterface: function(object) {
+      var attr, el, value, _i, _len;
+      el = object.$(object.el);
+      for (_i = 0, _len = elementBindAttributes.length; _i < _len; _i++) {
+        attr = elementBindAttributes[_i];
+        if ((value = el.attr(attr))) return value;
+      }
+    }
+  };
+});
diff --git a/static/vendor/synapse-0.4.2.min.js b/static/vendor/synapse-0.4.2.min.js
new file mode 100644 (file)
index 0000000..44fddbc
--- /dev/null
@@ -0,0 +1 @@
+(function(a,b){return typeof exports!="undefined"?b(a,exports):typeof define=="function"&&define.amd?define("synapse/core",["exports"],function(c){return b(a,c)}):a.SynapseCore=b(a,{})})(this,function(a,b){var c;return c={},{toString:Object.prototype.toString,getType:function(a){return this.toString.call(a).match(/^\[object\s(.*)\]$/)[1]},isObject:function(a){return this.getType(a)==="Object"},isArray:function(a){return this.getType(a)==="Array"},isFunction:function(a){return this.getType(a)==="Function"},isString:function(a){return this.getType(a)==="String"},isBoolean:function(a){return this.getType(a)==="Boolean"}}});var __slice=Array.prototype.slice;(function(a,b){return typeof exports!="undefined"?b(a,exports,require("synapse/core")):typeof define=="function"&&define.amd?define("synapse",["synapse/core","exports"],function(c,d){return b(a,d,c)}):a.Synapse=b(a,{},a.SynapseCore)})(this,function(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p;return k=1,o={},n=[],j=["observe","notify","syncWith","stopObserving","pauseObserving","resumeObserving","stopNotifying","pauseNotifying","resumeNotifying"],b=function(){function a(b){var d,e,f,g,h,i,l,m,p,q=this;if(b instanceof a)return b;if(this.constructor!==a){g=new a(b),f=g.raw,h=function(a){return f[a]=function(){return g[a].apply(g,arguments),this}};for(i=0,m=j.length;i<m;i++)e=j[i],h(e);return f}for(l=0,p=n.length;l<p;l++){d=n[l];if(d.checkObjectType(b))break;d=null}if(!d)throw new Error("No hook exists for "+c.getType(b)+" types");this.raw=(typeof d.coerceObject=="function"?d.coerceObject(b):void 0)||b,this.hook=d,this.guid=k++,this._observing={},this._notifying={},o[this.guid]=this}return a.prototype.version="0.4.2",a.prototype.get=function(){var a;return(a=this.hook).getHandler.apply(a,[this.raw].concat(__slice.call(arguments)))},a.prototype.set=function(){var a;return(a=this.hook).setHandler.apply(a,[this.raw].concat(__slice.call(arguments))),this},a.prototype.observe=function(){var b,c;return c=arguments[0],b=2<=arguments.length?__slice.call(arguments,1):[],c=new a(c),d.apply(null,[c,this].concat(__slice.call(b))),this},a.prototype.notify=function(){var b,c;return c=arguments[0],b=2<=arguments.length?__slice.call(arguments,1):[],c=new a(c),d.apply(null,[this,c].concat(__slice.call(b))),this},a.prototype.syncWith=function(b){return b=new a(b),this.observe(b).notify(b),this},a.prototype.stopObserving=function(a){var b,c,d,e,f;if(!a)for(e in this._observing){b=this._observing[e],d=o[e];for(c in b)f=b[c],l(d,f.event,f.handler);this._observing={_open:!0}}else{b=this._observing[a.guid];for(c in b)f=b[c],l(a,f.event,f.handler);this._observing[a.guid]={_open:!0}}return this},a.prototype.pauseObserving=function(a){var b,c;if(!a)for(c in this._observing)b=this._observing[c],b._open=!1;else b=this._observing[a.guid],b._open=!1;return this},a.prototype.resumeObserving=function(a){var b,c;if(a){if(b=this._observing[a.guid])b._open=!0}else for(c in this._observing)this._observing[c]._open=!0;return this},a.prototype.stopNotifying=function(a){var b,c,d,e,f;if(!a)for(d in this._notifying){b=this._notifying[d],c=o[d];for(e in b)f=b[e],l(this,f.event,f.handler);this._notifying={_open:!0}}else{b=this._notifying[a.guid];for(e in b)f=b[e],l(this,f.event,f.handler);this._notifying[a.guid]={_open:!0}}return this},a.prototype.pauseNotifying=function(a){var b,c;if(!a)for(c in this._notifying)b=this._notifying[c],b._open=!1;else b=this._notifying[a.guid],b._open=!1;return this},a.prototype.resumeNotifying=function(a){var b,c;if(a){if(b=this._notifying[a.guid])b._open=!0}else for(c in this._notifying)this._notifying[c]._open=!0;return this},a}(),b.addHooks=function(){return n.push.apply(n,arguments)},b.clearHooks=function(){return n=[]},g=function(){var a,b,c,d;b=arguments[0],a=2<=arguments.length?__slice.call(arguments,1):[];if(c=(d=b.hook).detectEvent.apply(d,[b.raw].concat(__slice.call(a))))return c;throw new Error(""+b.hook.typeName+" types do not support events")},m=function(){var a,b,c,d;b=arguments[0],a=2<=arguments.length?__slice.call(arguments,1):[];if(c=typeof (d=b.hook).onEventHandler=="function"?d.onEventHandler.apply(d,[b.raw].concat(__slice.call(a))):void 0)return b;throw new Error(""+b.hook.typeName+" types do not support events")},l=function(){var a,b,c,d;b=arguments[0],a=2<=arguments.length?__slice.call(arguments,1):[];if(c=typeof (d=b.hook).offEventHandler=="function"?d.offEventHandler.apply(d,[b.raw].concat(__slice.call(a))):void 0)return b;throw new Error(""+b.hook.typeName+" types do not support events")},p=function(){var a,b,c,d;b=arguments[0],a=2<=arguments.length?__slice.call(arguments,1):[];if(c=typeof (d=b.hook).triggerEventHandler=="function"?d.triggerEventHandler.apply(d,[b.raw].concat(__slice.call(a))):void 0)return b;throw new Error(""+b.hook.typeName+" types do not support events")},h=function(a){var b;return typeof (b=a.hook).detectInterface=="function"?b.detectInterface(a.raw):void 0},i=function(a){var b;return typeof (b=a.hook).detectOtherInterface=="function"?b.detectOtherInterface(a.raw):void 0},f={event:null,subjectInterface:null,observerInterface:null,converter:null,triggerOnBind:!0},e=function(a,b,d){var e,j,k,l,n,o,q,r,s,t,u,v,w,x;for(o in f)v=f[o],d[o]==null&&(d[o]=v);(j=d.converter)&&!c.isFunction(j)&&(j=b.object[j]);if(!(t=d.subjectInterface)&&!(t=h(a)||i(b))&&!j)throw new Error("An interface for "+a.hook.typeName+" objects could not be detected");if(!(r=d.observerInterface)&&!(r=h(b)||i(a)))throw new Error("An interface for "+b.hook.typeName+" objects could not be detected");(l=d.event)||(l=g(a,t)),c.isArray(l)||(l=[l]),u=d.triggerOnBind;for(w=0,x=l.length;w<x;w++)k=l[w],n=function(){if(b._observing[a.guid]._open===!0&&a._notifying[b.guid]._open===!0)return v=a.get(t),j&&(v=j(v)),b.set(r,v)},(q=b._observing[a.guid])||(q=b._observing[a.guid]={_open:!0}),(s=a._notifying[b.guid])||(s=a._notifying[b.guid]={_open:!0}),e={event:k,handler:n},q[r]=e,s[r]=e,m(a,k,n),u&&p(a,k)},d=function(){var a,b,d,f,g,h,i,j,k;i=arguments[0],f=arguments[1],d=3<=arguments.length?__slice.call(arguments,2):[],h=d,a=d[0],b=d[1];if(c.isFunction(a))h={converter:a};else if(c.isArray(a)||!c.isObject(a))h={subjectInterface:a,observerInterface:b};c.isArray(h)||(h=[h]);for(j=0,k=h.length;j<k;j++)g=h[j],e(i,f,g)},b}),function(a,b){return typeof exports!="undefined"?b(a,exports,require("synapse/core")):typeof define=="function"&&define.amd?define("synapse/hooks/object",["synapse/core","exports"],function(c,d){return b(a,d,c)}):a.ObjectHook=b(a,{},a.SynapseCore)}(this,function(a,b,c){return{typeName:"Plain Object",checkObjectType:function(a){return c.isObject(a)},getHandler:function(a,b){return c.isFunction(a[b])?a[b]():a[b]},setHandler:function(a,b,d){return c.isFunction(a[b])?a[b](d):a[b]=d}}});var __slice=Array.prototype.slice;(function(a,b){if(typeof define=="function"&&define.amd)return define("synapse/hooks/jquery",["synapse/core","jquery","exports"],function(c,d,e){return b(a,e,c,d)});if(typeof exports=="undefined")return a.jQueryHook=b(a,{},a.SynapseCore,a.jQuery)})(this,function(a,b,c,d){var e,f,g,h;return h=function(){return{registry:{},register:function(a){return this.registry[a.name]=a},unregister:function(a){return delete this.registry[a]},get:function(){var a,b,c,d,e,f;e=arguments[0],d=arguments[1],a=3<=arguments.length?__slice.call(arguments,2):[],f=d.split("."),d=f[0],c=f[1],c!=null&&(a=[c].concat(a));if(b=this.registry[d])return b.get.apply(e,a)},set:function(){var a,b,c,d,e,f;e=arguments[0],d=arguments[1],a=3<=arguments.length?__slice.call(arguments,2):[],f=d.split("."),d=f[0],c=f[1],c!=null&&(a=[c].concat(a));if(b=this.registry[d])return b.set.apply(e,a)}}}(),function(){var a,b,d,e,f,g;return d=function(b){return this.prop!=null?this.prop(b):a.call(this,b)},g=function(a,b){return this.prop!=null?typeof a=="object"?this.prop(a):this.prop(a,b):e.call(this,a,b)},a=function(a){return this.attr(a)},e=function(a,b){return c.isObject(a)?this.attr(a):this.attr(a,b)},b=function(a){return this.css(a)},f=function(a,b){return c.isObject(a)?this.css(a):this.css(a,b)},h.register({name:"text",get:function(){return this.text()},set:function(a){return this.text((a!=null?a:"").toString())}}),h.register({name:"html",get:function(){return this.html()},set:function(a){return this.html((a!=null?a:"").toString())}}),h.register({name:"value",get:function(){return this.val()},set:function(a){return this.val(a!=null?a:"")}}),h.register({name:"enabled",get:function(){return!d.call(this,"disabled")},set:function(a){return c.isArray(a)&&a.length===0&&(a=!1),g.call(this,"disabled",!Boolean(a))}}),h.register({name:"disabled",get:function(){return d.call(this,"disabled")},set:function(a){return c.isArray(a)&&a.length===0&&(a=!1),g.call(this,"disabled",Boolean(a))}}),h.register({name:"checked",get:function(){return d.call(this,"checked")},set:function(a){return c.isArray(a)&&a.length===0&&(a=!1),g.call(this,"checked",Boolean(a))}}),h.register({name:"visible",get:function(){return b.call(this,"display")===!1},set:function(a){return c.isArray(a)&&a.length===0&&(a=!1),Boolean(a)?this.show():this.hide()}}),h.register({name:"hidden",get:function(){return b.call(this,"display")==="none"},set:function(a){return c.isArray(a)&&a.length===0&&(a=!1),Boolean(a)?this.hide():this.show()}}),h.register({name:"prop",get:function(a){return d.call(this,a)},set:function(a,b){return g.call(this,a,b)}}),h.register({name:"attr",get:function(b){return a.call(this,b)},set:function(a,b){return e.call(this,a,b)}}),h.register({name:"css",get:function(a){return b.call(this,a)},set:function(a,b){return f.call(this,a,b)}}),h.register({name:"data",get:function(a){return this.data(a)},set:function(a,b){return this.data(a,b)}}),h.register({name:"class",get:function(a){return this.hasClass(a)},set:function(a,b){return this.toggleClass(a,Boolean(b))}})}(),e=[["a,button,[type=button],[type=reset]","click"],["select,[type=checkbox],[type=radio],textarea","change"],["[type=submit]","submit"],["input","keyup"]],g=[["[type=checkbox],[type=radio]","checked"],["input,textarea,select","value"]],f=["name","role","data-bind"],{typeName:"jQuery",domEvents:e,elementBindAttributes:f,elementInterfaces:g,interfaces:h,checkObjectType:function(a){return a instanceof d||a.nodeType===1||c.isString(a)},coerceObject:function(a){return d(a)},getHandler:function(a,b){var c;return c=h.get(a,b),c&&a.is("[type=number]")?c.indexOf(".")>-1?parseFloat(c):parseInt(c):c},setHandler:function(a,b,c){return h.set(a,b,c)},onEventHandler:function(a,b,c){return a.bind(b,c)},offEventHandler:function(a,b,c){return a.unbind(b,c)},triggerEventHandler:function(a,b){return a.trigger(b)},detectEvent:function(a){var b,c,d,f,g;for(f=0,g=e.length;f<g;f++){c=e[f],d=c[0],b=c[1];if(a.is(d))return b}},detectInterface:function(a){var b,c,d,e,f;for(e=0,f=g.length;e<f;e++){c=g[e],d=c[0],b=c[1];if(a.is(d))return b}return"text"},detectOtherInterface:function(a){var b,c,d,e;for(d=0,e=f.length;d<e;d++){b=f[d];if(c=a.attr(b))return c}}}}),function(a,b){return typeof exports!="undefined"?b(a,exports,require("synapse/core"),require("backbone")):typeof define=="function"&&define.amd?define("synapse/hooks/backbone-model",["synapse/core","backbone","exports"],function(c,d,e){return b(a,e,c,d)}):a.BackboneModelHook=b(a,{},a.SynapseCore,a.Backbone)}(this,function(a,b,c){return{typeName:"Backbone Model",checkObjectType:function(a){return a instanceof Backbone.Model},getHandler:function(a,b){return c.isFunction(a[b])?a[b]():a.get(b)},setHandler:function(a,b,d){var e;return c.isFunction(a[b])?a[b](d):(e={},e[b]=d,a.set(e))},onEventHandler:function(a,b,c){return a.bind(b,c)},offEventHandler:function(a,b,c){return a.unbind(b,c)},triggerEventHandler:function(a,b){return a.trigger(b)},detectEvent:function(a,b){return b&&!a[b]?"change:"+b:"change"}}});var __slice=Array.prototype.slice;(function(a,b){if(typeof define=="function"&&define.amd)return define("synapse/hooks/backbone-view",["synapse/core","backbone","exports"],function(c,d,e){return b(a,e,c,d)});if(typeof exports=="undefined")return a.BackboneViewHook=b(a,{},a.SynapseCore,a.Backbone)})(this,function(a,b,c){var d,e,f,g;return g=function(){return{registry:{},register:function(a){return this.registry[a.name]=a},unregister:function(a){return delete this.registry[a]},get:function(){var a,b,c,d,e,f;e=arguments[0],d=arguments[1],a=3<=arguments.length?__slice.call(arguments,2):[],f=d.split("."),d=f[0],c=f[1],c!=null&&(a=[c].concat(a));if(b=this.registry[d])return b.get.apply(e,a)},set:function(){var a,b,c,d,e,f;e=arguments[0],d=arguments[1],a=3<=arguments.length?__slice.call(arguments,2):[],f=d.split("."),d=f[0],c=f[1],c!=null&&(a=[c].concat(a));if(b=this.registry[d])return b.set.apply(e,a)}}}(),function(){var a,b,d,e,f,h;return d=function(b){return this.prop!=null?this.prop(b):a.call(this,b)},h=function(a,b){return this.prop!=null?typeof a=="object"?this.prop(a):this.prop(a,b):e.call(this,a,b)},a=function(a){return this.attr(a)},e=function(a,b){return c.isObject(a)?this.attr(a):this.attr(a,b)},b=function(a){return this.css(a)},f=function(a,b){return c.isObject(a)?this.css(a):this.css(a,b)},g.register({name:"text",get:function(){return this.text()},set:function(a){return this.text((a!=null?a:"").toString())}}),g.register({name:"html",get:function(){return this.html()},set:function(a){return this.html((a!=null?a:"").toString())}}),g.register({name:"value",get:function(){return this.val()},set:function(a){return this.val(a!=null?a:"")}}),g.register({name:"enabled",get:function(){return!d.call(this,"disabled")},set:function(a){return c.isArray(a)&&a.length===0&&(a=!1),h.call(this,"disabled",!Boolean(a))}}),g.register({name:"disabled",get:function(){return d.call(this,"disabled")},set:function(a){return c.isArray(a)&&a.length===0&&(a=!1),h.call(this,"disabled",Boolean(a))}}),g.register({name:"checked",get:function(){return d.call(this,"checked")},set:function(a){return c.isArray(a)&&a.length===0&&(a=!1),h.call(this,"checked",Boolean(a))}}),g.register({name:"visible",get:function(){return b.call(this,"display")===!1},set:function(a){return c.isArray(a)&&a.length===0&&(a=!1),Boolean(a)?this.show():this.hide()}}),g.register({name:"hidden",get:function(){return b.call(this,"display")==="none"},set:function(a){return c.isArray(a)&&a.length===0&&(a=!1),Boolean(a)?this.hide():this.show()}}),g.register({name:"prop",get:function(a){return d.call(this,a)},set:function(a,b){return h.call(this,a,b)}}),g.register({name:"attr",get:function(b){return a.call(this,b)},set:function(a,b){return e.call(this,a,b)}}),g.register({name:"css",get:function(a){return b.call(this,a)},set:function(a,b){return f.call(this,a,b)}}),g.register({name:"data",get:function(a){return this.data(a)},set:function(a,b){return this.data(a,b)}}),g.register({name:"class",get:function(a){return this.hasClass(a)},set:function(a,b){return this.toggleClass(a,Boolean(b))}})}(),d=[["a,button,[type=button],[type=reset]","click"],["select,[type=checkbox],[type=radio],textarea","change"],["[type=submit]","submit"],["input","keyup"]],f=[["[type=checkbox],[type=radio]","checked"],["input,textarea,select","value"]],e=["name","role","data-bind"],{typeName:"Backbone View",domEvents:d,elementBindAttributes:e,elementInterfaces:f,interfaces:g,checkObjectType:function(a){return a instanceof Backbone.View},getHandler:function(a,b){var d,e;return d=a.$(a.el),c.isFunction(a[b])?e=a[b]():e=g.get(d,b),e&&d.is("[type=number]")?e.indexOf(".")>-1?parseFloat(e):parseInt(e):e},setHandler:function(a,b,d){return c.isFunction(a[b])?a[b](d):g.set(a.$(a.el),b,d)},onEventHandler:function(a,b,c){return a.$(a.el).bind(b,c)},offEventHandler:function(a,b,c){return a.$(a.el).unbind(b,c)},triggerEventHandler:function(a,b){return a.$(a.el).trigger(b)},detectEvent:function(a){var b,c,e,f,g,h;b=a.$(a.el);for(g=0,h=d.length;g<h;g++){e=d[g],f=e[0],c=e[1];if(b.is(f))return c}},detectInterface:function(a){var b,c,d,e,g,h;b=a.$(a.el);for(g=0,h=f.length;g<h;g++){d=f[g],e=d[0],c=d[1];if(b.is(e))return c}return"text"},detectOtherInterface:function(a){var b,c,d,f,g;c=a.$(a.el);for(f=0,g=e.length;f<g;f++){b=e[f];if(d=c.attr(b))return d}}}});
\ No newline at end of file
diff --git a/static/vendor/synapse.js b/static/vendor/synapse.js
new file mode 120000 (symlink)
index 0000000..4314e86
--- /dev/null
@@ -0,0 +1 @@
+synapse-0.4.2.js
\ No newline at end of file
diff --git a/static/vendor/synapse.min.js b/static/vendor/synapse.min.js
new file mode 120000 (symlink)
index 0000000..df5f59b
--- /dev/null
@@ -0,0 +1 @@
+synapse-0.4.2.min.js
\ No newline at end of file