{"modules":{"0.2535609410541485":{"definition":"//\n// step\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2016\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the fab modules \n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'z scan'\n//\n// initialization\n//\nvar init = function() {\n mod.value.value = ''\n mod.start.value = 0\n mod.stop.value = 10\n mod.step.value = 1\n }\n//\n// inputs\n//\nvar inputs = {\n start:{type:'event',\n event:function(evt) {\n mod.nextvalue = parseFloat(mod.start.value)\n update_value()\n }},\n step:{type:'event',\n event:function(evt) {\n update_value()\n }}}\n//\n// outputs\n//\nvar outputs = {\n begin:{type:'event',\n event:function() {\n mods.output(mod,'begin','begin')\n }},\n value:{type:'number',\n event:function() {\n mods.output(mod,'value',parseFloat(mod.value.value))\n }},\n end:{type:'event',\n event:function() {\n mods.output(mod,'end','end')\n }}}\n//\n// interface\n//\nvar interface = function(div) {\n mod.div = div\n div.appendChild(document.createTextNode('value: '))\n input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.value = input\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('start: '))\n input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.start = input\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('stop: '))\n input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.stop = input\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('step: '))\n input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.step = input\n }\n//\n// local functions\n//\nfunction update_value() {\n var value = mod.nextvalue\n mod.value.value = value\n var start = parseFloat(mod.start.value)\n var stop = parseFloat(mod.stop.value)\n var step = parseFloat(mod.step.value)\n if (value == start)\n outputs.begin.event()\n if (start < stop) {\n if (value <= stop) {\n outputs.value.event()\n mod.nextvalue = value + step\n }\n else {\n mod.value.value = ''\n outputs.end.event()\n }\n }\n else {\n if (value >= stop) {\n outputs.value.event()\n mod.nextvalue = value + step\n }\n else {\n mod.value.value = ''\n outputs.end.event()\n }\n }\n }\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"271","left":"233","inputs":{},"outputs":{}},"0.9339870295565246":{"definition":"//\n// step and delay\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2016\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the fab modules \n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'theta scan'\n//\n// initialization\n//\nvar init = function() {\n mod.value.value = ''\n mod.start.value = 0\n mod.stop.value = 10\n mod.step.value = 1\n mod.delay.value = 0.1\n mod.timeout == ''\n }\n//\n// inputs\n//\nvar inputs = {\n start:{type:'event',\n event:function(evt) {\n mod.nextvalue = parseFloat(mod.start.value)\n update_value()\n }}}\n//\n// outputs\n//\nvar outputs = {\n begin:{type:'event',\n event:function() {\n mods.output(mod,'begin','begin')\n }},\n value:{type:'number',\n event:function() {\n mods.output(mod,'value',parseFloat(mod.value.value))\n }},\n end:{type:'event',\n event:function() {\n mods.output(mod,'end','end')\n }}}\n//\n// interface\n//\nvar interface = function(div) {\n mod.div = div\n div.appendChild(document.createTextNode('value: '))\n input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.value = input\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('start: '))\n input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.start = input\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('stop: '))\n input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.stop = input\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('step: '))\n input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.step = input\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('delay (s): '))\n input= document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.delay = input\n div.appendChild(document.createElement('br'))\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('start'))\n btn.addEventListener('click',function(){\n mod.nextvalue = parseFloat(mod.start.value)\n update_value()\n })\n div.appendChild(btn)\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('stop'))\n btn.addEventListener('click',function(){\n window.clearTimeout(mod.timeout)\n mod.value.value = ''\n })\n div.appendChild(btn)\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n var text = document.createTextNode('pause')\n mod.pause = text\n btn.appendChild(text)\n btn.addEventListener('click',function(){\n if (mod.timeout != '') {\n window.clearTimeout(mod.timeout)\n mod.pause.nodeValue = 'resume'\n mod.timeout = ''\n }\n else {\n mod.pause.nodeValue = 'pause'\n var delay = 1000*parseFloat(mod.delay.value)\n mod.timeout = window.setTimeout(update_value,delay)\n }\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\nfunction update_value() {\n var value = mod.nextvalue\n mod.value.value = value\n var start = parseFloat(mod.start.value)\n var stop = parseFloat(mod.stop.value)\n var step = parseFloat(mod.step.value)\n var delay = 1000*parseFloat(mod.delay.value)\n if (value == start)\n outputs.begin.event()\n if (start < stop) {\n if (value <= stop) {\n outputs.value.event()\n mod.nextvalue = value + step\n mod.timeout = window.setTimeout(update_value,delay)\n }\n else {\n mod.value.value = ''\n outputs.end.event()\n }\n }\n else {\n if (value >= stop) {\n outputs.value.event()\n mod.nextvalue = value + step\n mod.timeout = window.setTimeout(update_value,delay)\n }\n else {\n mod.value.value = ''\n outputs.end.event()\n }\n }\n }\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"489","left":"206","inputs":{},"outputs":{}},"0.0011659221974470446":{"definition":"//\n// format string\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2015\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the fab modules \n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'format packet'\n//\n// initialization\n//\nvar init = function() {\n mod.expression.value = \"'z: '+mod.var1+', theta: '+mod.var2\"\n }\n//\n// inputs\n//\nvar inputs = {\n var1:{type:'String',\n event:function(evt) {\n mod.var1 = evt.detail\n format_string()\n }},\n var2:{type:'String',\n event:function(evt) {\n mod.var2 = evt.detail\n format_string()\n }}}\n//\n// outputs\n//\nvar outputs = {\n output:{type:'String',\n event:function(){\n mods.output(mod,'output',mod.value.value)\n }}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n div.appendChild(document.createTextNode('expression:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',mods.ui.rows)\n text.setAttribute('cols',mods.ui.cols)\n text.addEventListener('input',function(evt) {\n format_string()\n })\n div.appendChild(text)\n mod.expression = text\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('value:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',mods.ui.rows)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.value = text\n }\n//\n// local functions\n//\nfunction format_string() {\n mod.value.value = eval(mod.expression.value)\n outputs.output.event()\n }\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"531","left":"716","inputs":{},"outputs":{}},"0.24205313692818475":{"definition":"//\n// event generator\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2016\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the fab modules \n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'start scan'\n//\n// initialization\n//\nvar init = function() {\n mod.event.value = 'start'\n }\n//\n// inputs\n//\nvar inputs = {\n trigger:{type:'event',\n event:function(evt){\n outputs.output.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n output:{type:'event',\n event:function(){\n mods.output(mod,'output',mod.event.value)}}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // generate button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('generate'))\n btn.addEventListener('click',function(){\n outputs.output.event()\n })\n div.appendChild(btn)\n //\n // event value\n //\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('value: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('change',function(){\n })\n div.appendChild(input)\n mod.event = input\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"97","left":"207","inputs":{},"outputs":{}},"0.7206492720988903":{"definition":"//\n// video\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2015,6\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the fab modules \n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'video'\n//\n// initialization\n//\nvar init = function() {\n mod.width.value = 640 \n mod.height.value = 480\n start_video()\n }\n//\n// inputs\n//\nvar inputs = {\n capture:{type:'event',\n event:function(evt){\n capture_video()}}}\n//\n// outputs\n//\nvar outputs = {\n image:{type:'RGBA',\n event:function(){\n var ctx = mod.img.getContext(\"2d\")\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n mods.output(mod,'image',img)}}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // on-screen drawing canvas\n //\n var canvas = document.createElement('canvas')\n canvas.width = mods.ui.canvas\n canvas.height = mods.ui.canvas\n canvas.style.backgroundColor = 'rgb(255,255,255)'\n div.appendChild(canvas)\n mod.canvas = canvas\n div.appendChild(document.createElement('br'))\n //\n // off-screen image canvas\n //\n var canvas = document.createElement('canvas')\n mod.img = canvas\n //\n // capture button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('capture'))\n btn.addEventListener('click',function() {\n capture_video()\n })\n div.appendChild(btn)\n div.appendChild(document.createTextNode(' '))\n //\n // view button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('view'))\n btn.addEventListener('click',function(){\n var win = window.open('')\n var btn = document.createElement('button')\n btn.appendChild(document.createTextNode('close'))\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.addEventListener('click',function(){\n win.close()\n })\n win.document.body.appendChild(btn)\n win.document.body.appendChild(document.createElement('br'))\n var canvas = document.createElement('canvas')\n canvas.width = mod.img.width\n canvas.height = mod.img.height\n win.document.body.appendChild(canvas)\n var ctx = canvas.getContext(\"2d\")\n ctx.drawImage(mod.img,0,0)\n })\n div.appendChild(btn)\n div.appendChild(document.createElement('br'))\n //\n // width\n //\n div.appendChild(document.createTextNode('width: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('change',function() {\n update_video()\n })\n div.appendChild(input)\n mod.width = input\n div.appendChild(document.createElement('br'))\n //\n // height\n //\n div.appendChild(document.createTextNode(' height: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('change',function() {\n update_video()\n })\n div.appendChild(input)\n mod.height = input\n div.appendChild(document.createElement('br'))\n //\n // video element\n //\n var video = document.createElement('video')\n //div.appendChild(video)\n mod.video = video\n }\n//\n// local functions\n//\nfunction start_video() {\n var w = parseInt(mod.width.value)\n var h = parseInt(mod.height.value)\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = w\n ctx.canvas.height = h\n navigator.getMedia = (\n navigator.getUserMedia ||\n navigator.webkitGetUserMedia ||\n navigator.mozGetUserMedia ||\n navigator.msGetUserMedia)\n navigator.getMedia(\n {video:true,audio:false},\n function(stream) {\n var vendorURL = window.URL || window.webkitURL\n mod.video.src = vendorURL.createObjectURL(stream)\n mod.video.play()\n },\n function(err) {console.log(\"video startup error\")}\n )\n mod.video.addEventListener('canplay',\n function(evt) {\n mod.video.setAttribute('width',w)\n mod.video.setAttribute('height',h)\n capture_video()\n })\n }\nfunction update_video() {\n var w = parseInt(mod.width.value)\n var h = parseInt(mod.height.value)\n mod.video.setAttribute('width',w)\n mod.video.setAttribute('height',h)\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = w\n ctx.canvas.height = h\n }\nfunction capture_video() {\n var w = parseInt(mod.width.value)\n var h = parseInt(mod.height.value)\n var ctx = mod.img.getContext(\"2d\")\n ctx.drawImage(mod.video,0,0,w,h)\n if (w > h) {\n var x0 = 0\n var y0 = mod.canvas.height*.5*(1-h/w)\n var wd = mod.canvas.width\n var hd = mod.canvas.width*h/w\n }\n else {\n var x0 = mod.canvas.width*.5*(1-w/h)\n var y0 = 0\n var wd = mod.canvas.height*w/h\n var hd = mod.canvas.height\n }\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n ctx.drawImage(mod.img,x0,y0,wd,hd)\n outputs.image.event()\n }\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"78","left":"753","inputs":{},"outputs":{}},"0.921663484124666":{"definition":"//\n// pause event\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2016\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the fab modules \n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'pause event'\n//\n// initialization\n//\nvar init = function() {\n }\n//\n// inputs\n//\nvar inputs = {\n input:{type:'event',\n event:function(evt){\n mod.event.value = evt.detail\n mod.label.nodeValue = 'click to continue'\n mod.labelspan.style.fontWeight = 'bold'\n }}}\n//\n// outputs\n//\nvar outputs = {\n output:{type:'event',\n event:function(){\n mods.output(mod,'output',mod.event.value)\n }}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // pause button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n var span = document.createElement('span')\n var text = document.createTextNode('waiting for event')\n mod.label = text\n span.appendChild(text)\n mod.labelspan = span\n btn.appendChild(span)\n btn.addEventListener('click',function(){\n mod.label.nodeValue = 'waiting for event'\n mod.labelspan.style.fontWeight = 'normal'\n outputs.output.event()\n })\n div.appendChild(btn)\n //\n // event value\n //\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('value: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('change',function(){\n })\n div.appendChild(input)\n mod.event = input\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"768","left":"189","inputs":{},"outputs":{}}},"links":["{\"source\":\"{\\\"id\\\":\\\"0.2535609410541485\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"value\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.9339870295565246\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"start\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.2535609410541485\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"value\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.0011659221974470446\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"var1\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.9339870295565246\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"value\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.0011659221974470446\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"var2\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.24205313692818475\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"output\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.2535609410541485\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"start\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.0011659221974470446\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"output\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.7206492720988903\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"capture\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.9339870295565246\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"end\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.921663484124666\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"input\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.921663484124666\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"output\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.2535609410541485\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"step\\\"}\"}"]}