;
(function(mag, document, undefined) {

  'use strict'

  var module = mag.mod,
    render = mag.render,
    fill = mag.fill,
    topModule,
    type = {}.toString,
    FUNCTION = 'function',
    OBJECT = '[object Object]';

  mag.running = false

  var redrawing = false
  mag.redraw = function() {
    if (redrawing) {
      // do we ever get here?
      // necessary?
      return
    }
    redrawing = true
    render.redraw(module || render.module || {}, fill)
    redrawing = false
  }

  mag.withProp = function(prop, withAttrCallback) {
    return function(e) {
      e = e || event;
      var currentTarget = e.currentTarget || this;
      withAttrCallback(prop in currentTarget ? currentTarget[prop] : currentTarget.getAttribute(prop))
    }
  }

  mag.prop = function(store) {

    if (((store != null && type.call(store) === OBJECT) || typeof store === FUNCTION) && typeof store.then === FUNCTION) {
      return propify(store)
    }

    return gettersetter(store)
  }

  function gettersetter(store) {
    var prop = function() {
      if (arguments.length) {
        store = arguments[0]
        // Is a redraw here necessary?
        mag.redraw()
      }
      return store
    }

    // do we still need this?
    // TODO: value hookin?
    prop.type = 'fun'

    prop.toJSON = function() {
      // return a copy
      return store
    }

    return prop
  }

  function propify(promise, initialValue) {
    var prop = mag.prop(initialValue);
    promise.then(prop);
    prop.then = function(resolve, reject) {
      return propify(promise.then(resolve, reject), initialValue)
    };
    return prop
  }

  var hookins = {
    attributes: [],
    elementMatcher : []
  }
  mag.hookin = function(name, key, handler) {
    hookins[name].push({
      context: {},
      handler: handler,
      key: key
    })
  }

  mag.hook = function(name, key, data, before) {
    for (var i in hookins[name]) {
      data.changed = false
      if (hookins[name][i].key == key) {
        before = JSON.stringify({
          v: data.value,
          k: data.key
        })
        hookins[name][i].handler.call(hookins[name][i].context, data)
        //if any change
        if (before !== JSON.stringify({
          v: data.value,
          k: data.key
        })) {
          data.change = true
        }
      }
    }
  }

  var unloaders = [];

  function unloaderer(index) {
    //console.log('unloaderer', index)
    var isPrevented = false
    var event = {
      preventDefault: function() {
        isPrevented = true
      }
    }

    // WHY here?
    for (var i = 0, unloader; unloader = unloaders[i]; i++) {
      //console.log('unloaderer')
      // unloader.handler.call(unloader.controller, event)
      // unloader.controller.onunload = null
    }

    if (isPrevented) {
      //console.log('index unload', index)
      for (var i = 0, unloader; unloader = unloaders[i]; i++) unloader.controller.onunload = unloader.handler
    } else unloaders = []

    if (module.controllers[index] && typeof module.controllers[index].onunload === FUNCTION) {
      //console.log('unloader?', index)
      module.controllers[index].onunload(event)
      module.controllers[index].onunload = 0
    }

    return isPrevented
  }

  mag.module = function(domElementId, moduleObject, props, clone) {

    var index = render.roots.indexOf(domElementId)

    //UNLOADERS that exist?
    if (index > -1 && unloaderer(index)) return

    // clear cache if exists
    if (props && !props.retain) render.clear(index, domElementId, fill)

    // create new index on roots
    if (index < 0 || clone) index = render.roots.length;


    //DOM
    var element = document.getElementById(domElementId)
    if (!element) return Error('Mag.JS Module - invalid node')


    render.roots[index] = element.id

    //MODULE
    if (!moduleObject.view) return Error('Mag.JS module - requires a view')

    // TODO: should props be frozen or changeable?
    var mod = module.submodule(moduleObject, [Object.freeze(props || {})])

    var controller = module.getController(mod, element, fill)

    module.controllers[index] = controller
    if (controller.onunload) unloaders.push({
      controller: controller,
      handler: controller.onunload
    })

    module.modules[index] = mod
    module.elements[index] = clone ? element.cloneNode(true) : element


    module.promises[index] = new Promise(function(resolve, reject) {
      module.deferreds[index] = arguments
      // call onload if present in controller
      // if (controller.onload && !mag.running) render.callOnload(module)
    }.bind({}, clone, index))

    //INTERPOLATIONS
    mag.redraw()


    // call controller unloaders ?
    // check if was in previous and now not for the same node
    // add to fill.js


    // interpolations haven't occurred yet
    // return a promise in a settergetter

    return propify(module.promises[index], {
      _html: module.elements[index].innerHTML
    })

  }

})(window.mag || {}, document)

@@ -1677,14 +1677,13 @@
 cher
- 
 : %5B%5D%0A
+
   %7D%0A
@@ -2324,914 +2324,8 @@
  %7D%0A%0A
-  var unloaders = %5B%5D;%0A%0A  function unloaderer(index) %7B%0A    //console.log('unloaderer', index)%0A    var isPrevented = false%0A    var event = %7B%0A      preventDefault: function() %7B%0A        isPrevented = true%0A      %7D%0A    %7D%0A%0A    // WHY here?%0A    for (var i = 0, unloader; unloader = unloaders%5Bi%5D; i++) %7B%0A      //console.log('unloaderer')%0A      // unloader.handler.call(unloader.controller, event)%0A      // unloader.controller.onunload = null%0A    %7D%0A%0A    if (isPrevented) %7B%0A      //console.log('index unload', index)%0A      for (var i = 0, unloader; unloader = unloaders%5Bi%5D; i++) unloader.controller.onunload = unloader.handler%0A    %7D else unloaders = %5B%5D%0A%0A    if (module.controllers%5Bindex%5D && typeof module.controllers%5Bindex%5D.onunload === FUNCTION) %7B%0A      //console.log('unloader?', index)%0A      module.controllers%5Bindex%5D.onunload(event)%0A      module.controllers%5Bindex%5D.onunload = 0%0A    %7D%0A%0A    return isPrevented%0A  %7D%0A%0A
   ma
@@ -2469,24 +2469,26 @@
  exist?%0A    
+//
 if (index %3E 
@@ -2509,16 +2509,30 @@
 er(index
+, domElementId
 )) retur
@@ -3216,24 +3216,25 @@
  controller%0A
+%0A
     if (cont
@@ -3250,16 +3250,23 @@
 unload) 
+render.
 unloader

Update mag.js