This commit is contained in:
nrhck 2019-03-17 04:19:57 +01:00
parent c27151ec62
commit 798ac06fd1
14 changed files with 299 additions and 158 deletions

10
LJ.conf
View File

@ -1,13 +1,13 @@
[General]
lasernumber = 1
debug = 1
lasernumber = 2
debug = 0
ljayserverip = 127.0.0.1
nozoscip = 127.0.0.1
bhoroscip = 127.0.0.1
[laser0]
color = -1
ip = 192.168.1.3
ip = 127.0.0.1
kpps = 25000
centerx = -1610
centery = 0
@ -26,7 +26,7 @@ warpdest = [[-1500., 1500.],
[laser1]
color = -1
ip = 127.0.0.1
ip = 192.168.1.3
kpps = 25000
centerx = 506
centery = 413
@ -91,6 +91,6 @@ plugins = {
"simu": {"OSC": 8008, "command": "python plugins/simu.py"},
"bank0": {"OSC": 8010, "command": "python3 plugins/VJing/bank0.py"},
"ljpong": {"OSC": 8020, "command": "python plugins/games/ljpong/main.py"},
"laserwars": {"OSC": 8021, "command": "python plugins/games/ljsw/main.py"}
"ljwars": {"OSC": 8021, "command": "python plugins/games/ljsw/main.py"}
}

View File

@ -82,23 +82,26 @@ import gstt
import homographyp
import settings
import redis
import plugins
r = redis.StrictRedis(host=gstt.LjayServerIP , port=6379, db=0)
GenericCommands = ["start","ljclient","clientnumber","noteon","pong","mouse","emergency","simu","status","run","nozoid","planet","live","words","ai","bank0"]
GenericCommands = ["start","ljclient","clientnumber","noteon","pong","mouse","emergency","simu","status","run","nozoid","planet","live","words","ai","bank0","lj"]
def UserOn(laser):
print "User for laser ", laser
plugins.sendWSall("/status User on laser " + str(laser))
r.set('/order/'+str(laser), 0)
def NewEDH(laser):
print "New EDH requested for laser ", laser
plugins.sendWSall("/status New EDH on laser " + str(laser))
settings.Write()
print "Settings saving swapX ", gstt.swapX[laser]
print "Settings saving swapY ", gstt.swapY[laser]
@ -108,12 +111,14 @@ def NewEDH(laser):
def BlackOn(laser):
print "Black for laser ", laser
plugins.sendWSall("/status Black on laser " + str(laser))
r.set('/order/'+str(laser), 2)
def GridOn(laser):
print "Grid for laser ", laser
plugins.sendWSall("/status Grid on laser " + str(laser))
r.set('/order/'+str(laser), 3)
@ -127,11 +132,12 @@ def Resampler(laser,lsteps):
def LasClientChange(clientnumber):
#
if r.get("/pl/"+str(clientnumber)+"/0") != None:
print "Switching to laser client", clientnumber
gstt.LasClientNumber = clientnumber
plugins.sendWSall("/status Client " + str(gstt.LasClientNumber) + " laser " + str(gstt.Laser))
r.set('/clientkey', "/pl/"+str(clientnumber)+"/")
print "clientkey set to", "/pl/"+str(clientnumber)+"/"
for laserid in xrange(0,gstt.LaserNumber):
@ -152,9 +158,12 @@ def NoteOn(note):
if note > 23 and note < 32:
if note - 24 > gstt.LaserNumber -1:
print "Only",gstt.LaserNumber,"lasers asked, you dum ass !"
plugins.sendWSall("/status Not Enough Laser")
else:
gstt.Laser = note -24
print "Current Laser switched to",gstt.Laser
plugins.sendWSall("/status Client " + str(gstt.LasClientNumber) + " laser " + str(gstt.Laser))
print "Current Laser switched to", gstt.Laser
def Mouse(x1,y1,x2,y2):
print "Mouse", x1,y1,x2,y2
@ -163,8 +172,8 @@ def Mouse(x1,y1,x2,y2):
def handler(oscpath, args):
print ""
print "OSC handler in commands.py got oscpath[1] :",oscpath[1], "with args :",args
#print ""
print "OSC handler in commands.py got /"+ str(oscpath)+ " with args :",args
# 2 incoming cases : generic or specific for a given lasernumber :
# Generic : Commands without a laser number
@ -179,8 +188,9 @@ def handler(oscpath, args):
NoteOn(int(args[0]))
elif oscpath[1] == "pong":
print ""
print "Got pong from ",args
print "LJ commands got pong from", args
plugins.sendWSall("/" + args[0] + "start 1")
plugins.sendWSall("/status got pong from "+ args[0] +".")
elif oscpath[1] == "mouse":
Mouse(int(args[0]),int(args[1]),int(args[2]),int(args[3]))
@ -189,10 +199,12 @@ def handler(oscpath, args):
if oscpath[1] == "emergency":
if args[0] == "1":
print "EMERGENCY MODE"
for laser in range(gstt.lasernumber):
print "Black requested for laser ", laser
BlackOn(laser)
print "EMERGENCY MODE"
plugins.sendWSall("/status EMERGENCY MODE")
else:
for laser in range(gstt.lasernumber):
print "Back to normal for laser ", laser
@ -239,7 +251,7 @@ def handler(oscpath, args):
print "New Angle modification for laser ", oscpath[2], ":", float(args[0])
gstt.finANGLE[laser] += float(args[0])
NewEDH(laser)
"New angle", gstt.finANGLE[laser]
print "New angle", gstt.finANGLE[laser]
# /intens/lasernumber value
if oscpath[1] == "intens":

30
main.py
View File

@ -247,7 +247,7 @@ def handler(path, tags, args, source):
oscpath = path.split("/")
print ""
print "OSC default handler in main said : path", path," oscpath ", oscpath," args", args
print "OSC handler in main said : path", path," oscpath ", oscpath," args", args
#print "debug", gstt.debug
#if gstt.debug >0:
# print "default handler"
@ -367,9 +367,25 @@ def message_received(client, wserver, message):
oscpath = message.split(" ")
print "WS Client", client['id'], "said :", message, "splitted in an oscpath :", oscpath
# Ping all plugins connexion and send message if right plugin is online.
for plugin in gstt.plugins.keys():
if plugins.Send(plugin,oscpath):
print "Plugin", plugin, "processed",oscpath
# Plugin Online
if plugins.Ping(plugin):
sendWSall("/"+ plugin + "/start 1")
if gstt.debug >0:
print "plugin", plugin, "answered."
if oscpath[0].find(plugin) != -1 and plugins.Send(plugin,oscpath):
print "message sent correctly to", plugin
# Plugin Offline
else:
sendWSall("/"+ plugin + "/start 0")
if gstt.debug >0:
print "plugin", plugin, "didn't answered."
'''
if plugins.Send("planet",oscpath):
pass
@ -395,7 +411,6 @@ def message_received(client, wserver, message):
#print oscpath[0].split("/"),oscpath[1]
# current UI has no dedicated off button so /on 0 trigs /off to extosc
if oscpath[0] == "/on":
if oscpath[1] == "1":
sendextosc("/on")
@ -405,6 +420,13 @@ def message_received(client, wserver, message):
if len(oscpath) == 1:
args[0] = "noargs"
#print "noargs command"
elif len(oscpath) > 1:
args[0] = str(oscpath[1])
#print "arg",oscpath[1]
commands.handler(oscpath[0].split("/"),args)

View File

@ -59,14 +59,18 @@ def Start(name):
sendWSall("/status Starting...")
# Get LJ path
ljpath = r'%s' % os.getcwd().replace('\\','/')
print ""
print "Starting plugin :", name
print "LJ path :", ljpath
print "LJ is starting plugin :", name
# Construct the command with absolute path.
PluginPath = command.split(" ")
# Launch as a subprocess
PluginProcess = subprocess.Popen([PluginPath[0], ljpath + "/" + PluginPath[1]])
if gstt.debug >0:
print "LJ path :", ljpath
print "New process pid for ", name, ":", PluginProcess.pid
data = Data(name)
@ -81,11 +85,11 @@ def OSCsend(name, oscaddress, oscargs =''):
PluginPort = Port(name)
sendWSall("/status Checking "+ name + "...")
if gstt.debug >0:
if gstt.debug >1:
print ""
print "Checking plugin ",name, "..."
print "Plugin ", name, "is at", gstt.LjayServerIP, "and has OSC port : " + str(PluginPort)
print "Sending", oscaddress, oscargs,"to plugin ", name
print "OSCSend is checking plugin", name, "..."
print "Plugin", name, "is at", gstt.LjayServerIP, ":" + str(PluginPort)
print "Sending", oscaddress, oscargs,"to plugin", name
osclientplugin = OSCClient()
osclientplugin.connect((gstt.LjayServerIP, PluginPort))
@ -96,15 +100,16 @@ def OSCsend(name, oscaddress, oscargs =''):
try:
osclientplugin.sendto(oscmsg, (gstt.LjayServerIP, PluginPort))
oscmsg.clearData()
if gstt.debug >0:
print oscaddress, oscargs, "was sent to",name
#if gstt.debug >0:
# print oscaddress, oscargs, "was sent to",name
return True
except:
print ""
print 'Connection to plugin IP', gstt.LjayServerIP ,'port', PluginPort,' refused : died ?'
if gstt.debug > 0:
print 'OSCSend : Connection to plugin IP', gstt.LjayServerIP ,':', PluginPort,'refused : died ?'
#sendWSall("/status No plugin.")
sendWSall("/status No plugin.")
sendWSall("/status " + name + " is offline")
sendWSall("/" + name + "/start 0")
#PluginStart(name)
return False
@ -166,8 +171,8 @@ def Send(name,oscpath):
else:
if gstt.debug >0:
print "Plugin " + name + " offline."
print "Command", oscpath
print "Send says plugin " + name + " is offline."
#print "Command", oscpath
sendWSall("/status Plugin " + name + " offline")
sendWSall("/"+ name + "/start 0")

View File

@ -607,9 +607,16 @@ def OSCrun(value):
print("I got /run with value", value)
doit = value
# /quit
def OSCquit():
WebStatus("Bank0 stopping")
print("Stopping OSC...")
lj3.OSCstop()
sys.exit()
def WebStatus(message):
lj3.Send("/status",message)
lj3.SendLJ("/status",message)
#doit = Starfield
@ -629,6 +636,7 @@ osc_udp_server("127.0.0.1", OSCinPort, "InPort")
osc_method("/bank0/run*", OSCrun)
osc_method("/bank0/ping*", lj3.OSCping)
osc_method("/bank0/ljclient", OSCljclient)
osc_method("/quit", OSCquit)
import pygame

View File

@ -69,15 +69,7 @@ def OSCframe():
def OSCstop():
osc_terminate()
# Answer to LJ pings
def OSCping(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /ping with value", value)
Send("/pong",value)
def Send(oscaddress,oscargs=''):
def SendLJ(oscaddress,oscargs=''):
try:
msg = oscbuildparse.OSCMessage(oscaddress, None, [oscargs])
@ -87,6 +79,15 @@ def Send(oscaddress,oscargs=''):
except:
print ('Connection to LJ refused : died ?')
pass
# Answer to LJ pings
def OSCping(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /ping with value", value)
SendLJ("/pong",value)
'''
def handlerfunction(s, x, y):
# Will receive message data unpacked in s, x, y

View File

@ -20,10 +20,10 @@ duration = 300
OSCinPort = 8006
Word0 = "0"
Word1 = "1"
Word2 = "2"
Word3 = "3"
Word0 = "LASER"
Word1 = "LASER"
Word2 = "LASER"
Word3 = "LASER"
'''
is_py2 = sys.version[0] == '2'
@ -32,8 +32,7 @@ if is_py2:
else:
from queue import Queue
'''
print ("")
print ("Arguments parsing if needed...")
print ("Words is checking arguments parsing if needed...")
argsparser = argparse.ArgumentParser(description="Text Cycling for LJ")
argsparser.add_argument("-r","--redisIP",help="IP of the Redis server used by LJ (127.0.0.1 by default) ",type=str)
argsparser.add_argument("-c","--client",help="LJ client number (0 by default)",type=int)
@ -65,55 +64,74 @@ lj3.Config(redisIP,ljclient)
def OSCword0(value):
global Word0
# Will receive message address, and message data flattened in s, x, y
print("I got /words with value", value)
print("Words 0 got /words/text/0 with value", value)
Word0 = value
def OSCword1(value):
global Word1
# Will receive message address, and message data flattened in s, x, y
print("I got /words with value", value)
print("Words 1 got /words/text/1 with value", value)
Word1 = value
def OSCword2(value):
global Word2
# Will receive message address, and message data flattened in s, x, y
print("I got /words with value", value)
print("Words 2 got /words/text/2 with value", value)
Word3 = value
def OSCword3(value):
global Words3
# Will receive message address, and message data flattened in s, x, y
print("I got /words with value", value)
print("Words 3 got /words/text/3 with value", value)
Word3 = value
def OSCljclient(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /words/ljclient with value", value)
print("Words got /words/ljclient with value", value)
ljclient = value
lj3.LjClient(ljclient)
def WebStatus(message):
lj3.Send("/status",message)
# /ping
def OSCping():
lj3.OSCping("words")
lj3.SendLJ("words/text/0",Word0)
lj3.SendLJ("words/text/1",Word1)
# /quit
def OSCquit():
lj3.OSCquit("Words")
def Run():
WebStatus("Load Words")
# OSC Server callbacks
print("Starting OSC at 127.0.0.1 port",OSCinPort,"...")
print("Words starting its OSC server at 127.0.0.1 port",OSCinPort,"...")
osc_startup()
osc_udp_server("127.0.0.1", OSCinPort, "InPort")
osc_method("/words/0*", OSCword0)
osc_method("/words/1*", OSCword1)
osc_method("/words/2*", OSCword2)
osc_method("/words/3*", OSCword3)
osc_method("/ping*", lj3.OSCping)
osc_method("/words/text/0*", OSCword0)
osc_method("/words/text/1*", OSCword1)
osc_method("/words/text/2*", OSCword2)
osc_method("/words/text/3*", OSCword3)
osc_method("/ping*", OSCping)
osc_method("/words/ljclient", OSCljclient)
osc_method("/quit", OSCquit)
color = lj3.rgb2int(255,255,255)
lj3.WebStatus("Loading Words...")
lj3.WebStatus("Words ready.")
lj3.SendLJ("/words/start 1")
WebStatus("Words ready.")
lj3.SendLJ("words/text/0",Word0)
lj3.SendLJ("words/text/1",Word1)
try:
@ -142,8 +160,8 @@ def Run():
finally:
WebStatus("Words Exit")
print("Stopping OSC...")
lj3.WebStatus("Words Exit")
print("Stopping Words OSC...")
lj3.OSCstop()
print ("Words Stopped.")

View File

@ -1,7 +1,9 @@
# coding=UTF-8
'''
LJ v0.8.1 in python3
lj3 v0.8.1
Some LJ functions useful for python clients (was framy.py)
OSC functions commented, waiting working on OSC in python3
@ -11,15 +13,16 @@ PolyLineOneColor
rPolyLineOneColor
Text(word, color, PL, xpos, ypos, resize, rotx, roty, rotz) : Display a word
Send(adress,message) : remote control. See commands.py
SendLJ(adress,message) : LJ remote control. See commands.py
WebStatus(message) : display message on webui
DrawPL(point list number) : once you stacked all wanted elements, like 2 polylines, send them to lasers.
rgb2int(r,g,b)
OSCstart(): Start the OSC system.
OSCframe():
OSCframe(): Handle incoming OSC message. Calling the right callback
OSCstop(): Properly close the OSC system
OSCping(value): Answer to LJ pings
OSCping(value): Answer to LJ pings by sending /pong value
OSCquit(name): Exit calling script using name in terminal
setup_controls(joystick)
@ -72,14 +75,7 @@ def OSCstop():
osc_terminate()
# Answer to LJ pings
def OSCping(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /ping with value", value)
Send("/pong",value)
def Send(oscaddress,oscargs=''):
def SendLJ(oscaddress,oscargs=''):
try:
msg = oscbuildparse.OSCMessage(oscaddress, None, [oscargs])
@ -89,6 +85,26 @@ def Send(oscaddress,oscargs=''):
except:
print ('Connection to LJ refused : died ?')
pass
def WebStatus(message):
SendLJ("/status", message)
# Answer to LJ pings
def OSCping(value):
# Will receive message address, and message data flattened in s, x, y
print("Got /ping with value", value)
SendLJ("/pong",value)
# /quit
def OSCquit(name):
WebStatus(name + " quit.")
print("Stopping OSC...")
OSCstop()
sys.exit()
'''
def handlerfunction(s, x, y):
# Will receive message data unpacked in s, x, y
@ -321,7 +337,6 @@ def ResetPL(self, PL):
pl[PL] = []
def DigitsDots(number,color):
dots =[]
for dot in ASCII_GRAPHICS[number]:
@ -330,6 +345,7 @@ def DigitsDots(number,color):
#self.point_list.append((xy + (c,)))
return dots
def CharDots(char,color):
dots =[]
@ -337,6 +353,7 @@ def CharDots(char,color):
dots.append((dot[0],dot[1],color))
return dots
def Text(message,c, PL, xpos, ypos, resize, rotx, roty, rotz):
dots =[]

View File

@ -54,7 +54,7 @@ def OSCstop():
osc_terminate()
def Send(oscaddress,oscargs=''):
def SendLJ(oscaddress,oscargs=''):
try:
msg = oscbuildparse.OSCMessage(oscaddress, None, [oscargs])
@ -64,6 +64,13 @@ def Send(oscaddress,oscargs=''):
except:
print ('Connection to LJ refused : died ?')
pass
# Answer to LJ pings
def OSCping(value):
# Will receive message address, and message data flattened in s, x, y
print("I got /ping with value", value)
SendLJ("/pong",value)
'''
def handlerfunction(s, x, y):
# Will receive message data unpacked in s, x, y

View File

@ -581,18 +581,20 @@ def NewTime(timeshift):
if DisplayAnything:
UpdateAnything()
# /quit
def OSCquit():
def OSCstart(value):
# Will receive message address, and message data flattened in s, x, y
print("Planetarium OSC server got /planet/start with value", value)
WebStatus("Planet stopping")
print("Stopping OSC...")
lj3.OSCstop()
sys.exit()
def OSCUI(value):
# Will receive message address, and message data flattened in s, x, y
print("Planetarium OSC server got /planet/planetUI with value", value)
def WebStatus(message):
lj3.Send("/status",message)
lj3.SendLJ("/status",message)
#
# Main part
@ -606,8 +608,9 @@ try:
print("Starting OSC at 127.0.0.1 port",OSCinPort,"...")
osc_startup()
osc_udp_server("127.0.0.1", OSCinPort, "InPort")
osc_method("/planet/start*", OSCstart)
osc_method("/planet/planetUI*", OSCUI)
osc_method("/ping*", lj3.OSCping)
osc_method("/quit", OSCquit)
WebStatus("Load Cities.")
ts = load.timescale()
@ -635,7 +638,7 @@ try:
UpdateStars(ts)
WebStatus("Ready")
lj3.Send("/planet/start",1)
lj3.SendLJ("/planet/start",1)
print ("Done.")
# UpdateStars() Todo

View File

@ -1,8 +1,12 @@
# coding=UTF-8
'''
LJ v0.8.1
Cycling text on one LJ laser.
LICENCE : CC
'''
import redis
@ -27,7 +31,7 @@ if is_py2:
else:
from queue import Queue
'''
print ("")
print ("Arguments parsing if needed...")
argsparser = argparse.ArgumentParser(description="Text Cycling for LJ")
argsparser.add_argument("-r","--redisIP",help="IP of the Redis server used by LJ (127.0.0.1 by default) ",type=str)
@ -70,7 +74,7 @@ def rgb2int(r,g,b):
def WebStatus(message):
lj3.Send("/status",message)
lj3.SendLJ("/status",message)
def OSCljclient(value):
# Will receive message address, and message data flattened in s, x, y
@ -79,14 +83,26 @@ def OSCljclient(value):
lj3.LjClient(ljclient)
# /ping
def OSCping():
lj3.OSCping("cycl")
# /quit
def OSCquit():
lj3.OSCquit("Cycl")
osc_startup()
osc_udp_server("127.0.0.1", OSCinPort, "InPort")
osc_method("/ping*", lj3.OSCping)
osc_method("/ping*", OSCping)
osc_method("/quit", OSCquit)
osc_method("/cycl/ljclient", OSCljclient)
WebStatus("Textcycl")
WebStatus("Textcycl Ready")
lj3.SendLJ("/cycl/start 1")
def Run():

View File

@ -82,6 +82,8 @@
x.style.display = "none";
var x = document.getElementById("wordsUI");
x.style.display = "none";
var x = document.getElementById("pluginsUI");
x.style.display = "none";
}
function showplanetUI() {
@ -124,6 +126,13 @@
_WS.send("/words/ping");
}
function showpluginsUI() {
nosimuUI();
var x = document.getElementById("pluginsUI");
x.style.display = "grid";
//_WS.send("/words/ping");
}
//
// Button clicked
//
@ -151,6 +160,9 @@
if (clicked_id === "words/wordsUI") {
showwordsUI();
}
if (clicked_id === "lj/pluginsUI") {
showpluginsUI();
}
if (clicked_id === "nozoid/down 50") {
var x = document.getElementById("nozoid/down 50");
x.value = 0 ;
@ -214,6 +226,7 @@
//console.log(res[0].substring(0,6))
switch (res[0].substring(0,6)) {
case "/statu":
_WS.showstatus(e.data.slice(8));
break;

View File

@ -20,7 +20,7 @@
}
.mgstatus {
display: grid;
grid-template-columns: 390px 150px 1fr;
grid-template-columns: 313px 150px 1fr;
grid-template-raw: 30px;
grid-column-gap: 1px;
grid-row-gap: 1px;

View File

@ -146,7 +146,7 @@
<webaudio-switch id="simu" value="1" height="27" width="75" tooltip="Switch-B" src="knobs/simu.png"></webaudio-switch>
<webaudio-switch id="live" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/live.png"></webaudio-switch>
<webaudio-switch id="run" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/run.png"></webaudio-switch>
<webaudio-switch id="pysimu/start" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/pysimu.png"></webaudio-switch>
<!--
<button class="button" id="showrun" onclick="showRun()">Run</button>
<button class="button" id="shownozoid" onclick="showNozoid()">Nozoid</button>
@ -157,7 +157,7 @@
<div>
<span class="lasertext">Virtual</span>
<select onclick="buttonClicked(this.value) value="0">
<select onclick="buttonClicked(this.value)" id="virtual" value="0">
<option value="noteon 0">0</option>
<option value="noteon 1">1</option>
<option value="noteon 2">2</option>
@ -181,7 +181,8 @@
</select>
-->
<select onclick="buttonClicked(this.value)" value="planet/planetUI">
<select onclick="buttonClicked(this.value)" value="lj/pluginsUI">
<option value="lj/pluginsUI">Plugins</option>
<option value="planet/planetUI">Planetarium</option>
<option value="nozoid/nozoidUI">Nozoid</option>
<option value="bank0/vjUI">VJing</option>
@ -530,7 +531,7 @@
<!-- sub right part : planetarium -->
<div id ="planetUI" style = "display: grid;justify-items: center;">
<div id ="planetUI" style = "display: none;justify-items: center;">
<!-- Stop and start switch -->
<div>
<div><webaudio-switch id="planet/start" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/planet.png"></webaudio-switch>
@ -663,8 +664,28 @@
</div>
<!-- sub right part : pluginsUI -->
<!-- sub right part : vjUI -->
<div id ="pluginsUI" style = "display: grid;justify-items: center;">
<!-- Plugins choice Interface -->
<div>
<webaudio-switch id="pysimu/start" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/pysimu.png"></webaudio-switch>
</div>
<div>
<webaudio-switch id="glyph/start" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/glyph.png"></webaudio-switch>
<webaudio-switch id="cycl/start" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/cycl.png"></webaudio-switch>
</div>
<div>
<webaudio-switch id="ljpong/start" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/ljpong.png"></webaudio-switch>
<webaudio-switch id="ljwars/start" value="0" height="27" width="75" tooltip="Switch-B" src="knobs/ljwars.png"></webaudio-switch>
</div>
</div>
<!-- sub right part : vjUI bank0 -->
<div id ="vjUI" class="cnvbuttons">
@ -707,61 +728,59 @@
</select>
</div>
<form onsubmit="onSubmit(); return false;">
<span class="lasertext">Laser 0 word : </span>
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="words/0">
<span class="lasertext">Color</span>
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="words/text/0" value=" ">
<select onclick="buttonClicked(this.value)">
<option value="words/0 red" selected >Red</option>
<option value="words/0 green">Green</option>
<option value="words/0 blue">Blue</option>
<option value="words/0 white">White</option>
<option value="words/0 yellow">Yellow</option>
<option value="words/0 cyan">Cyan</option>
<option value="words/0 pink">Pink</option>
<option value="words/color/0 red" selected >Red</option>
<option value="words/color/0 green">Green</option>
<option value="words/color/0 blue">Blue</option>
<option value="words/color/0 white">White</option>
<option value="words/color/0 yellow">Yellow</option>
<option value="words/color/0 cyan">Cyan</option>
<option value="words/color/0 pink">Pink</option>
</select>
<span class="lasertext">Laser 0</span>
</form>
<form onsubmit="onSubmit(); return false;">
<span class="lasertext">Laser 1 word : </span>
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="words/1">
<span class="lasertext">Color</span>
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="words/text/1" value=" ">
<select onclick="buttonClicked(this.value)">
<option value="words/1 red" selected >Red</option>
<option value="words/1 green">Green</option>
<option value="words/1 blue">Blue</option>
<option value="words/0 white">White</option>
<option value="words/0 yellow">Yellow</option>
<option value="words/0 cyan">Cyan</option>
<option value="words/0 pink">Pink</option>
<option value="words/color/1 red" selected >Red</option>
<option value="words/color/1 green">Green</option>
<option value="words/color/1 blue">Blue</option>
<option value="words/color/1 white">White</option>
<option value="words/color/1 yellow">Yellow</option>
<option value="words/color/1 cyan">Cyan</option>
<option value="words/color/1 pink">Pink</option>
</select>
<span class="lasertext">Laser 1</span>
</form>
<form onsubmit="onSubmit(); return false;">
<span class="lasertext">Laser 2 word : </span>
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="words/2">
<span class="lasertext">Color</span>
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="words/text/2" value=" ">
<select onclick="buttonClicked(this.value)">
<option value="words/2 red" selected >Red</option>
<option value="words/2 green">Green</option>
<option value="words/2 blue">Blue</option>
<option value="words/0 white">White</option>
<option value="words/0 yellow">Yellow</option>
<option value="words/0 cyan">Cyan</option>
<option value="words/0 pink">Pink</option>
<option value="words/color/2/color red" selected >Red</option>
<option value="words/color/2 green">Green</option>
<option value="words/color/2 blue">Blue</option>
<option value="words/color/2 white">White</option>
<option value="words/color/2 yellow">Yellow</option>
<option value="words/color/2 cyan">Cyan</option>
<option value="words/color/2 pink">Pink</option>
</select>
<span class="lasertext">Laser 2</span>
</form>
<form onsubmit="onSubmit(); return false;">
<span class="lasertext">Laser 3 word : </span>
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="words/3">
<span class="lasertext">Color</span>
<input class = "submit" onchange = "onSubmit(this.id)" type="text" id="words/text/3" value=" ">
<select onclick="buttonClicked(this.value)">
<option value="words/3 red" selected >Red</option>
<option value="words/3 green">Green</option>
<option value="words/3 blue">Blue</option>
<option value="words/0 white">White</option>
<option value="words/0 yellow">Yellow</option>
<option value="words/0 cyan">Cyan</option>
<option value="words/0 pink">Pink</option>
<option value="words/color/3 red" selected >Red</option>
<option value="words/color/3 green">Green</option>
<option value="words/color/3 blue">Blue</option>
<option value="words/color/3 white">White</option>
<option value="words/color/3 yellow">Yellow</option>
<option value="words/color/3 cyan">Cyan</option>
<option value="words/color/3 pink">Pink</option>
</select>
<span class="lasertext">Laser 3</span>
</form>
</div>