diff --git a/README.md b/README.md
index 7040549e33ea6d262b4bd347040a23ac5ebeabb3..363e5fba39bb945b06e65e20118d5666037b444a 100644
--- a/README.md
+++ b/README.md
@@ -17,151 +17,25 @@ bootstrap, numeric.js ...
 
 http://backbonejs.org/#Events
 
+## Desires
+ - load / keep state 
 
-... should figure out how mods does events, what do they attach to?
-... can we do a browser / node agnostic architecture? 
+## Model Consistency
 
+In Memory: array of modules
 
-best approach is to design what you'd like
- - code loading, unit sources, UI is built or specified in code?
- - how to serve / build UI's on top of, or connect top-level nodes at API level 
- - like, no bash make
+Saved / interfaced with: json of this - so to load from this, we need paths and ids attached to each module on load time.
 
+To wrap / add heirarchy: this json object can be loaded the same as a program, given top level inputs and outputs, and made into another require()d module. 
 
-## Network Motion Control Scheme
+Modules are tiny programs, specifics (inputs, outputs, state) are read by system and wrapped into UI. UI has access to write into state, and connect events together.
 
-Motors eat trapezoid packets, acknowledge when complete with int32_t of steps taken, updates window transmission and current position tracker. 
+To wrap, we write a representation in api-type rep, with one connection. We output the 'text line' of a Terminal into the 'text input' input of a gcode parser, and see the output / state bubble through the UI.
 
-Path planner has:
- - complete path in memory
- - current position
- - path ptrs:
-  - plan end (last segment accel planned for, zero exit speed)
-  - current segment (last segment to go out network buffer)
+ - to test, cleanup and write gcode obj
+ - confirm state change comes down to server
+ - confirm event bubbles through in server 
+ - push event back to server ui ? dat.updatedisplay() ? 
 
- - path planning is an app that uses atkapi
- - atkapi: create objs of hardware nodes,
-  - .settings 
-    .reset()
-    .disable()
-    ... etc 
-    - for replies, these obj's should fire events that can be listened to
-    
-automatakit
-automatickit 
-
-# Ambitions for this page 
-
- - landing page for all users, consider FAB14 workshop landing here 
-  - is machine / robot control for fungible machines 
-  - show video examples Reich, MoControl 
- - explain scheme, idea, statelessness and event-basedness 
-
- - practicum
-  - how to mkterminal, what is
-  - how to atk api javascript
-  - explain example application entry point
-  - explain example C code
-
-
-
-XX Is a collection of hardware, firmware and software that lets you build machines in the same way we build software: quickly, with great joy, and with rapid reconfiguration of resources.
-
-With XX, all of the motors, sensors, and end effectors in a machine are connected via a low-latency network that we call [APA](link). An API allows us to interface with this network to build applications for machine control. 
-
-```JavaScript
-Stepper.trapezoid(entry,steps,rate,exit);
-Stepper.onPacket(packet){
-	// on return packet
-}
-
-DCRotary.setPos(pos);
-DCRotary.onPacket(packet){
-	// 
-}
-
-// all have
-Endpoint.sendPacket(packet);
-Endpoint.onPacket(packet){
-	// returning
-}
-```
-
-Entry points to the network are through the [mksocketserver](link) and [mkterminal](link) interfaces. These open hardware ports on a host computer to send and receive messages across the network.
-
-Endpoints are hardware objects that receive control commands, and execute them faithfully: move motors, read sensors, heat things, control positions and currents, etc. 
-
-## APA Networking
- 
- - clean nomenclature: 'routers' are 'nodes' and can be just-routers or endpoints, etc, anything that lives on the network is a node
-
-### The Packet
-
-*Asynchronous Packet Automata* is a networking scheme from Neil Gershenfeld, wherein packets traverse a network not based on destination addresses, but on designated routes. In Technical Networking Language, is is a source-routed port-forwarding scheme, which means that routing is done at the source of the packet, and upon arriving at a position in the network, packets are forwarded along another port, or consumed at that position, based on the route contained in the packet. As the packet traverses the network, pieces of the route are 'consumed' and replaced with a reversed route, such that the destination knows how to return the packet.
-
-The structure of a packet is typically broken into bytes (8-bit long 'words') and is structured like this:
-
-![apa-packet](/images/apa-packet-structure.png)
-
-The 1st byte of any packet denotes the length of the complete packet, in bytes, and is used to parse packets arriving at nodes. For example, when a node starts receiving a packet, it takes the first byte arriving to be the length, and counts bytes until the end is reached, when it can then act on the packet. 
-
-### Routing
-
-Bytes in the route-header section of the packet designate the order of ports the packet should be forwarded on. When the packet arrives at a new network node, the node shifts-out the last port, and adds to the tail of the route-header the port that the packet arrived on, effectively adding return information to the route. The 'pointer' (we designate the byte representing 254, or ^ diagramatically), denotes the packet's current position in the route. 
-
-We can see an example packet traversal here:
-
-![apa-packet-traverse](/images/apa-packet-traverse.png)
-
-![apa-packet-route-shift](/images/apa-packet-shift.png)
-
-Because of the route-header shifting, the 1st byte in the route-header always denotes the port number which the packet should leave the current node on. If the 1st byte in the route-header is the pointer (^ or 254) the packet is at its destination and should be consumed by that node. At this point, the tail of the packet-header contains a route which, when reversed, forms a route back to it's original source. 
-
-![apa-packet-reply](/images/apa-packet-reply.png)
-
-### The Physical Layer 
-
-APA does not designate a particular Physical Layer (in Networking Nomenclature, referred to as a 'PHY', or Layer 2). AutomataKit uses a microcontroller's UART peripheral for the PHY layer, but we are expanding to use FPGAs and a per-bit token-passing scheme, as well as exploring wireless links.  
-
-### Hardware Implementation
-
-The network nodes implemented in AutomataKit use a UART Physical Layer. This means that network packets arrive on a per-byte basis, and are parsed into packets in the microcontroller's C code (firmware). 
-
-... etc 
-
-
-## Endpoints
-
-Endpoints are hardware...
-
-Global API
-
-**127** test, turns on a light and returns the packet
-
-**128** reset, resets the board
-
-**129** setpos,
-
-**130** getpos,
-
-**131** trapezoid,
-
-### MKRouter
-
-### MKStepper17
-
-### MKStepper23
-
-### MKBLDCDriver
-
-### MKBreadBoardBoard
-
-### MKSmallRotary
-
-## Applications
-
- - example applications do:
-  - mocontrol acceleration
-  - dynamic control
-  - feedback?
+For extra points, we read in the connection also with an SVG layer - iterating through connections of the represented program.
 
diff --git a/client/client.js b/client/client.js
index aee399d4c1ff0497c0a8c589873c7f678724cb23..e8c7915561d9862880af8a7650c086dcea6a0ac3 100644
--- a/client/client.js
+++ b/client/client.js
@@ -21,6 +21,25 @@ 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
+        var req = {
+            type: 'get menu',
+            data: ''
+        }
+        sckt.send(JSON.stringify(req))
+    } else {
+        // socket brkn 
+        location.reload()
+    }
+    // prevents event bubbling 
+    return false
+}
+
 function socketRecv(evt) {
     var recv = JSON.parse(evt.data)
     var type = recv.type
@@ -30,35 +49,30 @@ function socketRecv(evt) {
         case 'console':
             console.log('recv console:', data)
             break
+        case 'program':
+            console.log('recv program')
+            addReps(data)
+            break
         case 'put menu':
             buildMenu(data)
             break
         case 'put new rep':
             addRep(data)
             break
+        case 'put state':
+            changeState(data)
+            break
         default:
             console.log('recv with non recognized type', recv)
             break
     }
 }
 
-// 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
-        var req = {
-            type: 'get menu',
-            data: ''
-        }
-        sckt.send(JSON.stringify(req))
-    } else {
-        // socket brkn 
-        location.reload()
+function addReps(data){
+    for(module in data){
+        addRep(data[module])
+        console.log(data[module])
     }
-    // prevents event bubbling 
-    return false
 }
 
 // return ul element with name and alt and link? 
@@ -96,11 +110,6 @@ function buildMenu(tree) {
     document.addEventListener('click', rmListener)
 }
 
-
-function get(data) {
-
-}
-
 // write html from json representation
 function addRep(rep) {
     // a div to locate it 
@@ -197,8 +206,6 @@ function addRep(rep) {
             title.onmouseup = null
         }
     }
-
-    console.log(rep.ui)
     reps.push(rep)
     wrapper.appendChild(rep.ui.domElem)
 }
@@ -240,9 +247,45 @@ function evtConnectHandler(clk) {
         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.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
+            }
+        }
+        socketSend('put link', data)
     }
 }
 
+function changeState(mod){
+    var ors = reps[mod.id].state
+    var nrs = mod.state
+
+    for(key in nrs){
+        if(ors[key] != nrs[key]){
+            ors[key] = nrs[key]
+            console.log(ors)
+            for(var i in reps[mod.id].ui.dat.__controllers){
+                reps[mod.id].ui.dat.__controllers[i].updateDisplay()
+            }
+            console.log(key, 'to', nrs[key], 'in', mod.id)
+        }
+    }
+}
+
+// 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 ? 
+
+// trying to do this top level from the program config itself, will try sending jsonified modules[] 
+
+// consistency with saved formats, written formats, sent... json objs
+
 var svgns = 'http://www.w3.org/2000/svg'
 var svg = {}
 
@@ -298,7 +341,6 @@ function newState(rep) {
         state: rep.state
     }
     socketSend('put state', data)
-    console.log('pushing new state', data)
 }
 
 // init & hookup
diff --git a/lib/inout.js b/lib/inout.js
index d8b48b1d8cd122d28cdf2f5d1924d4065a3cb5e4..5a27283c62f3bdb5053b58a92afe4ce16f9f2786 100644
--- a/lib/inout.js
+++ b/lib/inout.js
@@ -14,7 +14,7 @@ function Output(type){
 	this.calls = new Array()
 
 	this.attach = (input) => {
-		this.calls.push(input.fn)
+		this.calls.push(input)
 	}
 
 	this.emit = (data) => {
@@ -23,7 +23,7 @@ function Output(type){
 			console.log('no events bound to this event: ', this.name)
 		} else {
 			for(index in this.calls){
-				this.calls[index](data)
+				this.calls[index].fn(data)
 			}
 		}
 	}
diff --git a/server.js b/server.js
index 6350706dd3612bcae0a7913c55c7781d59ee6468..780f6d65d23b4eaad2584979bc4b083a0fce092b 100644
--- a/server.js
+++ b/server.js
@@ -24,7 +24,10 @@ const wss = new WebSocket.Server({ port: 8081 })
 
 wss.on('connection', (ws) => {
     sckt = ws
+    // say hello
     socketSend('console', 'hello client')
+    // send current config 
+    socketSend('program', modules)
     console.log('socket open on 8081')
     ws.on('message', (evt) => {
         socketRecv(evt)
@@ -38,16 +41,27 @@ http.listen(8080, () => {
 
 // server globals 
 
-var sckt = {}
+var sckt = null
 
 var modules = new Array()
 
+// wrap require() up, appending path used to object, and giving ID
+// use the same to load from browser 
+var termOne = addModule('./src/ui/terminal.js')
+var termTwo = addModule('./src/ui/terminal.js')
+
+termOne.outputs.lineOut.attach(termTwo.lineIn)
+
+console.log(modules)
+
 function socketSend(type, data) {
-    var msg = {
-        type: type,
-        data: data
+    if (sckt) {
+        var msg = {
+            type: type,
+            data: data
+        }
+        sckt.send(JSON.stringify(msg))
     }
-    sckt.send(JSON.stringify(msg))
 }
 
 function socketRecv(evt) {
@@ -70,6 +84,7 @@ function socketRecv(evt) {
             newState(data)
             break
         case 'put link':
+            putLink(data)
             // id:output > id:input
             break
         case 'rm link':
@@ -85,42 +100,63 @@ function addModule(path) {
     // get and add to server system
     if (fs.existsSync(path)) {
         var src = require(path) // get and return 
-        var mod = new src()
-        modules.push(mod)
+        var mod = new src() // make a new one
+        modules.push(mod) // add to the system
+
+        // assign and id and remember from whence it came
         mod.id = modules.length - 1
-        console.log('adding module', mod.description.name, 'id', mod.id)
-        // mod.inputs.lineIn.fn('log')
+        mod.path = path
 
+        // add hooks to external fn's
+        mod.emitStateChange = onStateOutput
+        console.log('adding module', mod.description.name, 'id', mod.id)
         // now roll and return representable object 
+        // first to UI
         socketSend('put new rep', mod)
+        // also to fn call, in case writing program ? 
+        return mod
     } else {
         console.log('no module found at', path)
     }
 }
 
+function onStateOutput(mod){
+    socketSend('put state', mod)
+}
+
 function newState(data) {
+    // of one module 
     // should just recv all state, walk tree for differences
-    var os = modules[data.id].state 
+    var os = modules[data.id].state
     var ns = data.state
     var id = data.id
 
     for (key in os) {
-        if (typeof os[key] == 'object' && os[key] !== null) {
-            for (subkey in os[key]) {
-                if(os[key][subkey] != ns[key][subkey]){
-                    os[key][subkey] = ns[key][subkey]
-                    console.log(subkey, 'to ', ns[key][subkey], 'in', data.id)
-                }
-            }
-        } else {
-            if(os[key] != ns[key]){
-                os[key] = ns[key]
-                console.log(key, 'to ', ns[key], 'in', data.id)
-            }
+        if (os[key] != ns[key]) {
+            os[key] = ns[key]
+            console.log(key, 'to ', ns[key], 'in', data.id)
+            modules[data.id].onStateChange(key)
         }
     }
 }
 
+function putLink(data) {
+    var fromModule = modules.find((module) => {
+        return module.id === data.from.id
+    })
+
+    var toModule = modules.find((module) => {
+        return module.id === data.to.id
+    })
+
+    console.log('from', fromModule)
+    console.log('to', toModule)
+
+    fromModule.outputs[data.from.output].attach(toModule.inputs[data.to.input])
+
+    console.log('new from', fromModule)
+}
+
 function put(data) {
     switch (data.target) {
         case 'state':
diff --git a/src/ui/terminal.js b/src/ui/terminal.js
index 956c925cb720a0a65d897e0ba3937cf623c7c4de..843cb2daf77513fce4cb8db80dbfbaee1c217eda 100644
--- a/src/ui/terminal.js
+++ b/src/ui/terminal.js
@@ -15,12 +15,23 @@ function Terminal() {
 
     // object state
     this.state = {
-        inputSize: {
-            width: 64,
-            height: 48
-        },
+        width: 64,
+        height: 48,
         width: 12,
-        text: 'one line'
+        input: 'one line',
+        output: 'output line'
+    }
+
+    this.onStateChange = function(key) {
+        console.log('changing state', key)
+        switch(key){
+            case 'input':
+                post(this.state.input)
+                break
+            default:
+                console.log('key with no switch')
+                break
+        }
     }
 
     // natural inputs / local functions
@@ -36,6 +47,11 @@ function Terminal() {
     */
 
     var post = (str) => {
+        // update internal state of output
+        this.state.output = str
+        // hook to send state to UI
+        console.log(this.emitStateChange)
+        this.emitStateChange(this)
         console.log(str)
     }