diff --git a/js/main.js b/js/main.js
index a791d31ae4664d8a78f7a0444ece690b0af77033..23b223034b663d5b1fa72010b3bbbb2a676a65b3 100644
--- a/js/main.js
+++ b/js/main.js
@@ -7,6 +7,12 @@ $(function(){
 
     three = Three();
     setupNavBar();
-    persistentWorkers(4);
+    workers = persistentWorkers(4);
+
+    workers.map([11,12,13,14,15, 18, 30], executable, {});
+
+    function executable(){
+        return arg*arg;
+    }
 
 });
diff --git a/js/persistentWorkers.js b/js/persistentWorkers.js
index 5a13971086795b473e3308aa79b44b6828985eab..a269ffc8ad68a6aa5bc08b8a404c0c8b9da85f48 100644
--- a/js/persistentWorkers.js
+++ b/js/persistentWorkers.js
@@ -8,22 +8,57 @@ function persistentWorkers(numWorkers){
         return nil;
     }
 
-    //create array of workers
+    //local variables
     var allWorkers = [];
+    var mapQueue = [];
+
+    //create array of workers
     var URL = window.URL || window.webkitURL;
     var workerURL = makeBlobURL(URL, myWorker);
     for (var i=0;i<numWorkers;i++){
         var worker = new Worker(workerURL);
-        var location = document.location;
-        worker.postMessage({url: location.toString()});
-        worker.postMessage([i,4]);
         worker.onmessage = workerCallback;
+        worker.postMessage({url: document.location.toString()});
         allWorkers.push(worker);
     }
     URL.revokeObjectURL(workerURL);
 
+    function map(data, executable, env){
+
+        //save args in map queue
+        mapQueue.push({data:data, executable:executable, env:env, index:0});
+
+        for (var i=0;i<allWorkers.length;i++){
+            allWorkers[i].postMessage({isWorking:true});//ask workers if they are busy
+        }
+    }
+
     function workerCallback(e){
-        console.log(e.data);
+
+        if (e.data.result) console.log(e.data.result);//handle result first
+
+        if (e.data.isWorking === false){
+            //get next work item off queue
+            if (mapQueue.length == 0) return;
+
+            var currentTask = mapQueue[0];
+            var currentIndex = currentTask.index;
+            currentTask.index = currentTask.index+1;
+
+            //check that the index is not out of bounds
+            if (currentTask.data.length<=currentIndex){
+                mapQueue.shift();//remove first element
+
+                e.data.result = null;//remove result so it doesn't get handled twice
+                workerCallback(e);//try again in case there is another item in the queue
+                return;
+            }
+
+            e.target.postMessage({
+                arg:currentTask.data[currentIndex],
+                localEnv:currentTask.env,
+                executable:currentTask.executable.toString()});
+        }
     }
 
     function makeBlobURL(URL, someFunction) {
@@ -31,4 +66,6 @@ function persistentWorkers(numWorkers){
         return URL.createObjectURL(blob);
     }
 
+    return {map:map}//return all public methods and vars
+
 }
\ No newline at end of file
diff --git a/js/worker.js b/js/worker.js
index ea476c9ab7b89aecb34906109f11b56d109e88fa..154f9e944b82b852b8f0b7e738c64dc2355cc3ba 100644
--- a/js/worker.js
+++ b/js/worker.js
@@ -3,6 +3,12 @@
  */
 
 function myWorker(){
+
+    //local variables
+    localEnv = null;//local variables passed in from outside
+    working = false;//boolean that says whether I'm busy or not
+    arg = null;//main data we are crunching
+
     self.onmessage = function(e) {
         var data = e.data;
 
@@ -15,13 +21,36 @@ function myWorker(){
         //load all scripts
         importScripts(url + 'dependencies/three.js');
     //    importScripts(url + 'js/element.js');
-            return;
+        }
+//
+//        if (data.id){
+//            id = data.id;
+//        }
+
+        if (data.executable){
+
+            if (data.localEnv){//be sure to get local environment vars before executable runs
+                localEnv = data.localEnv;
+            }
+            if (data.arg){//be sure to get arg before executable runs
+                arg = data.arg;
+            }
+
+            if (working) {
+                console.log("problem here, already working on something else");
+                return;
+            }
+            working = true;
+            eval(data.executable);
+            var result = executable();
+            working = false;
+            postMessage({result:result, isWorking:working});
         }
 
+        if (data.isWorking){
+            postMessage({isWorking:working});
+        }
 
-        console.log(new THREE.Vector3(0,3,4));
-        var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
-        postMessage(workerResult);
 
     };
 }