diff --git a/README.md b/README.md
index 14bc3ffc947acf7ef69e1347441a05b18dc86139..61dfc673e497453fe5f06ac238526e049a8c371f 100644
--- a/README.md
+++ b/README.md
@@ -15,9 +15,34 @@ This project serves the developement environment / api we use to write and repre
 
 ## For MW
 
+ - GIFS
+  - load a program
+  - drag around
+  - zoom in and out 
+  - add a module
+  - hook events up
+  - rm events
+  - rm modules
+  - change settings 
+
  - *don't forget*
+  - onload, load state... 
   - when hooking back to server, server.emitChange(key) ... from writeStateObject 
-  - does state copy over successfully from loaded mod?
+
+ - this spiral
+  - entire programs read into UI
+   - hook sever-and-back 
+    - for event hookup
+    - for module add 
+    - for state push-down 
+   - re-hook state push-down 
+  - can req and add to program new modules
+  - can req to load new program 
+  - can req to save this program 
+
+ - next spiral
+  - programs come in chunk-wise and get placed 
+  - programs are modules are heirarchical 
 
  - fundament
   - the basic unit is a .js file having inputs, outputs, and state objects 
diff --git a/client/client.js b/client/client.js
index 4252f5c7f40e7ba94112bcfc2ae60e2ba921eab6..35db7fc2bc104f45e1eb193ad1ae89a9741ac706 100644
--- a/client/client.js
+++ b/client/client.js
@@ -1,17 +1,85 @@
-// client side js for atkapi reconf 
+//
+//
+// new node controller / VIEW 
+//
+// client.js
+//
+//
+// Jake Read at the Center for Bits and Atoms
+// (c) Massachusetts Institute of Technology 2018
+//
+// This work may be reproduced, modified, distributed, performed, and
+// displayed for any purpose, but must acknowledge the mods
+// project. Copyright is retained and must be preserved. The work is
+// provided as is; no warranty is provided, and users accept all
+// liability.
 
+/*
 
-// client globals
+CLIENT GLOBALS ---------------------------------------------------
 
-var reps = new Array()
+*/
 
 var sckt = {}
-var lastPos = {}
+var lastPos = { x: 10, y: 10 }
 
 // drawing / div-ing
 var wrapper = {}
 
-// client fns
+/*
+
+STARTUP ---------------------------------------------------
+
+*/
+
+window.onload = function() {
+    svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
+    svg.style.position = 'absolute'
+    svg.style.left = 0
+    svg.style.top = 0
+    svg.style.zIndex = 0
+    svg.style.overflow = 'visible'
+    svg.setAttribute('width', 2)
+    svg.setAttribute('height', 2)
+    svg.setAttribute('id', 'svg')
+    svg.setAttribute('width', '100%')
+    svg.setAttribute('height', '100%')
+    document.body.appendChild(svg)
+
+    wrapper = document.createElement('div')
+    wrapper.id = 'wrapper'
+    document.body.append(wrapper)
+
+    const socket = new WebSocket('ws://localhost:8081')
+
+    socket.onopen = function(evt) {
+        // pass to global ref 
+        sckt = this
+        // say hello 
+        socketSend('console', 'hello server')
+        console.log('socket open')
+        // ask for the current program 
+        socketSend('get current program', '')
+        // main socket entry point
+        this.onmessage = (evt) => {
+            socketRecv(evt)
+        }
+        // others
+        this.onerror = (err) => {
+            console.log('socket error', err)
+        }
+        this.onclose = (evt) => {
+            console.log('socket closed', evt)
+            sckt = null
+        }
+    }
+}
+
+/*
+
+RECV / SEND PORTALS ---------------------------------------------------
+
+*/
 
 function socketSend(type, data) {
     var msg = {
@@ -22,21 +90,6 @@ function socketSend(type, data) {
     sckt.send(JSON.stringify(msg))
 }
 
-// get json menu item and render
-// and ask for module at /obj/key
-oncontextmenu = function(evt) {
-    if (sckt) {
-        lastPos.X = evt.pageX
-        lastPos.Y = evt.pageY
-        socketSend('get menu', '')
-    } else {
-        // socket brkn 
-        location.reload()
-    }
-    // prevents event bubbling 
-    return false
-}
-
 function socketRecv(evt) {
     var recv = JSON.parse(evt.data)
     var type = recv.type
@@ -47,39 +100,113 @@ function socketRecv(evt) {
         case 'console':
             console.log('RECV CONSOLE:', data)
             break
-        case 'put menu':
-            buildMenu(data)
+        case 'put module menu':
+            console.log('RECV MENU')
+            heapSendsModuleMenu(data)
             break
-        case 'add reps':
+        case 'put program':
             console.log('RECV PROGRAM')
-            addReps(data)
-            break
-        case 'add rep':
-            addRep(data)
-            break
-        case 'change rep':
-            changeRep(data)
-            break
-        case 'change state':
-            changeState(data)
+            heapSendsNewProgram(data)
             break
+        case 'put module':
+            console.log('RECV NEW MODULE')
+            heapSendsNewModule(data)
+            break 
+        case 'put state':
+            console.log('RECV STATE CHANGE')
+            heapSendsNewState(data)
+            break 
         default:
             console.log('ERR recv with non recognized type', recv)
             break
     }
 }
 
+/*
+
+MISC ---------------------------------------------------
 
-function addReps(reps) {
+*/
+
+// return ul element with name and alt and link? 
+function heapSendsModuleMenu(tree) {
+    var menuDom = document.createElement('div')
+    menuDom.id = 'menu'
+    menuDom.style.left = lastPos.x + 'px'
+    menuDom.style.top = lastPos.y + 'px'
+    for (key in tree) {
+        var ul = document.createElement('ul')
+        ul.innerHTML = key.toString()
+        for (subkey in tree[key]) {
+            var li = document.createElement('li')
+            var path = tree[key][subkey].path
+            li.innerHTML = subkey.toString()
+            li.id = path
+            li.addEventListener('click', function(evt) {
+                var data = this.id
+                socketSend('add module', data)
+                wrapper.removeChild(document.getElementById('menu'))
+            })
+            ul.appendChild(li)
+        }
+        menuDom.appendChild(ul)
+    }
+    wrapper.append(menuDom)
+
+    function rmListener(evt) {
+        var findMenu = document.getElementById('menu')
+        if (findMenu !== null && findMenu.id == 'menu') {
+            wrapper.removeChild(findMenu)
+        }
+    }
+
+    document.addEventListener('click', rmListener)
+}
+
+/*
+
+HEAP -> SERVER ---------------------------------------------------
+
+*/
+
+// always a rep, tho
+var program = {}
+
+
+// re-writes the program, adds a description,
+// and loads multiple representations of modules to the view 
+
+function heapSendsNewProgram(prgm) {
+    // whole hearted replace
+    // hello for bugs when we lay this on top of something else 
+    program = prgm
+    // 1st we want to git rm old shit ... 
     // when adding links, we'll have to add all and then draw links
-    for (rep in reps) {
-        addRep(reps[rep])
+    console.log(program)
+    for (mdlName in program.modules) {
+        addRepToView(program.modules[mdlName])
+    }
+    redrawLinks()
+}
+
+function heapSendsNewModule(mdl){
+    if(program.description == null){
+        program.description.name = 'unnamed program'
+    }
+    if(program.modules == null){
+        program.modules = {}
     }
+    addRepToView(mdl)
+    program.modules[mdl.description.id] = mdl 
     redrawLinks()
 }
 
-// write html from json representation
-function addRep(rep) {
+
+// writes DOM elements to represent the module, appends to the wrapper
+// and appends to the rep object a .ui object 
+// containing references to those DOM objects 
+
+function addRepToView(rep) {
     // a div to locate it 
     var domElem = document.createElement('div')
     // dif. color for hardwares ?
@@ -87,8 +214,8 @@ function addRep(rep) {
     if (rep.description.isHardware) {
         domElem.classList.add('hardware')
     }
-    domElem.style.left = lastPos.X + 'px'
-    domElem.style.top = lastPos.Y + 'px'
+    domElem.style.left = lastPos.x + 'px'
+    domElem.style.top = lastPos.y + 'px'
 
     // more html: the title
     var title = document.createElement('div')
@@ -97,8 +224,8 @@ function addRep(rep) {
     title.alt = rep.description.alt
     domElem.appendChild(title)
 
-    // make UI elements 
     // place in pos if info present 
+    // the rep.ui object will store references to the module's related DOM elements
     if (rep.ui != null) {
         if (rep.ui.left != null) {
             domElem.style.left = rep.ui.left + 'px'
@@ -108,8 +235,8 @@ function addRep(rep) {
         }
     } else {
         rep.ui = {}
-        rep.ui.left = lastPos.X
-        rep.ui.top = lastPos.Y
+        rep.ui.left = lastPos.x
+        rep.ui.top = lastPos.y
     }
 
     rep.ui.domElem = domElem
@@ -164,7 +291,7 @@ function addRep(rep) {
 
         document.addEventListener('mousemove', domElemMouseMove)
 
-        domElem.onmouseup = function() {
+        title.onmouseup = function() {
             rep.ui.left = parseInt(domElem.style.left, 10)
             rep.ui.top = parseInt(domElem.style.top, 10)
             putUi(rep)
@@ -173,55 +300,12 @@ function addRep(rep) {
         }
     }
 
-    console.log('REP AT ADD', rep)
-
-    // ADD TO LISTS, DOC
-    reps.push(rep)
     wrapper.appendChild(rep.ui.domElem)
-
-    putUi(rep)
-}
-
-function redrawLinks() {
-    while (svg.firstChild) {
-        svg.removeChild(svg.firstChild)
-    }
-    // rm old links then redraw everything 
-    //console.log('now drawing links')
-    for (var i = 0; i < reps.length; i++) {
-        var rep = reps[i]
-        for (key in rep.outputs) {
-            var output = rep.outputs[key]
-            var outputUi = rep.ui.outputs[key]
-            for (input in output.calls) {
-                var toId = output.calls[input].parentId
-                var toKey = output.calls[input].key
-                var inputUi = reps[toId].ui.inputs[toKey]
-
-                var outPos = getOutputArrow(outputUi)
-                var inPos = getInputArrow(inputUi)
-
-                var bz = newBezier(outPos.x, outPos.y, inPos.x, inPos.y)
-            }
-        }
-    }
-}
-
-function changeRep(data) {
-    console.log('CHANGE REP', data)
-    var rep = reps[data.id]
-
-    for (var key in data) {
-        if (key == 'outputs') {
-            rep.outputs = data.outputs
-        }
-    }
-
-    redrawLinks()
 }
 
 // update state from server to UI
-function changeState(data) {
+function heapSendsNewState(data) {
+    console.log('HEAP SENDS CHANGE STATE IN MODULE', data)
     var rep = reps[data.id]
     for (var key in data.state) {
         if (data.state[key].isButton) {
@@ -239,13 +323,11 @@ function changeState(data) {
     }
 }
 
-function isStateKey(key) {
-    if (key.indexOf('_') == 0 || key == 'emitters' || key == 'onChange' || key == 'emitChange') {
-        return false
-    } else {
-        return true
-    }
-}
+/*
+
+UI -> HEAP ---------------------------------------------------
+
+*/
 
 // push new state from UI to server 
 function putState(rep) {
@@ -269,42 +351,45 @@ function putUi(rep) {
     socketSend('put ui', data)
 }
 
-var clkState = false
-var oClk = {}
-var tmpBz = {}
+/*
 
-// input / output click handling
-function evtConnectHandler(clk) {
-    if (!clkState) {
-        // first click
-        oClk = clk
-        clkState = true
+UTILITIES? ---------------------------------------------------
+
+*/
+
+function isStateKey(key) {
+    if (key.indexOf('_') == 0 || key == 'emitters' || key == 'onChange' || key == 'emitChange') {
+        return false
     } else {
-        // second click
-        var tClk = clk
-        console.log(oClk, tClk)
-        var x1 = parseInt(oClk.evt.target.offsetParent.style.left, 10) + oClk.evt.target.offsetLeft + oClk.evt.target.clientWidth
-        var y1 = parseInt(oClk.evt.target.offsetParent.style.top, 10) + oClk.evt.target.offsetTop + oClk.evt.target.clientHeight / 2
-        var x2 = parseInt(tClk.evt.target.offsetParent.style.left, 10) + tClk.evt.target.offsetLeft
-        var y2 = parseInt(tClk.evt.target.offsetParent.style.top, 10) + tClk.evt.target.offsetTop + tClk.evt.target.clientHeight / 2
-        var bz = newBezier(x1, y1, x2, y2)
-        clkState = false
+        return true
+    }
+}
 
-        console.log('connect', oClk.rep.id, oClk.name, 'to', tClk.rep.id, tClk.name)
-        var data = {
-            from: {
-                id: oClk.rep.id,
-                output: oClk.name
-            },
-            to: {
-                id: tClk.rep.id,
-                input: tClk.name
+function redrawLinks() {
+    // probably not a great way to do this, we're removing everything
+    // svg -rm -r 
+    while (svg.firstChild) {
+        svg.removeChild(svg.firstChild)
+    }
+    // redraw thru all links, just look at reps
+    for(mdlName in program.modules){
+        var mdlRep = program.modules[mdlName]
+        for(key in mdlRep.outputs){
+            var output = mdlRep.outputs[key]
+            var outputUi = mdlRep.ui.outputs[key]
+            for (input in output.calls) {
+                var toId = output.calls[input].parentId
+                var toKey = output.calls[input].key
+                var inputUi = program.modules[toId].ui.inputs[toKey]
+                var outPos = getOutputArrow(outputUi)
+                var inPos = getInputArrow(inputUi)
+                var bz = newBezier(outPos.x, outPos.y, inPos.x, inPos.y)
             }
         }
-        socketSend('put link', data)
     }
 }
 
+
 // need top level rep of program - nice to think of how to handle heirarchy later on? tl rep is internal rep ... is same ? 
 // how to handle movement of rep, incl. svg - goes with moving mouse after 1st click: svg lives 'in' rep ? 
 
@@ -315,99 +400,58 @@ function evtConnectHandler(clk) {
 var svgns = 'http://www.w3.org/2000/svg'
 var svg = {}
 
-// 651 
-// 1554
-
-
 /*
-var crv = {}
 
-document.addEventListener('mousemove', function(evt) {
-    modifyBezier(crv, 0, 0, evt.pageX, evt.pageY)
-})
-*/
+UI EVENTS ---------------------------------------------------
 
-// return ul element with name and alt and link? 
-function buildMenu(tree) {
-    var menuDom = document.createElement('div')
-    menuDom.id = 'menu'
-    menuDom.style.left = lastPos.X + 'px'
-    menuDom.style.top = lastPos.Y + 'px'
-    for (key in tree) {
-        var ul = document.createElement('ul')
-        ul.innerHTML = key.toString()
-        for (subkey in tree[key]) {
-            var li = document.createElement('li')
-            var path = tree[key][subkey].path
-            li.innerHTML = subkey.toString()
-            li.id = path
-            li.addEventListener('click', function(evt) {
-                var data = this.id
-                socketSend('add module', data)
-                wrapper.removeChild(document.getElementById('menu'))
-            })
-            ul.appendChild(li)
-        }
-        menuDom.appendChild(ul)
-    }
-    wrapper.append(menuDom)
+*/
 
-    function rmListener(evt) {
-        var findMenu = document.getElementById('menu')
-        if (findMenu !== null && findMenu.id == 'menu') {
-            wrapper.removeChild(findMenu)
-        }
+// get json menu item and render
+// and ask for module at /obj/key
+oncontextmenu = function(evt) {
+    if (sckt) {
+        lastPos.x = evt.pageX
+        lastPos.y = evt.pageY
+        socketSend('get module menu', '')
+    } else {
+        // socket brkn, reload page 
+        location.reload()
     }
-
-    document.addEventListener('click', rmListener)
+    // prevents event bubbling 
+    return false
 }
 
-// init & hookup
-
-window.onload = function() {
-    svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
-    svg.style.position = 'absolute'
-    svg.style.left = 0
-    svg.style.top = 0
-    svg.style.zIndex = 0
-    svg.style.overflow = 'visible'
-    svg.setAttribute('width', 2)
-    svg.setAttribute('height', 2)
-    svg.setAttribute('id', 'svg')
-    svg.setAttribute('width', '100%')
-    svg.setAttribute('height', '100%')
-    document.body.appendChild(svg)
-
-    wrapper = document.createElement('div')
-    wrapper.id = 'wrapper'
-    document.body.append(wrapper)
-
-    const socket = new WebSocket('ws://localhost:8081')
+var clkState = false
+var oClk = {}
+var tmpBz = {}
 
-    socket.onopen = function(evt) {
-        // pass to global ref 
-        sckt = this
-        // say hello 
-        socketSend('console', 'hello server')
-        console.log('socket open')
-        // main socket entry point
-        this.onmessage = (evt) => {
-            socketRecv(evt)
-        }
-        // others
-        this.onerror = (err) => {
-            console.log('socket error', err)
-        }
-        this.onclose = (evt) => {
-            console.log('socket closed', evt)
-            sckt = null
+// input / output click handling
+function evtConnectHandler(clk) {
+    if (!clkState) {
+        // first click
+        oClk = clk
+        clkState = true
+    } else {
+        // second click
+        var tClk = clk
+        //console.log(oClk, tClk)
+        var x1 = parseInt(oClk.evt.target.offsetParent.style.left, 10) + oClk.evt.target.offsetLeft + oClk.evt.target.clientWidth
+        var y1 = parseInt(oClk.evt.target.offsetParent.style.top, 10) + oClk.evt.target.offsetTop + oClk.evt.target.clientHeight / 2
+        var x2 = parseInt(tClk.evt.target.offsetParent.style.left, 10) + tClk.evt.target.offsetLeft
+        var y2 = parseInt(tClk.evt.target.offsetParent.style.top, 10) + tClk.evt.target.offsetTop + tClk.evt.target.clientHeight / 2
+        //var bz = newBezier(x1, y1, x2, y2)
+        clkState = false
+        //console.log('connect', oClk.rep.description.id, oClk.name, 'to', tClk.rep.description.id, tClk.name)
+        var data = {
+            from: {
+                id: oClk.rep.description.id,
+                output: oClk.name
+            },
+            to: {
+                id: tClk.rep.description.id,
+                input: tClk.name
+            }
         }
+        socketSend('put link', data)
     }
-}
-
-/*
- - add inputs and outputs
- - ui for link inputs and outputs 
-
- - .. hold svg's in div of ui element rep.ui.domElement - also track endpts there, write tiny svg class ? then .onmove etc ties through to all elements ? 
-*/
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/client/divtools.js b/client/divtools.js
index 1b57063a28793b6dbc1df51a0ffa26517892167a..fb99fc95f2f751966ae58b2dcae357417e463410 100644
--- a/client/divtools.js
+++ b/client/divtools.js
@@ -2,68 +2,56 @@
 
 function writeStateRep(container, rep, key) {
     var variable = rep.state[key]
-    if (variable.isButton) {
-        console.log('BUTTON!')
-        var li = document.createElement('li')
-        li.appendChild(document.createTextNode(variable.label))
-        li.addEventListener('click', function() {
-            // invert 
-            if (rep.state[key].isPressed) {
-                rep.state[key].isPressed = false
-            } else {
-                rep.state[key].isPressed = true
-            }
-            putState(rep)
-        })
-        container.appendChild(li)
-        return li
-    } else if (variable.isMultiLine) {
-        console.log('MULTILINE!')
-        var li = document.createElement('li')
-        li.appendChild(document.createTextNode(variable.label))
-        li.appendChild(document.createElement('br'))
-        var txtArea = document.createElement('textarea')
-        txtArea.rows = variable.rows
-        txtArea.cols = 27
-        txtArea.value = variable.value 
-        txtArea.addEventListener('change', function(){
-            rep.state[key].value = txtArea.value
-            putState(rep)
-        })
-        li.appendChild(txtArea)
-        container.appendChild(li)
-        return txtArea
-    } else {
-        if (typeof variable == 'string') {
+    switch (variable.type) {
+        case 'button':
+            console.log('BUTTON!')
             var li = document.createElement('li')
-            li.appendChild(document.createTextNode(key))
-            var input = document.createElement('input')
-            input.type = 'text'
-            input.size = 24
-            input.value = variable
-            input.addEventListener('change', function() {
-                rep.state[key] = input.value
+            li.appendChild(document.createTextNode(variable.label))
+            li.addEventListener('click', function() {
+                // invert 
+                if (rep.state[key].isPressed) {
+                    rep.state[key].isPressed = false
+                } else {
+                    rep.state[key].isPressed = true
+                }
                 putState(rep)
             })
-            li.appendChild(input)
             container.appendChild(li)
-            return input
-        } else if (typeof variable == 'number') {
+            return li
+            break
+        case 'multiline':
+            console.log('MULTILINE!')
             var li = document.createElement('li')
-            li.appendChild(document.createTextNode(key))
-            var input = document.createElement('input')
-            input.type = 'text'
-            input.size = 24
-            input.value = variable.toString()
-            input.addEventListener('change', function() {
-                rep.state[key] = parseFloat(input.value)
+            li.appendChild(document.createTextNode(variable.label))
+            li.appendChild(document.createElement('br'))
+            var txtArea = document.createElement('textarea')
+            txtArea.rows = variable.rows
+            txtArea.cols = 27
+            txtArea.value = variable.value
+            txtArea.addEventListener('change', function() {
+                rep.state[key].value = txtArea.value
                 putState(rep)
             })
-            li.appendChild(input)
+            li.appendChild(txtArea)
             container.appendChild(li)
-            return input
-        } else if (typeof variable == 'object') {
-            if (Array.isArray(variable)) {
+            return txtArea
+            break
+        default:
+            if (typeof variable == 'string') {
+                var li = document.createElement('li')
+                li.appendChild(document.createTextNode(key))
+                var input = document.createElement('input')
+                input.type = 'text'
+                input.size = 24
+                input.value = variable
+                input.addEventListener('change', function() {
+                    rep.state[key] = input.value
+                    putState(rep)
+                })
+                li.appendChild(input)
+                container.appendChild(li)
+                return input
+            } else if (typeof variable == 'number') {
                 var li = document.createElement('li')
                 li.appendChild(document.createTextNode(key))
                 var input = document.createElement('input')
@@ -71,20 +59,36 @@ function writeStateRep(container, rep, key) {
                 input.size = 24
                 input.value = variable.toString()
                 input.addEventListener('change', function() {
-                    var arr = input.value.split(',')
-                    arr.forEach(function(element, index, array) {
-                        array[index] = parseFloat(element)
-                    })
-                    rep.state[key] = arr
+                    rep.state[key] = parseFloat(input.value)
                     putState(rep)
                 })
                 li.appendChild(input)
                 container.appendChild(li)
                 return input
+            } else if (typeof variable == 'object') {
+                if (Array.isArray(variable)) {
+                    var li = document.createElement('li')
+                    li.appendChild(document.createTextNode(key))
+                    var input = document.createElement('input')
+                    input.type = 'text'
+                    input.size = 24
+                    input.value = variable.toString()
+                    input.addEventListener('change', function() {
+                        var arr = input.value.split(',')
+                        arr.forEach(function(element, index, array) {
+                            array[index] = parseFloat(element)
+                        })
+                        rep.state[key] = arr
+                        putState(rep)
+                    })
+                    li.appendChild(input)
+                    container.appendChild(li)
+                    return input
+                }
+            } else {
+                console.log("unui'd type:", typeof variable)
             }
-        } else {
-            console.log("unui'd type:", typeof variable)
-        }
+            break
     }
 }
 
@@ -123,7 +127,6 @@ function newBezier(x1, y1, x2, y2) {
     return bz
 }
 
-
 function redrawBezier(bz) {
     var bl = Math.sqrt(Math.pow((bz.x1 - bz.x2), 2) + Math.pow((bz.y1 - bz.y2), 2)) * 0.6
     var ps = 'M ' + bz.x1 + ' ' + bz.y1 + ' C ' + (bz.x1 + bl) + ' ' + bz.y1
diff --git a/main.js b/main.js
index 86ead59d7ccec40b9906fd82a464c2d226b4b402..fd762dd08ce1966dfc2647974a5a12c49a9175c7 100644
--- a/main.js
+++ b/main.js
@@ -1,6 +1,6 @@
 //
 //
-// new node controller
+// new node controller / HEAP 
 //
 // main.js
 //
@@ -18,27 +18,11 @@
 
 RULES:
 
-*/
-
-/*
-
-SERVER
+modules are objects having inputs, outputs, and state 
+programs are assemblies of modules 
 
 */
 
-/*
-------------------------------------------------------
-PROGRAM AS API
-------------------------------------------------------
-*/
-
-// nodes are objects having inputs, outputs, and state
-// nodes can be made up of other nodes 
-// a node originates somewhere, 
-
-// is it a JSON, or a txt .js file ? loadProgram and loadModule ...
-// it wants to be an object that gets 'read' in ... 
-
 const Reps = require('./reps.js')
 const Programs = require('./programs.js')
 
@@ -59,46 +43,7 @@ PROGRAM REPRESENT
 
 */
 
-//console.log('modules at prgmem start', modules)
-function putReps() {
-    var reps = new Array()
-    for (mod in modules) {
-        reps.push(makeRep(modules[mod]))
-    }
-    socketSend('add reps', reps)
-}
-
-function makeRep(mod) {
-    // scrape for only things we'll want to represent 
-    var rep = {
-        id: mod.id,
-        desc: mod.description,
-        inputs: mod.inputs,
-        outputs: mod.outputs,
-        state: {}
-    }
-
-    // holds UI information - to load mods at location
-    if (mod.ui != null) {
-        rep.ui = mod.ui
-    }
-
-    for (var key in mod.state) {
-        if (isStateKey(key)) {
-            rep.state[key] = mod.state[key]
-        }
-    }
-
-    return rep
-}
-
-function putRep(mod) {
-    socketSend('add rep', makeRep(mod))
-}
-
-function changeRep(mod) {
-    socketSend('change rep', makeRep(mod))
-}
+/*
 
 // update state from UI to server 
 function changeState(data) {
@@ -188,23 +133,6 @@ function putLink(data) {
     changeRep(fromModule)
 }
 
-function buildMenu() {
-    var tree = {}
-    var dir = fs.readdirSync('./src')
-    for (i in dir) {
-        tree[dir[i]] = {}
-        var subdir = fs.readdirSync('./src/' + dir[i])
-        for (j in subdir) {
-            // find js files
-            if (subdir[j].slice(-3) === '.js') {
-                var obj = {}
-                obj.path = './src/' + dir[i] + '/' + subdir[j]
-                tree[dir[i]][subdir[j].slice(0, -3)] = obj
-            }
-        }
-    }
-
-    return tree
-}
+*/
 
 // put
\ No newline at end of file
diff --git a/reps.js b/reps.js
index 7e0024105b23bd1a452cb63184f9fa2bf9c702e0..81a4fbeda41ae95ec00ad096a1f8053bf894d222 100644
--- a/reps.js
+++ b/reps.js
@@ -1,3 +1,6 @@
+const JSUnit = require('./lib/jsunit.js')
+let isStateKey = JSUnit.isStateKey
+
 function makeRepFromModule(mdl) {
     var rep = {
         description: {
diff --git a/save/onesave.json b/save/onesave.json
index 97421540da2a85a82027de9155330c52a0a90723..9f9dcf6bfc6ebc9864e10e8ab6e09e845eede9d1 100644
--- a/save/onesave.json
+++ b/save/onesave.json
@@ -23,10 +23,6 @@
             {
               "parentId": "delay-2",
               "key": "thru"
-            },
-            {
-              "parentId": "logger-3",
-              "key": "thru"
             }
           ]
         }
diff --git a/views.js b/views.js
index 80c3782025b1aadf572cbdad72a75606ae71d53a..57bfa9d0fa32c409a7c14f7cbac4f484fec3c28c 100644
--- a/views.js
+++ b/views.js
@@ -8,13 +8,15 @@ const http = require('http').Server(app)
 // websocket, to share program representations with the client (and back)
 const WebSocket = require('ws')
 
+const Reps = require('./reps.js')
+
 /*
 
-SERVER AND WS SETUP
+SERVER AND WS SETUP --------------------------------------------------
 
 */
 
-var program = null 
+var program = null
 var sckt = null
 
 function startHttp() {
@@ -45,7 +47,6 @@ function startWs() {
         // say hello
         socketSend('console', 'hello client')
         // send current config as list of all modules
-        uiInit()
         console.log('socket open on 8081')
         ws.on('message', (evt) => {
             socketRecv(evt)
@@ -53,6 +54,22 @@ function startWs() {
     })
 }
 
+/*
+
+HOOKUP REF TO TL ------------------------------------------------------
+
+*/
+
+function assignProgram(prgm) {
+    program = prgm
+}
+
+/*
+
+RECV / SEND PORTALS ---------------------------------------------------
+
+*/
+
 function socketRecv(evt) {
     var recv = JSON.parse(evt)
     var type = recv.type
@@ -63,25 +80,27 @@ function socketRecv(evt) {
         case 'console':
             console.log('RECV CONSOLE:', data)
             break
-        case 'get menu':
-            var tree = buildMenu()
-            socketSend('put menu', tree)
+        case 'get current program':
+            uiRequestCurrentProgram()
+            break
+        case 'get module menu':
+            uiRequestModuleMenu()
+            break
+        case 'load program':
+            uiRequestLoadProgram()
             break
-        case 'add module':
-            addModule(data)
+        case 'put module':
+            uiRequestNewModule(data)
             break
         case 'put state':
-            changeState(data)
+            uiRequestStateChange(data)
             break
         case 'put link':
-            putLink(data)
+            uiRequestLinkChange(data)
             // id:output > id:input
             break
         case 'put ui':
-            changeUi(data)
-            break
-        case 'rm link':
-            // id:output > id:input
+            uiRequestUiChange(data)
             break
         default:
             console.log('ERR server recv with non recognized type', recv)
@@ -100,18 +119,84 @@ function socketSend(type, data) {
     }
 }
 
-function assignProgram(prgm){
-    program = prgm
-}
+/*
+
+HEAP -> UI HANDLES ---------------------------------------------------
+
+*/
 
 // runs when browser first loads
-function uiInit(){
+function uiRequestCurrentProgram() {
     // make reps from program and send the list 
-    console.log("BRWSER LOADED")
-    console.log(program)
+    console.log('SEND PROGRAMS TO UI')
+    var prgRep = {
+        description: {
+            name: program.description.name,
+            id: program.description.id,
+            path: program.description.path
+        },
+        modules: {}
+    }
+
+    for (mdlName in program.modules) {
+        var mdlRep = Reps.makeFromModule(program.modules[mdlName])
+        prgRep.modules[mdlName] = mdlRep
+    }
+    socketSend('put program', prgRep)
+}
+
+function uiRequestModuleMenu() {
+    var availableSourceRep = {}
+    var dir = fs.readdirSync('./src')
+    for (i in dir) {
+        availableSourceRep[dir[i]] = {}
+        var subdir = fs.readdirSync('./src/' + dir[i])
+        for (j in subdir) {
+            // find js files
+            if (subdir[j].slice(-3) === '.js') {
+                var obj = {}
+                obj.path = './src/' + dir[i] + '/' + subdir[j]
+                availableSourceRep[dir[i]][subdir[j].slice(0, -3)] = obj
+            }
+        }
+    }
+
+    socketSend('put module menu', availableSourceRep)
 }
 
+/*
+
+UI -> HEAP HANDLES ---------------------------------------------------
+
+*/
+
+function uiRequestLoadProgram(data){
+    console.log('UI REQUEST TO OPEN NEW PROGRAM', data)
+}
 
+function uiRequestNewModule(data) {
+    console.log('UI REQUEST ADD MODULE TO PROGRAM', data)
+}
+
+function uiRequestStateChange(data) {
+    console.log('UI REQUEST CHANGE STATE IN MODULE', data)
+    // do state.obj.emit 
+}
+
+function uiRequestLinkChange(data) {
+    console.log('UI REQUEST ADD EVENT LINK', data)
+}
+
+function uiRequestUiChange(data) {
+    console.log('UI REQUEST ADD / CHANGE UI INFO TO MODULE', data)
+    // do it in module.description 
+}
+
+/*
+
+EXPORTS --------------------------------------------------------------
+
+*/
 
 module.exports = {
     startHttp: startHttp,