summaryrefslogtreecommitdiffstats
path: root/arts/builder
diff options
context:
space:
mode:
Diffstat (limited to 'arts/builder')
-rw-r--r--arts/builder/FullDuplexTest.arts139
-rw-r--r--arts/builder/Makefile.am39
-rw-r--r--arts/builder/TODO69
-rw-r--r--arts/builder/artsbuilder.desktop122
-rw-r--r--arts/builder/artsbuilderui.rc47
-rw-r--r--arts/builder/autorouter.cpp609
-rw-r--r--arts/builder/autorouter.h184
-rw-r--r--arts/builder/createtool.cpp339
-rw-r--r--arts/builder/createtool.h132
-rw-r--r--arts/builder/dirmanager.cpp96
-rw-r--r--arts/builder/dirmanager.h34
-rw-r--r--arts/builder/drawutils.cpp39
-rw-r--r--arts/builder/drawutils.h31
-rw-r--r--arts/builder/execdlg.cpp201
-rw-r--r--arts/builder/execdlg.h54
-rw-r--r--arts/builder/interfacedlg.cpp178
-rw-r--r--arts/builder/interfacedlg.h52
-rw-r--r--arts/builder/main.cpp958
-rw-r--r--arts/builder/main.h118
-rw-r--r--arts/builder/menumaker.cpp212
-rw-r--r--arts/builder/menumaker.h70
-rw-r--r--arts/builder/module.cpp439
-rw-r--r--arts/builder/module.h108
-rw-r--r--arts/builder/mwidget.cpp652
-rw-r--r--arts/builder/mwidget.h129
-rw-r--r--arts/builder/pics/Makefile.am24
-rw-r--r--arts/builder/pics/Synth_ADD.xpm305
-rw-r--r--arts/builder/pics/Synth_AMAN_PLAY.xpm316
-rw-r--r--arts/builder/pics/Synth_ATAN_SATURATE.xpm310
-rw-r--r--arts/builder/pics/Synth_AUTOPANNER.xpm292
-rw-r--r--arts/builder/pics/Synth_BUS_DOWNLINK.xpm323
-rw-r--r--arts/builder/pics/Synth_BUS_UPLINK.xpm323
-rw-r--r--arts/builder/pics/Synth_DEBUG.xpm319
-rw-r--r--arts/builder/pics/Synth_DIV.xpm1350
-rw-r--r--arts/builder/pics/Synth_EMPTY.xpm1119
-rw-r--r--arts/builder/pics/Synth_ENVELOPE_ADSR.xpm318
-rw-r--r--arts/builder/pics/Synth_FILEPLAY.xpm312
-rw-r--r--arts/builder/pics/Synth_MIDI_DEBUG.xpm323
-rw-r--r--arts/builder/pics/Synth_MIDI_ROUTER.xpm323
-rw-r--r--arts/builder/pics/Synth_MOOG_VCF.xpm305
-rw-r--r--arts/builder/pics/Synth_MUL.xpm309
-rw-r--r--arts/builder/pics/Synth_MULTI_ADD.xpm1510
-rw-r--r--arts/builder/pics/Synth_PLAY.xpm316
-rw-r--r--arts/builder/pics/Synth_PLAY_AKAI.xpm317
-rw-r--r--arts/builder/pics/Synth_PLAY_AKAIS.xpm317
-rw-r--r--arts/builder/pics/Synth_PLAY_WAV.xpm317
-rw-r--r--arts/builder/pics/Synth_PSCALE.xpm299
-rw-r--r--arts/builder/pics/Synth_RC.xpm323
-rw-r--r--arts/builder/pics/Synth_SEQUENCE.xpm319
-rw-r--r--arts/builder/pics/Synth_SEQUENCE_FREQ.pngbin0 -> 3545 bytes
-rw-r--r--arts/builder/pics/Synth_SHELVE_CUTOFF.xpm247
-rw-r--r--arts/builder/pics/Synth_WAVE_SAW.xpm323
-rw-r--r--arts/builder/pics/Synth_WAVE_SIN.xpm320
-rw-r--r--arts/builder/pics/Synth_WAVE_SQUARE.xpm323
-rw-r--r--arts/builder/pics/Synth_WAVE_TRI.xpm305
-rw-r--r--arts/builder/pics/Synth_XFADE.xpm313
-rw-r--r--arts/builder/pics/cr16-action-artsbuilderexecute.pngbin0 -> 133 bytes
-rw-r--r--arts/builder/pics/cr22-action-artsbuilderexecute.pngbin0 -> 184 bytes
-rw-r--r--arts/builder/pics/hi16-app-artsbuilder.pngbin0 -> 898 bytes
-rw-r--r--arts/builder/pics/hi16-app-artscontrol.pngbin0 -> 859 bytes
-rw-r--r--arts/builder/pics/hisc-app-artsbuilder.svgzbin0 -> 1971 bytes
-rw-r--r--arts/builder/pics/hisc-app-artscontrol.svgzbin0 -> 4421 bytes
-rw-r--r--arts/builder/portposdlg.cpp258
-rw-r--r--arts/builder/portposdlg.h51
-rw-r--r--arts/builder/propertypanel.cpp404
-rw-r--r--arts/builder/propertypanel.h78
-rw-r--r--arts/builder/propertypanelbase.ui362
-rw-r--r--arts/builder/qttableview.cpp2274
-rw-r--r--arts/builder/qttableview.h251
-rw-r--r--arts/builder/retrievedlg.cpp137
-rw-r--r--arts/builder/retrievedlg.h45
-rw-r--r--arts/builder/scomponent.cpp108
-rw-r--r--arts/builder/scomponent.h87
-rw-r--r--arts/builder/session.cpp80
-rw-r--r--arts/builder/session.h38
-rw-r--r--arts/builder/structure.cpp462
-rw-r--r--arts/builder/structure.h92
-rw-r--r--arts/builder/structureport.cpp287
-rw-r--r--arts/builder/structureport.h66
-rw-r--r--arts/builder/x-artsbuilder.desktop60
80 files changed, 22311 insertions, 0 deletions
diff --git a/arts/builder/FullDuplexTest.arts b/arts/builder/FullDuplexTest.arts
new file mode 100644
index 00000000..bcd6f753
--- /dev/null
+++ b/arts/builder/FullDuplexTest.arts
@@ -0,0 +1,139 @@
+name=FullDuplexTest
+module=Arts::Synth_BUS_DOWNLINK
+{
+ id=0
+ x=3
+ y=0
+ port=busname
+ {
+ id=1
+ string_data=in_soundcard
+ }
+ port=left
+ {
+ id=2
+ connect_to=9
+ }
+ port=right
+ {
+ id=3
+ connect_to=13
+ }
+}
+module=Arts::Synth_BUS_UPLINK
+{
+ id=4
+ x=3
+ y=8
+ port=busname
+ {
+ id=5
+ string_data=out_soundcard
+ }
+ port=left
+ {
+ id=6
+ connect_to=11
+ }
+ port=right
+ {
+ id=7
+ connect_to=15
+ }
+}
+module=Arts::Synth_MUL
+{
+ id=8
+ x=3
+ y=5
+ port=invalue1
+ {
+ id=9
+ connect_to=2
+ }
+ port=invalue2
+ {
+ id=10
+ connect_to=25
+ }
+ port=outvalue
+ {
+ id=11
+ connect_to=6
+ }
+}
+module=Arts::Synth_MUL
+{
+ id=12
+ x=6
+ y=5
+ port=invalue1
+ {
+ id=13
+ connect_to=3
+ }
+ port=invalue2
+ {
+ id=14
+ connect_to=25
+ }
+ port=outvalue
+ {
+ id=15
+ connect_to=7
+ }
+}
+module=Arts::Synth_FREQUENCY
+{
+ id=16
+ x=0
+ y=0
+ port=frequency
+ {
+ id=17
+ audio_data=100.00000
+ }
+ port=pos
+ {
+ id=18
+ connect_to=20
+ }
+}
+module=Arts::Synth_WAVE_SIN
+{
+ id=19
+ x=1
+ y=1
+ port=pos
+ {
+ id=20
+ connect_to=18
+ }
+ port=outvalue
+ {
+ id=21
+ connect_to=23
+ }
+}
+module=Arts::Synth_MUL
+{
+ id=22
+ x=2
+ y=2
+ port=invalue1
+ {
+ id=23
+ connect_to=21
+ }
+ port=invalue2
+ {
+ id=24
+ audio_data=12.00000
+ }
+ port=outvalue
+ {
+ id=25
+ connect_to=10
+ connect_to=14
+ }
+}
diff --git a/arts/builder/Makefile.am b/arts/builder/Makefile.am
new file mode 100644
index 00000000..3f5ce2b3
--- /dev/null
+++ b/arts/builder/Makefile.am
@@ -0,0 +1,39 @@
+SUBDIRS = pics
+# set the include path for X, qt, KDE, mico and the synthesizer class defs
+INCLUDES= -I$(top_srcdir)/arts/runtime -I$(top_builddir)/arts/runtime -I$(kde_includes)/arts $(all_includes)
+
+xdg_apps_DATA = artsbuilder.desktop
+
+kdemime_DATA = x-artsbuilder.desktop
+kdemimedir = $(kde_mimedir)/application
+
+bin_PROGRAMS = artsbuilder
+
+artsbuilder_SOURCES = autorouter.cpp main.cpp propertypanelbase.ui \
+ module.cpp propertypanel.cpp structure.cpp \
+ retrievedlg.cpp createtool.cpp structureport.cpp \
+ drawutils.cpp scomponent.cpp portposdlg.cpp \
+ menumaker.cpp session.cpp dirmanager.cpp mwidget.cpp \
+ execdlg.cpp qttableview.cpp interfacedlg.cpp
+artsbuilder_COMPILE_FIRST = ../runtime/artsbuilder.h
+
+noinst_HEADERS = qttableview.h
+
+METASOURCES = AUTO
+
+artsbuilder_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+
+# the libraries to link against. Be aware of the order. First the libraries,
+# that depend on the following ones.
+artsbuilder_LDADD = $(LIB_KFILE) -lqtmcop $(LIB_X11) $(LIBPTHREAD) $(top_builddir)/arts/runtime/libartsbuilder.la -lsoundserver_idl -lartskde
+
+rcdir = $(kde_datadir)/artsbuilder
+rc_DATA = artsbuilderui.rc
+
+# make messages.po. Move this one to ../po/ and "make merge" in po
+# the -x is for skipping messages already translated in kdelibs
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/artsbuilder.pot
+
+propertypanel.h: propertypanelbase.h
+
diff --git a/arts/builder/TODO b/arts/builder/TODO
new file mode 100644
index 00000000..139f22b2
--- /dev/null
+++ b/arts/builder/TODO
@@ -0,0 +1,69 @@
+Bugs:
+====
+- docked properties can be removed, but not fetched back
+
+Wishlist for the artsbuilder app:
+================================
+- implement File/New and provide templates
+- implement cut/copy/paste
+- implement undo
+- implement some preferences (e.g. zoom scale)
+
+- make application more KDE-like:
+ - icons in menus
+ - keyboard accelerators
+ - application icon(s)
+ - status bar
+ - session management
+ - tooltips and help
+ - kpart?
+
+- avoid crashing when loading a bad .arts file
+ (i.e. file open: wrong structure parameters like x/y pos)
+
+- ability to print a module view
+
+- don't allow execution of a structure with ports (like an instrument) directly
+
+- editing of structures while they are running (*)
+- wysiwyg editing of visual structures (like qt designer/delphi), requires (*)
+
+- provide a property dialog like
+ +----------+--------+
+ | property | value |
+ +----------+--------+
+ | caption | hello |
+ | width | 20 |
+ | height | 100 |
+ | x | 30 |
+ | y | 30 |
+ +----------+--------+
+ this should be very useful in editing objects with lots of properties
+ (widgets)
+
+- make _changed signals visible so you can connect the value_changed of a
+ poti to the frequency of a filter
+
+- make it possible to edit parent property of widgets (i.e. to insert one
+ widget into another)
+
+- add structure property dialog with structure meta information, at least
+ * (class) name
+ * (real world) name with i18n (?)
+ * implemented interfaces
+ * ports (maybe Details >>, tabbed notebook) - like already implemented
+ * author
+ * (category for menues)
+ * copyright
+ * license
+ * whether to publish or not (?)
+ * template (?)
+
+Additions "outside" the app code:
+================================
+- create standalone command line tool to load modules that does not
+ depend on KDE
+
+- write a tutorial in the arts manual
+
+- create more bitmaps/icons for all modules
diff --git a/arts/builder/artsbuilder.desktop b/arts/builder/artsbuilder.desktop
new file mode 100644
index 00000000..9d99c6d7
--- /dev/null
+++ b/arts/builder/artsbuilder.desktop
@@ -0,0 +1,122 @@
+# KDE Config File
+[Desktop Entry]
+Name=aRts Builder
+Name[af]=Arts Builder
+Name[ar]=باني Arts
+Name[bn]=আর্ট্‌স্ বিল্ডার
+Name[br]=arts Builder
+Name[ca]=Constructor aRts
+Name[cs]=Konstruktér aRts
+Name[cy]=Adeiladwr aRts
+Name[da]=aRts-bygger
+Name[de]=aRts-Builder
+Name[eo]=aRts-Sonkreilo
+Name[et]=aRtsi ehitaja
+Name[fa]=سازندۀ aRts
+Name[fi]=aRts-rakentaja
+Name[fr]=aRtsBuilder
+Name[gl]=Construtor aRts
+Name[hi]=एआरटीएस बिल्डर
+Name[hu]=aRts-modellező
+Name[is]=aRts-smiður
+Name[it]=Costruttore per aRts
+Name[ja]=aRts ビルダー
+Name[kk]=aRts құрастырғышы
+Name[km]=កម្មវិធី​បង្កើត aRts
+Name[ko]=aRts 빌더
+Name[lt]=aRts komponuoklis
+Name[lv]=aRts Būvētājs
+Name[mk]=Градител на aRts
+Name[nb]=aRts-bygger
+Name[nds]=aRts-Builder
+Name[ne]=aRts निर्माता
+Name[nn]=aRts-byggjar
+Name[pa]=aRts ਨਿਰਮਾਤਾ
+Name[pl]=Arts Builder
+Name[pt]=Construtor do aRts
+Name[pt_BR]=Construtor Arts
+Name[ru]=artsbuilder
+Name[se]=aRts-huksejeaddji
+Name[sl]=Graditelj aRts
+Name[sr]=Градитељ Rts-а
+Name[sr@Latn]=Graditelj Rts-a
+Name[sv]=Arts-byggare
+Name[ta]=aRts உருவாக்கி
+Name[tg]=Созандаи aRts
+Name[tr]=aRts
+Name[ven]=Mufhati wa aRts
+Name[xh]=Umakhi we aRts
+Name[zh_CN]=aRts 构建程序
+Name[zu]=Umakhi We aRts
+GenericName=Audio Filter Designer
+GenericName[af]=Audio Filter Ontwerper
+GenericName[bg]=Аудио дизайнер
+GenericName[bn]=অডিও ফিল্টার ডিসাইনার
+GenericName[br]=Ergrafer sil klevet
+GenericName[bs]=Dizajner audio filtera
+GenericName[ca]=Dissenyador de filtres àudio
+GenericName[cs]=Návrhář zvukových filtrů
+GenericName[cy]=Dylunydd Hidl Sain
+GenericName[da]=Audiofilter-designer
+GenericName[de]=Audiofilter-Designer
+GenericName[el]=Σχεδιαστής φίλτρων ήχου
+GenericName[eo]=Aŭdfiltrilo-desegnilo
+GenericName[es]=Diseñador de filtros de audio
+GenericName[et]=Audiofiltrite disainer
+GenericName[eu]=Audio iragazki diseinatzailea
+GenericName[fa]=طراح پالایۀ صوتی
+GenericName[fi]=Äänisuodattimien suunnitteluohjelma
+GenericName[fr]=Concepteur de filtre audio
+GenericName[ga]=Dearthóir Scagaire Fuaime
+GenericName[gl]=Deseñador de Filtros de Son
+GenericName[he]=מעצב מסנני שמע
+GenericName[hi]=ध्वनि फ़िल्टर डिजाइनर
+GenericName[hr]=Dizajner audio filtara
+GenericName[hu]=Hangszűrő-tervező
+GenericName[is]=Hljóðsíuhönnuður
+GenericName[it]=Disegnatore di filtro audio
+GenericName[ja]=オーディオフィルタデザイナー
+GenericName[kk]=Аудио сүзгі құрастырғышы
+GenericName[km]=កម្មវិធី​រចនាតម្រង​អូ​ឌីយូ​
+GenericName[ko]=오디오 필터 디자이너
+GenericName[lt]=Audio filtrų kūrimo priemonė
+GenericName[mk]=Изработувач на филтри за звук
+GenericName[ms]=Pereka Penapis Audio
+GenericName[nb]=Lydfilterdesigner
+GenericName[nds]=Klangfilter-Maker
+GenericName[ne]=अडियो फिल्टर डिजाइनर
+GenericName[nl]=Audiofilterontwerper
+GenericName[nn]=Utforming av lydfilter
+GenericName[pa]=ਆਡੀਓ ਫਿਲਟਰ ਡਿਜ਼ਾਈਨਰ
+GenericName[pl]=Projektant filtru audio
+GenericName[pt]=Editor de Filtros de Áudio
+GenericName[pt_BR]=Criador de Filtro de Áudio
+GenericName[ro]=Proiectare filtre audio
+GenericName[ru]=Дизайнер звуковых фильтров
+GenericName[se]=Jietnasilli hápmejeaddji
+GenericName[sk]=Návrh audio filtrov
+GenericName[sl]=Snovalnik avdio filtrov
+GenericName[sr]=Дизајнер аудио филтера
+GenericName[sr@Latn]=Dizajner audio filtera
+GenericName[sv]=Ljudfilterdesigner
+GenericName[ta]=கேட்பொலி வடிகட்டி படைப்பாளர்
+GenericName[tg]=Тарроҳи Полоягари Садо
+GenericName[th]=เครื่องมือออกแบบฟิลเตอร์ของเสียง
+GenericName[tr]=Ses Filtresi Tasarlayıcı
+GenericName[uk]=Дизайн аудіофільтрів
+GenericName[ven]=Muvhati wa filithara ino pfala
+GenericName[xh]=Umyili Wecebo lokucoca ulwelo Wesandi
+GenericName[zh_CN]=音频滤波器设计程序
+GenericName[zh_HK]=音訊過濾器設計師
+GenericName[zh_TW]=音效過濾器設計師
+GenericName[zu]=Umdwebi Wehluzo Lokuzwakalayo
+Exec=artsbuilder -caption "%c"
+Icon=artsbuilder
+Path=
+Type=Application
+Terminal=false
+MimeType=application/x-artsbuilder;
+DocPath=artsbuilder/index.html
+X-DCOP-ServiceType=Multi
+OnlyShowIn=KDE;
+Categories=Qt;KDE;AudioVideo;X-KDE-More;
diff --git a/arts/builder/artsbuilderui.rc b/arts/builder/artsbuilderui.rc
new file mode 100644
index 00000000..807d511f
--- /dev/null
+++ b/arts/builder/artsbuilderui.rc
@@ -0,0 +1,47 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="Artsbuilder" version="3">
+<MenuBar>
+ <Menu name="file"><text>&amp;File</text>
+ <Action name="file_open_example" append="new_merge"/>
+ <Action name="file_execute_structure"/>
+ <Action name="file_rename_structure"/>
+ <!-- currently unused
+ <Action name="file_open_session" append="new_merge"/>
+ <Action name="file_publish_structure"/>
+ <Action name="file_retrieve_from_server"/>
+ -->
+ </Menu>
+ <Menu name="edit"><text>&amp;Edit</text>
+ <Action name="edit_delete"/>
+ </Menu>
+ <Menu name="view"><text>&amp;View</text>
+ <Action name="view_properties"/>
+ <Separator/>
+ <Action name="view_200"/>
+ <Action name="view_150"/>
+ <Action name="view_100"/>
+ <Action name="view_50"/>
+ </Menu>
+ <Action name="modulesmenu"/>
+ <!--
+ <Menu name="modules"><text>&amp;Modules</text>
+ <Action name="modulesmenu"/>
+ <Separator/>
+ </Menu>
+ -->
+ <Menu name="ports"><text>&amp;Ports</text>
+ <Action name="ports_create_in_audio_signal"/>
+ <Action name="ports_create_out_audio_signal"/>
+ <Action name="ports_create_in_string_property"/>
+ <Action name="ports_create_in_audio_property"/>
+ <Separator/>
+ <Action name="ports_implement_interface"/>
+ <Separator/>
+ <Action name="ports_change_positions"/>
+ </Menu>
+</MenuBar>
+<ToolBar name="mainToolBar" ><text>Main Toolbar</text>
+ <Separator />
+ <Action name="file_execute_structure"/>
+</ToolBar>
+</kpartgui>
diff --git a/arts/builder/autorouter.cpp b/arts/builder/autorouter.cpp
new file mode 100644
index 00000000..bc69a7ee
--- /dev/null
+++ b/arts/builder/autorouter.cpp
@@ -0,0 +1,609 @@
+ /*
+
+ Copyright (C) 1998 Stefan Westerfeld <stefan@space.twc.de>,
+ 2002 Hans Meine <hans_meine@gmx.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include "autorouter.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <arts/debug.h>
+
+#include <kdebug.h>
+
+#ifndef HAVE_LIBPTHREAD
+#define pthread_create(a, b, c, d) ;
+#define pthread_join(a, b) ;
+#define pthread_mutex_lock(a) ;
+#define pthread_mutex_unlock(a) ;
+#define pthread_mutex_init(a, b) ;
+#define pthread_attr_init(a) ;
+#endif
+
+using namespace std;
+
+const int COST_INIT = 200000;
+const int PENALTY_OTHERCONNECTION = 100;
+const int PENALTY_CORNER = 100;
+const int IDLE_SLEEP_MILLISECONDS = 40;
+
+void *startroute(void *where)
+{
+ ((AutoRouter *)where)->thread_command_loop();
+ // just to prevent the compiler warning
+ return 0;
+}
+
+bool ARCommand::isDestructive()
+{
+ return false;
+}
+
+AutoRouter::AutoRouter(int width, int height)
+ : width(width), height(height)
+{
+#ifdef HAVE_LIBPTHREAD
+ pthread_attr_t attrs;
+
+ pthread_attr_init(&attrs);
+ pthread_mutex_init(&mutex_sync, 0);
+ pthread_mutex_init(&mutex_queue, 0);
+#endif
+
+ // allocate memory for fields..
+ field = new Field*[width];
+ completeField = new Field*[width];
+
+ for(int i = 0; i < width; i++)
+ {
+ field[i] = new Field[height];
+ completeField[i] = new Field[height];
+ }
+
+ // ..and clear the freshly allocated memory
+ thread_clear();
+ thread_sync();
+
+ newOwner = 1;
+
+ // init those two arrays - they should be constant somehow..
+ directionMask[DIR_DOWN] = ~(left | right);
+ directionMask[DIR_UP] = ~(left | right);
+ directionMask[DIR_LEFT] = ~(up | down);
+ directionMask[DIR_RIGHT] = ~(up | down);
+
+ ownerIndex[DIR_DOWN] = OWNER_UD;
+ ownerIndex[DIR_UP] = OWNER_UD;
+ ownerIndex[DIR_LEFT] = OWNER_LR;
+ ownerIndex[DIR_RIGHT] = OWNER_LR;
+
+ initPseudoRandom();
+
+ thread_terminate_now = false; // not yet
+#ifdef HAVE_LIBPTHREAD
+ // setup thread and run thread_command_loop() in it
+ pthread_create(&route_thread, &attrs, startroute, this);
+#endif
+
+ arts_debug("AR UP...");
+}
+
+void AutoRouter::initPseudoRandom()
+{
+ // init pseudoRandomDir array with random directions
+
+ int remainingDirs[4];
+ for(int i = 0; i < PRSIZE; i++)
+ {
+ if((i & 3) == 0)
+ {
+ int j = 0;
+ for(int dir = DIR_UP; dir <= DIR_RIGHT; dir++)
+ remainingDirs[j++] = dir;
+ }
+
+ int rnd;
+ do rnd = rand()&3;
+ while(remainingDirs[rnd] == DIR_NONE);
+
+ pseudoRandomDir[i] = remainingDirs[rnd];
+
+ remainingDirs[rnd] = DIR_NONE;
+ }
+ nextPR = 0;
+}
+
+AutoRouter::~AutoRouter()
+{
+ // tell the thread to shut down
+ pthread_mutex_lock(&mutex_queue);
+ thread_terminate_now = true;
+ pthread_mutex_unlock(&mutex_queue);
+
+ // terminate thread
+ void *rc;
+ pthread_join(route_thread, &rc);
+
+ // clean up
+ for(int i = 0; i < width; i++)
+ {
+ delete[] field[i];
+ delete[] completeField[i];
+ }
+ delete[] completeField;
+ delete[] field;
+
+ arts_debug("AR DOWN...");
+}
+
+void AutoRouter::enqueue(ARCommand *command)
+{
+#ifdef HAVE_LIBPTHREAD
+ // threaded execution, locking the queue
+ pthread_mutex_lock(&mutex_queue);
+
+ if(command->isDestructive())
+ {
+ // ok, then we can kill the whole list, since this will clear
+ // the whole results anyway
+
+ command_queue.setAutoDelete(true);
+ command_queue.clear();
+ command_queue.setAutoDelete(false);
+ }
+ command_queue.append(command);
+
+ pthread_mutex_unlock(&mutex_queue);
+#else
+ // immediate execution
+ command->execute(this);
+ delete command;
+#endif
+}
+
+void AutoRouter::thread_command_loop()
+{
+ while(1)
+ {
+ ARCommand *command = 0;
+
+ // pop one command from queue if possible..
+ pthread_mutex_lock(&mutex_queue);
+ if(!command_queue.isEmpty())
+ {
+ command = command_queue.first();
+ command_queue.remove(unsigned(0));
+ }
+ else
+ {
+ if (thread_terminate_now) {
+ pthread_mutex_unlock(&mutex_queue);
+ return;
+ }
+ }
+ pthread_mutex_unlock(&mutex_queue);
+
+ // ..and execute command if we got one
+ if(command)
+ {
+ command->execute(this);
+ delete command;
+ }
+ else // no more commands->wait for some milliseconds
+ usleep(1000 * IDLE_SLEEP_MILLISECONDS);
+ // TODO: use pthread_cond_wait here instead of half-busy-waiting?
+ }
+}
+
+// ------------------------- getXXX() handling -------------------------
+
+long AutoRouter::get(int x, int y)
+{
+ assert(x >= 0 && x < width);
+ assert(y >= 0 && y < height);
+
+ pthread_mutex_lock(&mutex_sync);
+ long result = completeField[x][y].data;
+ pthread_mutex_unlock(&mutex_sync);
+
+ return(result);
+}
+
+void AutoRouter::getowners(int x, int y, long& ud_owner, long& lr_owner)
+{
+ assert(x >= 0 && x < width);
+ assert(y >= 0 && y < height);
+
+ pthread_mutex_lock(&mutex_sync);
+ ud_owner = completeField[x][y].owner[OWNER_UD];
+ lr_owner = completeField[x][y].owner[OWNER_LR];
+ pthread_mutex_unlock(&mutex_sync);
+}
+
+// ------------------------- sync() handling -------------------------
+
+void AutoRouter::sync()
+{
+ enqueue(new ARSyncCommand());
+}
+
+void ARSyncCommand::execute(AutoRouter *router)
+{
+ router->thread_sync();
+}
+
+void AutoRouter::thread_sync()
+{
+ int i;
+ pthread_mutex_lock(&mutex_sync);
+
+ for(i = 0; i < width; i++)
+ memcpy(completeField[i], field[i], sizeof(Field)*height);
+ _needRedraw = true;
+
+ pthread_mutex_unlock(&mutex_sync);
+}
+
+bool AutoRouter::needRedraw()
+{
+ bool result;
+
+ pthread_mutex_lock(&mutex_sync);
+ result = _needRedraw;
+ _needRedraw = false;
+#ifdef AR_DEBUG
+ if(result) arts_debug("NEED REDRAW NOW!");
+#endif
+ pthread_mutex_unlock(&mutex_sync);
+
+ return result;
+}
+
+// ------------------------- clear() handling -------------------------
+
+void AutoRouter::clear()
+{
+ enqueue(new ARClearCommand());
+}
+
+bool ARClearCommand::isDestructive()
+{
+ return true;
+}
+
+void ARClearCommand::execute(AutoRouter *router)
+{
+ router->thread_clear();
+}
+
+void AutoRouter::thread_clear()
+{
+ arts_debug("clear()ing now...");
+ int x, y;
+
+ for(x = 0; x < width; x++)
+ for(y = 0; y < height; y++)
+ {
+ field[x][y].data = none;
+ field[x][y].penalty = 0;
+ field[x][y].owner[0] = -1;
+ field[x][y].owner[1] = -1;
+ }
+}
+
+// ------------------------- set() command handling -------------------------
+
+void AutoRouter::set(int x1, int y1, int x2, int y2, long lt)
+{
+ enqueue(new ARSetCommand(x1, y1, x2, y2, lt));
+}
+
+ARSetCommand::ARSetCommand(int x1, int y1, int x2, int y2, long lt)
+ : _x1(x1), _y1(y1), _x2(x2), _y2(y2), _lt(lt)
+{
+}
+
+void ARSetCommand::execute(AutoRouter *router)
+{
+ router->thread_set(_x1, _y1, _x2, _y2, _lt);
+}
+
+void AutoRouter::thread_set(int x1, int y1, int x2, int y2, long lt)
+{
+ for(int x = x1; x <= x2; x++)
+ {
+ for(int y = y1; y <= y2; y++)
+ {
+ assert(x >= 0 && x < width);
+ assert(y >= 0 && y < height);
+
+ if(lt & solid)
+ {
+ if((y - 1) >= 0)
+ field[x][y - 1].penalty += 5;
+
+ if((y - 2) >= 0)
+ field[x][y - 2].penalty += 2;
+
+ if((y + 1) < height)
+ field[x][y + 1].penalty += 5;
+
+ if((y + 2) < height)
+ field[x][y + 2].penalty += 2;
+ }
+
+ field[x][y].data = lt;
+ field[x][y].owner[0] = 0;
+ field[x][y].owner[1] = 0; // don't pass
+ }
+ }
+}
+
+
+long AutoRouter::connect(int x1, int y1, int x2, int y2, long owner)
+{
+ if(owner == 0)
+ owner = newOwner++;
+
+ enqueue(new ARConnectCommand(x1, y1, x2, y2, owner));
+
+ return owner;
+}
+
+ARConnectCommand::ARConnectCommand(int x1, int y1, int x2, int y2, long owner)
+{
+ _x1 = x1; _y1 = y1; _x2 = x2; _y2 = y2; _owner = owner;
+}
+
+void ARConnectCommand::execute(AutoRouter *router)
+{
+ router->thread_connect(_x1, _y1, _x2, _y2, _owner);
+}
+
+void AutoRouter::thread_connect(int x1, int y1, int x2, int y2, long owner)
+{
+ currentOwner = owner;
+
+#ifdef AR_DEBUG
+ arts_debug("-field[x1][y1].owner[0..1] = %ld, %ld",field[x1][y1].owner[0],
+ field[x1][y1].owner[1]);
+ arts_debug("-field[x2][y2].owner[0..1] = %ld, %ld", field[x2][y2].owner[0],
+ field[x2][y2].owner[1]);
+#endif
+
+ // clear data(source) & data(dest) first and restore later, since
+ // they might be solid
+ long sourceFieldData = field[x1][y1].data; field[x1][y1].data = none;
+ long destFieldData = field[x2][y2].data; field[x2][y2].data = none;
+
+ for(int x = 0; x < width; x++)
+ for(int y = 0; y < height; y++)
+ field[x][y].minCost = COST_INIT;
+
+#ifdef AR_DEBUG
+ arts_debug("autorouter: trying to connect %d, %d with %d, %d (owner %ld)",
+ x1, y1, x2, y2, owner);
+#endif
+ nextPR = 0;
+
+ bestGoalPath.cost = COST_INIT;
+
+ int activelist = 0;
+ numQueuedPaths = 0;
+
+ PathInfo path;
+ path.x1 = x1;
+ path.x2 = x2;
+ path.y1 = y1;
+ path.y2 = y2;
+ path.cost = 0;
+ path.depth = 0;
+ queuePath(path);
+
+ while(numQueuedPaths)
+ {
+ while(!pathlist[activelist].size())
+ activelist++;
+ PathQueue& activePathList =
+ pathlist[activelist];
+
+ assert(activePathList.size());
+ examinePath(activePathList.first());
+ activePathList.pop_front();
+ numQueuedPaths--;
+ }
+
+ field[x1][y1].data = sourceFieldData;
+ field[x2][y2].data = destFieldData;
+
+ if(bestGoalPath.cost != COST_INIT)
+ {
+ //arts_debug("bestGoalPath.history for this connection is %s", bestGoalPath.history.data());
+ //arts_debug("minCost for that was %d", gms);
+
+ const char *walk = bestGoalPath.history.ascii();
+
+ int x = x1;
+ int y = y1;
+
+ while(*walk)
+ {
+ field[x][y].owner[ownerIndex[*walk]] = currentOwner;
+ switch(*walk)
+ {
+ case DIR_DOWN:
+ field[x][y++].data |= down;
+ field[x][y].data |= up;
+ break;
+ case DIR_UP:
+ field[x][y--].data |= up;
+ field[x][y].data |= down;
+ break;
+ case DIR_LEFT:
+ field[x--][y].data |= left;
+ field[x][y].data |= right;
+ break;
+ case DIR_RIGHT:
+ field[x++][y].data |= right;
+ field[x][y].data |= left;
+ break;
+ }
+ field[x][y].owner[ownerIndex[*walk]] = currentOwner;
+ walk++;
+ }
+ }
+ else
+ {
+#ifdef AR_DEBUG
+ arts_debug("!! sorry, this connection is impossible !!");
+#endif
+ }
+}
+
+void AutoRouter::queuePath(const PathInfo &path)
+{
+ PathInfo newPath = path;
+
+ int targetlist = newPath.cost/5;
+ if(targetlist > 1023)
+ targetlist = 1023;
+
+ pathlist[targetlist].append(newPath);
+ qHeapSort(pathlist[targetlist]);
+
+ numQueuedPaths++;
+}
+
+void AutoRouter::examinePath(const PathInfo &path)
+{
+ const char *walk = path.history.ascii();
+
+// check if we can go here:
+
+ if(path.x1 < 0 || path.x1 >= width)
+ return;
+ if(path.y1 < 0 || path.y1 >= width)
+ return;
+
+ int currentFieldCost = path.cost;
+
+ if(path.depth > 0)
+ {
+ // going over a field where already connections are is bad
+ if(field[path.x1][path.y1].data != 0)
+ currentFieldCost += PENALTY_OTHERCONNECTION;
+
+ if(directionMask[walk[path.depth - 1]] & field[path.x1][path.y1].data)
+ {
+ // someone already uses that field... we can continue
+ // only if the connection has the same sourceport
+
+ long fieldowner = field[path.x1][path.y1].owner[ownerIndex[walk[path.depth - 1]]];
+
+ if(fieldowner != -1) // used?
+ {
+ if(fieldowner != currentOwner)
+ return;
+
+ // oops, the connections are from the same owner -> no
+ // penalty needed!
+ currentFieldCost -= PENALTY_OTHERCONNECTION;
+ }
+ }
+ }
+
+ // add cityblock distance to costs
+ currentFieldCost += abs(path.x1 - path.x2) + abs(path.y1 - path.y2);
+
+ // add field penalty to costs
+ currentFieldCost += field[path.x1][path.y1].penalty;
+
+ // add corner penalty to costs if path had corner here
+ if(path.depth > 2)
+ if(walk[path.depth - 2] != walk[path.depth - 1])
+ currentFieldCost += PENALTY_CORNER;
+
+ if(currentFieldCost > bestGoalPath.cost)
+ return;
+
+ // better path found?
+ if(currentFieldCost < field[path.x1][path.y1].minCost)
+ {
+ field[path.x1][path.y1].minCost = currentFieldCost;
+
+ // check if we are where we wanted to be:
+ if(path.x1 == path.x2 && path.y1 == path.y2) {
+ // goal! success! :-)
+
+ if(path.cost < bestGoalPath.cost)
+ {
+ bestGoalPath = path; // best solution until now
+ bestGoalPath.cost = currentFieldCost;
+ }
+
+ return;
+ }
+
+ // not at the goal yet, search next place to go; take some
+ // pseudo random direction order (this method improves search
+ // speed)
+
+ PathInfo newPath = path;
+ newPath.depth++;
+ newPath.cost = currentFieldCost;
+
+ for(int i = 0; i < 4; i++)
+ {
+ if(nextPR >= PRSIZE)
+ nextPR = 0;
+
+ switch(pseudoRandomDir[nextPR++])
+ {
+ case DIR_LEFT:
+ newPath.x1--;
+ newPath.history = path.history + (char)DIR_LEFT;
+ queuePath(newPath);
+ newPath.x1++;
+ break;
+
+ case DIR_RIGHT:
+ newPath.x1++;
+ newPath.history = path.history + (char)DIR_RIGHT;
+ queuePath(newPath);
+ newPath.x1--;
+ break;
+
+ case DIR_UP:
+ newPath.y1--;
+ newPath.history = path.history + (char)DIR_UP;
+ queuePath(newPath);
+ newPath.y1++;
+ break;
+
+ case DIR_DOWN:
+ newPath.y1++;
+ newPath.history = path.history + (char)DIR_DOWN;
+ queuePath(newPath);
+ newPath.y1--;
+ break;
+ }
+ }
+ }
+}
diff --git a/arts/builder/autorouter.h b/arts/builder/autorouter.h
new file mode 100644
index 00000000..df3780a0
--- /dev/null
+++ b/arts/builder/autorouter.h
@@ -0,0 +1,184 @@
+/*
+
+ Copyright (C) 1998 Stefan Westerfeld <stefan@space.twc.de>,
+ 2002 Hans Meine <hans_meine@gmx.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __AUTOROUTER_H_
+#define __AUTOROUTER_H_
+
+// If you get into trouble with threading (random crashes), you can configure
+// things with --disable-threading, which should fix everything by not using
+// threads
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_LIBPTHREAD
+#include <pthread.h>
+#endif
+
+#include <qptrlist.h>
+#include <qvaluelist.h>
+
+class PathInfo
+{
+public:
+ int x1, x2, y1, y2, cost, depth;
+ QString history;
+ int operator<(const PathInfo& x) const { return cost < x.cost; }
+ int operator==(const PathInfo& x) const { return cost == x.cost; }
+};
+
+typedef QValueList<PathInfo> PathQueue;
+
+class ARCommand;
+
+/**
+ * The AutoRouter uses threads, commands are passed as objects via
+ * AutoRouter::enqueue() to the routing thread.
+ */
+class AutoRouter
+{
+public:
+ enum { none=0,up=1,down=2,left=4,right=8,head=16,tail=32,solid=64 };
+ enum Direction { DIR_NONE=0, DIR_UP, DIR_DOWN, DIR_LEFT, DIR_RIGHT };
+
+protected:
+ int width, height;
+
+ enum OwnerType { OWNER_UD=0, OWNER_LR=1 };
+ OwnerType ownerIndex[DIR_RIGHT + 1]; // index is of type Direction
+ long directionMask[DIR_RIGHT + 1]; // index is of type Direction
+
+ struct Field
+ {
+ long data;
+ long minCost;
+ long penalty;
+ long owner[2];
+ } **field, **completeField;
+
+ long newOwner; // next free owner ID
+ long currentOwner;
+
+ bool _needRedraw;
+
+ PathInfo bestGoalPath;
+ PathQueue pathlist[1024];
+ int numQueuedPaths;
+
+ // pseudo random table for fast "random" decisions
+ enum { PRSIZE = 16 };
+ long pseudoRandomDir[PRSIZE];
+ int nextPR;
+ void initPseudoRandom();
+
+/****** thread stuff *****/
+#ifdef HAVE_LIBPTHREAD
+ pthread_mutex_t mutex_sync;
+ pthread_mutex_t mutex_queue;
+
+ pthread_t route_thread;
+#endif
+ QPtrList<ARCommand> command_queue;
+
+ bool thread_terminate_now;
+/*************************/
+
+ void queuePath(const PathInfo &path);
+ void examinePath(const PathInfo &path);
+
+public:
+ AutoRouter(int width, int height);
+ ~AutoRouter();
+
+ // queries _needRedraw flag and deletes it
+ // (assuming that the client is smart and redraws when getting true ;)
+ bool needRedraw();
+
+ long get(int x, int y);
+ void getowners(int x, int y, long& ud_owner, long& lr_owner);
+
+ void enqueue(ARCommand *command);
+
+ // marks the entire field as unused
+ void clear();
+ // sets the
+ void set(int x1, int y1, int x2, int y2, long lt);
+ long connect(int x1, int y1, int x2, int y2, long owner);
+ //
+ void sync();
+
+ // the following functions are not for direct use; they're used
+ // for threading only
+ void thread_clear();
+ void thread_set(int x1, int y1, int x2, int y2, long lt);
+ void thread_connect(int x1, int y1, int x2, int y2, long owner);
+ void thread_sync();
+
+ void thread_command_loop();
+};
+
+/**
+ * The ARCommand classes are used to communicate with the routing
+ * thread, see AutoRouter::enqueue()
+ */
+class ARCommand
+{
+public:
+ virtual void execute(AutoRouter *autorouter) = 0;
+ // if a command is destructive (default: false), the command queue
+ // will be emptied before queuing this one, assuming it'll destroy
+ // results of all other commands anyway.
+ virtual bool isDestructive();
+};
+
+class ARClearCommand :public ARCommand
+{
+public:
+ void execute(AutoRouter *autorouter);
+ bool isDestructive();
+};
+
+class ARSyncCommand :public ARCommand
+{
+public:
+ void execute(AutoRouter *autorouter);
+};
+
+class ARConnectCommand :public ARCommand
+{
+ int _x1, _y1, _x2, _y2;
+ long _owner;
+public:
+ ARConnectCommand(int x1, int y1, int x2, int y2, long owner);
+ void execute(AutoRouter *autorouter);
+};
+
+class ARSetCommand :public ARCommand
+{
+private:
+ int _x1, _y1, _x2, _y2;
+ long _lt;
+public:
+ ARSetCommand(int x1, int y1, int x2, int y2, long lt);
+ void execute(AutoRouter *autorouter);
+};
+
+#endif
diff --git a/arts/builder/createtool.cpp b/arts/builder/createtool.cpp
new file mode 100644
index 00000000..a96edc6d
--- /dev/null
+++ b/arts/builder/createtool.cpp
@@ -0,0 +1,339 @@
+ /*
+
+ Copyright (C) 1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include "createtool.h"
+
+#include "mwidget.h"
+#include "structureport.h"
+
+//#include <arts/debug.h>
+#include <qpalette.h>
+#include <qpainter.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+
+MWidgetTool::MWidgetTool(ModuleWidget *mwidget)
+{
+ this->mwidget = mwidget;
+}
+
+MWidgetTool::~MWidgetTool()
+{
+}
+
+CreateTool::CreateTool(ModuleWidget *mwidget)
+ : MWidgetTool(mwidget)
+{
+ oldCursor = mwidget->cursor();
+ mwidget->setCursor(Qt::crossCursor);
+
+ oldMouseTracking = mwidget->hasMouseTracking();
+ mwidget->setMouseTracking(true);
+
+ width = -1;
+ height = -1;
+ componentRect = QRect(0, 0, 0, 0);
+}
+
+CreateTool::~CreateTool()
+{
+ mwidget->repaint(componentRect);
+ mwidget->setCursor(oldCursor);
+ mwidget->setMouseTracking(oldMouseTracking);
+}
+
+void CreateTool::mousePressEvent(QMouseEvent *e)
+{
+ int x = mwidget->findCol(e->x());
+ int y = mwidget->findRow(e->y());
+
+ if(x < 0 || y < 0) return;
+
+ if( e->button() == Qt::LeftButton )
+ performCreate(x, y);
+
+ // well, perhaps make this an option
+ mwidget->leaveTool(this);
+}
+
+void CreateTool::mouseMoveEvent(QMouseEvent *e)
+{
+ if(width == -1) estimateSize();
+
+ int x = mwidget->findCol(e->x());
+ int y = mwidget->findRow(e->y());
+
+ if(x < 0 || y < 0) return;
+
+ int cellx, celly, cellx2, celly2;
+
+ bool posok = mwidget->colXPos(x, &cellx) && mwidget->rowYPos(y, &celly)
+ && mwidget->colXPos(x + width, &cellx2) && mwidget->rowYPos(y + height, &celly2);
+ if(!posok) return;
+
+ mwidget->repaint(componentRect);
+ componentRect = QRect(cellx, celly, cellx2 - cellx, celly2 - celly);
+
+ QPainter *p = new QPainter;
+
+ p->begin(mwidget);
+ p->save();
+ p->drawRect(componentRect);
+ p->restore();
+ p->end();
+ delete p;
+}
+
+void CreateTool::mouseReleaseEvent(QMouseEvent *e)
+{
+}
+
+// module creation
+
+void CreateModuleTool::estimateSize()
+{
+// yes, this is a it ugly: we create here the new module for a microsecond,
+// just to see how big it is, to be able to paint an accurate preview
+//
+// We delete it again, and if the user finally really creates the module
+// we recreate it.
+
+ mwidget->unselectAll();
+
+ Module *newModule = mwidget->theStructure()->createModule(minfo);
+ width = newModule->width();
+ height = newModule->height();
+ newModule->setSelected(true);
+
+ mwidget->theStructure()->deleteSelected();
+}
+
+void CreateModuleTool::performCreate(int x, int y)
+{
+ mwidget->unselectAll();
+ Module *newModule = mwidget->theStructure()->createModule(minfo);
+ newModule->setSelected(true);
+ newModule->move(x, y);
+
+ if(!mwidget->insertModule(newModule))
+ mwidget->theStructure()->deleteSelected();
+}
+
+CreateModuleTool::CreateModuleTool(ModuleWidget *mwidget,
+ const Arts::ModuleInfo& minfo) : CreateTool(mwidget)
+{
+ this->minfo = minfo;
+}
+
+CreateModuleTool::~CreateModuleTool()
+{
+}
+
+// interface creation
+
+void CreateInterfaceTool::estimateSize()
+{
+ vector<Arts::PortType>::iterator pi;
+
+ int input_width = 0;
+ int output_width = 0;
+
+ for(pi = minfo.ports.begin(); pi != minfo.ports.end(); ++pi)
+ {
+ if(pi->direction == Arts::input)
+ input_width++;
+
+ if(pi->direction == Arts::output)
+ output_width++;
+ }
+ width = max(input_width, output_width);
+ height = 5;
+}
+
+void CreateInterfaceTool::performCreate(int x, int y)
+{
+ vector<std::string>::iterator pni;
+ vector<Arts::PortType>::iterator pi;
+
+ mwidget->theStructure()->addInheritedInterface(minfo.name.c_str());
+
+ int input_width = 0;
+ int output_width = 0;
+
+ for(pi = minfo.ports.begin(), pni = minfo.portnames.begin();
+ pi != minfo.ports.end(); ++pi, pni++)
+ {
+ StructurePort *port = 0;
+ /*
+ * watch out: input ports (as in ports that accept data) are on the lower
+ * side of the structure, as the data flows out trough them ;)
+ */
+ if(pi->direction == Arts::input)
+ {
+ port = mwidget->insertPort(*pi, x + input_width, y + 4);
+ input_width++;
+ }
+ else if(pi->direction == Arts::output)
+ {
+ port = mwidget->insertPort(*pi, x + output_width, y);
+ output_width++;
+ }
+
+ assert(port);
+ port->rename(pni->c_str());
+ port->inheritedInterface(minfo.name.c_str());
+ }
+}
+
+CreateInterfaceTool::CreateInterfaceTool(ModuleWidget *mwidget,
+ const Arts::ModuleInfo& minfo) : CreateTool(mwidget)
+{
+ this->minfo = minfo;
+
+ vector<Arts::PortType>::iterator pi;
+ for(pi = this->minfo.ports.begin(); pi != this->minfo.ports.end(); ++pi)
+ {
+ /* reverse since we're inside the interface, not outside */
+ if(pi->direction == Arts::input)
+ pi->direction = Arts::output;
+ else if(pi->direction == Arts::output)
+ pi->direction = Arts::input;
+ }
+}
+
+CreateInterfaceTool::~CreateInterfaceTool()
+{
+}
+
+// port creation
+
+void CreatePortTool::estimateSize()
+{
+ width = height = 1;
+}
+
+void CreatePortTool::performCreate(int x, int y)
+{
+ mwidget->insertPort(type, x, y);
+}
+
+CreatePortTool::CreatePortTool(ModuleWidget *mwidget,
+ const Arts::PortType& type) : CreateTool(mwidget)
+{
+ this->type = type;
+}
+
+MoveComponentsTool::MoveComponentsTool(ModuleWidget *widget, QMouseEvent *e)
+ : MWidgetTool(widget),
+ lastPos(e->pos())
+{
+}
+
+void MoveComponentsTool::mousePressEvent(QMouseEvent *e)
+{
+}
+
+void MoveComponentsTool::mouseMoveEvent(QMouseEvent *e)
+{
+ int dx = (e->x() - lastPos.x())/mwidget->cellsize;
+ int dy = (e->y() - lastPos.y())/mwidget->cellsize;
+
+ if(dx == 0 && dy == 0)
+ return;
+
+ std::list<StructureComponent *>::iterator i;
+ std::list<StructureComponent *> *ComponentList = mwidget->structure->getComponentList();
+
+ for(i = ComponentList->begin();i != ComponentList->end();++i)
+ {
+ StructureComponent *c = *i;
+ if(c->selected() && !mwidget->hasSpace(c, c->x() + dx, c->y() + dy, true))
+ return;
+ }
+
+ mwidget->beginUpdate();
+ for(i = ComponentList->begin();i != ComponentList->end();++i)
+ {
+ StructureComponent *c = *i;
+ if(c->selected())
+ c->move(c->x() + dx, c->y() + dy);
+ }
+ mwidget->endUpdate();
+
+ lastPos.setX(lastPos.x() + dx*mwidget->cellsize);
+ lastPos.setY(lastPos.y() + dy*mwidget->cellsize);
+ mwidget->reRoute();
+}
+
+void MoveComponentsTool::mouseReleaseEvent(QMouseEvent *e)
+{
+ mwidget->leaveTool(this, true);
+}
+
+ConnectPortsTool::ConnectPortsTool(ModuleWidget *widget, ModulePort *connectingPort)
+ : MWidgetTool(widget),
+ connectingPort(connectingPort)
+{
+ firstPos = mwidget->portPos(connectingPort) + connectingPort->clickrect.center();
+}
+
+void ConnectPortsTool::mousePressEvent(QMouseEvent *e)
+{
+}
+
+void ConnectPortsTool::mouseMoveEvent(QMouseEvent *e)
+{
+ QPainter painter(mwidget);
+ painter.setPen(Qt::white);
+ mwidget->repaint(QRect(firstPos, lastPos).normalize());
+ painter.drawLine(firstPos, e->pos());
+ lastPos = e->pos();
+}
+
+void ConnectPortsTool::mouseReleaseEvent(QMouseEvent *e)
+{
+ StructureComponent *component;
+ ModulePort *otherPort;
+ mwidget->findAt(e->x(), e->y(), component, otherPort);
+ if(otherPort && (otherPort!= connectingPort))
+ {
+ // user is trying to close a connection
+ if(connectingPort->direction == otherPort->direction)
+ {
+ KMessageBox::sorry(mwidget,
+ i18n("You can only connect an IN-port with an OUT-port,\n"
+ "not two ports with the same direction."));
+ }
+ else
+ {
+ if(connectingPort->direction == ModulePort::in)
+ {
+ if(otherPort->PortDesc.connectTo(connectingPort->PortDesc))
+ mwidget->reRoute();
+ } else {
+ if(connectingPort->PortDesc.connectTo(otherPort->PortDesc))
+ mwidget->reRoute();
+ }
+ }
+ }
+ mwidget->repaint(QRect(firstPos, lastPos).normalize());
+ mwidget->leaveTool(this);
+}
diff --git a/arts/builder/createtool.h b/arts/builder/createtool.h
new file mode 100644
index 00000000..3796e018
--- /dev/null
+++ b/arts/builder/createtool.h
@@ -0,0 +1,132 @@
+ /*
+
+ Copyright (C) 1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef _CREATETOOL_H
+#define _CREATETOOL_H
+
+#include <qwidget.h>
+#include <qcursor.h>
+
+#include "structure.h"
+#include "module.h"
+#include "scomponent.h"
+
+class ModulePort;
+class ModuleWidget;
+
+class MWidgetTool
+{
+protected:
+ ModuleWidget *mwidget;
+
+public:
+ MWidgetTool(ModuleWidget *mwidget);
+ virtual ~MWidgetTool();
+
+ virtual void mousePressEvent(QMouseEvent *e) = 0;
+ virtual void mouseMoveEvent(QMouseEvent *e) = 0;
+ virtual void mouseReleaseEvent(QMouseEvent *e) = 0;
+};
+
+class CreateTool: public MWidgetTool
+{
+protected:
+ QCursor oldCursor;
+ bool oldMouseTracking;
+ QRect componentRect;
+ int width, height;
+
+public:
+ CreateTool(ModuleWidget *mwidget);
+ virtual ~CreateTool();
+
+ virtual void estimateSize() = 0;
+ virtual void performCreate(int x, int y) = 0;
+
+ void mousePressEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+};
+
+class CreateModuleTool: public CreateTool
+{
+protected:
+ Arts::ModuleInfo minfo;
+
+public:
+ CreateModuleTool(ModuleWidget *mwidget, const Arts::ModuleInfo& minfo);
+ ~CreateModuleTool();
+
+ void estimateSize();
+ void performCreate(int x, int y);
+};
+
+class CreateInterfaceTool: public CreateTool
+{
+protected:
+ Arts::ModuleInfo minfo;
+
+public:
+ CreateInterfaceTool(ModuleWidget *mwidget, const Arts::ModuleInfo& minfo);
+ ~CreateInterfaceTool();
+
+ void estimateSize();
+ void performCreate(int x, int y);
+};
+
+class CreatePortTool: public CreateTool
+{
+protected:
+ Arts::PortType type;
+
+public:
+ CreatePortTool(ModuleWidget *widget, const Arts::PortType& type);
+
+ void estimateSize();
+ void performCreate(int x, int y);
+};
+
+class MoveComponentsTool: public MWidgetTool
+{
+ QPoint lastPos;
+
+public:
+ MoveComponentsTool(ModuleWidget *widget, QMouseEvent *e);
+
+ void mousePressEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+};
+
+class ConnectPortsTool: public MWidgetTool
+{
+ ModulePort *connectingPort;
+ QPoint firstPos, lastPos;
+
+public:
+ ConnectPortsTool(ModuleWidget *widget, ModulePort *connectingPort);
+
+ void mousePressEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+};
+
+#endif
diff --git a/arts/builder/dirmanager.cpp b/arts/builder/dirmanager.cpp
new file mode 100644
index 00000000..80a2e0ff
--- /dev/null
+++ b/arts/builder/dirmanager.cpp
@@ -0,0 +1,96 @@
+ /*
+
+ Copyright (C) 1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <qfile.h>
+
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+#include <kapplication.h>
+#include <klocale.h>
+
+#include "dirmanager.h"
+
+using namespace std;
+
+const char *DirManager::mapDir()
+{
+ static char *d = 0;
+
+ if(!d) d = directory("/maps",i18n("instrument map files"));
+ return d;
+}
+
+const char *DirManager::sessionDir()
+{
+ static char *d = 0;
+
+ if(!d) d = directory("/sessions",
+ i18n("sessions (save files of the positions of all sliders/buttons)"));
+
+ return d;
+}
+
+const char *DirManager::structureDir()
+{
+ static char *d = 0;
+
+ if(!d) d = directory("/structures",i18n("structures (signal flow graphs)"));
+ return d;
+}
+
+const char *DirManager::baseDir()
+{
+ static char *d = 0;
+
+ if(!d) d = directory("",i18n("all aRts files/folders"));
+ return d;
+}
+
+char *DirManager::directory(const char *subdir, const QString &desc)
+{
+ const char *home = getenv("HOME");
+
+ if(home == 0) return strdup("");
+
+ QCString dirname = QCString(home) + "/arts" + subdir;
+
+ struct stat buf;
+ if(stat(dirname.data(), &buf) == -1)
+ {
+ QString message;
+ QString dir = QFile::decodeName(dirname);
+ message = i18n("You need the folder %1.\n"
+ "It will be used to store %2.\nShould I create it now?")
+ .arg(dir).arg(desc);
+
+ if(KMessageBox::questionYesNo(0,message,i18n("aRts Folder Missing"),i18n("Create Folder"),i18n("Do Not Create"))
+ == KMessageBox::Yes)
+ {
+ KStandardDirs::makeDir(dir);
+ }
+ }
+
+ return strdup(dirname.data());
+}
diff --git a/arts/builder/dirmanager.h b/arts/builder/dirmanager.h
new file mode 100644
index 00000000..6ae070de
--- /dev/null
+++ b/arts/builder/dirmanager.h
@@ -0,0 +1,34 @@
+ /*
+
+ Copyright (C) 1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef _DIRMANAGER_H_
+#define _DIRMANAGER_H_
+
+class DirManager {
+protected:
+ static char *directory(const char *subdir, const QString& desc);
+public:
+ static const char *mapDir();
+ static const char *sessionDir();
+ static const char *structureDir();
+ static const char *baseDir();
+};
+#endif
diff --git a/arts/builder/drawutils.cpp b/arts/builder/drawutils.cpp
new file mode 100644
index 00000000..144a8016
--- /dev/null
+++ b/arts/builder/drawutils.cpp
@@ -0,0 +1,39 @@
+ /*
+
+ Copyright (C) 1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include "drawutils.h"
+
+QString DrawUtils::cropText(QPainter *p, QString text, int maxlen, int& textwidth)
+{
+ QString label = text;
+
+ while(p->fontMetrics().width(label) > maxlen && label.length() > 0) {
+ int i = label.find('_');
+
+ if(i != -1)
+ label = label.mid(i+1);
+ else
+ label = label.left(label.length() - 1);
+ }
+
+ textwidth = p->fontMetrics().width(label);
+ return label;
+}
diff --git a/arts/builder/drawutils.h b/arts/builder/drawutils.h
new file mode 100644
index 00000000..3b1a6282
--- /dev/null
+++ b/arts/builder/drawutils.h
@@ -0,0 +1,31 @@
+ /*
+
+ Copyright (C) 1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __DRAWUTILS_H__
+#define __DRAWUTILS_H__
+
+#include <qpainter.h>
+
+class DrawUtils {
+public:
+ static QString cropText(QPainter *p, QString text, int maxlen, int& textwidth);
+};
+#endif
diff --git a/arts/builder/execdlg.cpp b/arts/builder/execdlg.cpp
new file mode 100644
index 00000000..2186d1f5
--- /dev/null
+++ b/arts/builder/execdlg.cpp
@@ -0,0 +1,201 @@
+ /*
+
+ Copyright (C) 1998 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include <qfile.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qlineedit.h>
+
+#include <kbuttonbox.h>
+#include <kfiledialog.h>
+#include <kseparator.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kstdguiitem.h>
+
+#include <unistd.h>
+#include "execdlg.h"
+#include "dirmanager.h"
+#include <arts/debug.h>
+#include <qpushbutton.h>
+
+#ifndef KDE_USE_FINAL
+static void min_size(QWidget *w) {
+ w->setMinimumSize(w->sizeHint());
+}
+#endif
+
+ExecDlg::ExecDlg(QWidget *parent, ExecutableStructure *structure)
+ :QDialog(parent,"X")
+/*, TRUE)*/
+{
+ this->structure = structure;
+
+ setCaption(i18n("aRts Module Execution"));
+
+ mainlayout = new QVBoxLayout(this);
+
+// caption label: "Synthesis running..."
+
+ mainlayout->addSpacing(5);
+ QLabel *captionlabel = new QLabel(this);
+ QFont labelfont(captionlabel->font());
+ labelfont.setPointSize(labelfont.pointSize()*3/2);
+ captionlabel->setFont(labelfont);
+ captionlabel->setText(QString(" ")+i18n("Synthesis running...")+QString(" "));
+ captionlabel->setAlignment(AlignCenter);
+ min_size(captionlabel);
+ mainlayout->addWidget(captionlabel);
+
+ cpuusagelabel = new QLabel(this);
+ cpuusagelabel->setText(i18n("CPU usage: unknown"));
+
+ cpuusagetimer = new QTimer( this );
+ connect( cpuusagetimer, SIGNAL(timeout()),
+ this, SLOT(updateCpuUsage()) );
+ connect( cpuusagetimer, SIGNAL(timeout()),
+ this, SLOT(guiServerTick()) );
+ cpuusagetimer->start( 2000, false );
+
+ min_size(cpuusagelabel);
+ mainlayout->addWidget(cpuusagelabel);
+
+// ruler above the sliderlayout
+
+ mainlayout->addSpacing(5);
+ KSeparator* sep = new KSeparator( KSeparator::HLine, this);
+ mainlayout->addWidget(sep);
+ mainlayout->addSpacing(5);
+
+// sliders, controlpanels
+
+ sliderlayout = new QVBoxLayout;
+ mainlayout->addLayout(sliderlayout);
+
+#if 0 /* PORT */
+ this->GUIServer = GUIServer;
+ GUIServer->setGlobalParent(this);
+ GUIServer->setGlobalLayout(sliderlayout);
+#endif
+
+// hruler below the sliderlayout
+
+ mainlayout->addSpacing(5);
+ sep = new KSeparator( KSeparator::HLine, this);
+ mainlayout->addWidget(sep);
+ mainlayout->addSpacing(5);
+
+// buttons
+
+ QHBoxLayout *buttonlayout = new QHBoxLayout;
+ mainlayout->addSpacing(5);
+ mainlayout->addLayout(buttonlayout);
+ mainlayout->addSpacing(5);
+
+ buttonlayout->addSpacing(5);
+ KButtonBox *bbox = new KButtonBox(this);
+
+ bbox->addButton(KStdGuiItem::help(), this, SLOT( help() ));
+
+ bbox->addStretch(1);
+
+ QButton *savebutton = bbox->addButton(KStdGuiItem::saveAs());
+ connect( savebutton, SIGNAL( clicked() ), SLOT(saveSession() ) );
+
+ QButton *okbutton = bbox->addButton(KStdGuiItem::ok());
+ connect( okbutton, SIGNAL( clicked() ), SLOT(accept() ) );
+
+ bbox->layout();
+ //min_size(bbox);
+
+ buttonlayout->addWidget(bbox);
+ buttonlayout->addSpacing(5);
+
+// mainlayout->freeze();
+}
+
+void ExecDlg::start()
+{
+ mainlayout->freeze();
+}
+
+void ExecDlg::guiServerTick()
+{
+#if 0 /* TODO:PORT */
+ GUIServer->tick();
+#endif
+}
+
+void ExecDlg::updateCpuUsage()
+{
+#if 0 /* TODO:PORT */
+ char cpuusage[100];
+
+ ArtsCorba::Status s = Synthesizer->getStatus();
+ if(s.halted)
+ {
+ cpuusagetimer->stop();
+ accept();
+ PortableKDE::KMsgSorry(this,i18n("Your synthesis has been interrupted due to excessive CPU load."));
+ /*
+ KMsgBox::message(this,i18n("Error"),
+ i18n("Your synthesis has been interrupted due to excessive CPU load."),
+ KMsgBox::STOP);
+ */
+ // warning: this is invalid after accept();
+ return;
+ }
+ sprintf(cpuusage,"%s%3.2f%%",
+ (const char *)i18n("CPU usage: "),s.cpu_usage*100);
+
+ cpuusagelabel->setText(cpuusage);
+
+ if(!structure->isExecuting()) accept();
+ // warning: this is invalid after accept();
+#endif
+}
+
+void ExecDlg::done( int r )
+{
+ structure->stopExecute();
+ QDialog::done(r);
+ emit ready();
+}
+
+void ExecDlg::saveSession()
+{
+ chdir(DirManager::sessionDir());
+
+ QString filename = KFileDialog::getSaveFileName(0,"*.arts-session",this);
+ if(!filename.isEmpty())
+ {
+ arts_debug("save... %s",filename.local8Bit().data());
+ structure->saveSession(QFile::encodeName(filename));
+ }
+}
+
+void ExecDlg::help()
+{
+ KApplication::kApplication()->invokeHelp("", "karts");
+}
+#include "execdlg.moc"
diff --git a/arts/builder/execdlg.h b/arts/builder/execdlg.h
new file mode 100644
index 00000000..47db3562
--- /dev/null
+++ b/arts/builder/execdlg.h
@@ -0,0 +1,54 @@
+ /*
+
+ Copyright (C) 1998 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __EXECDLG_H_
+#define __EXECDLG_H_
+
+#include "structure.h"
+#include <qdialog.h>
+#include <qtimer.h>
+#include <qlabel.h>
+#include <qscrollbar.h>
+#include <qlayout.h>
+
+class ExecDlg :public QDialog {
+ Q_OBJECT
+public:
+ QTimer *cpuusagetimer;
+ QLabel *cpuusagelabel;
+ QVBoxLayout *mainlayout,*sliderlayout;
+ ExecutableStructure *structure;
+
+ void start();
+ void done(int r);
+ ExecDlg(QWidget *parent, ExecutableStructure *structure);
+
+protected slots:
+ void updateCpuUsage();
+ void guiServerTick();
+ void saveSession();
+ void help();
+
+signals:
+ void ready();
+};
+
+#endif
diff --git a/arts/builder/interfacedlg.cpp b/arts/builder/interfacedlg.cpp
new file mode 100644
index 00000000..b0cc5970
--- /dev/null
+++ b/arts/builder/interfacedlg.cpp
@@ -0,0 +1,178 @@
+ /*
+
+ Copyright (C) 1998-2001 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include "interfacedlg.h"
+#include "structureport.h"
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qlistbox.h>
+#include <kbuttonbox.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <kseparator.h>
+#include <klocale.h>
+#include <qlineedit.h>
+#include <stdio.h>
+#include <arts/debug.h>
+#include <arts/core.h>
+#include <arts/dispatcher.h>
+#include <qpushbutton.h>
+#include <kstdguiitem.h>
+
+using namespace std;
+
+InterfaceDlg::InterfaceDlg(QWidget *parent) :QDialog(parent,"Props", TRUE)
+{
+ setCaption(i18n("aRts: Structureport View"));
+
+ QVBoxLayout *mainlayout = new QVBoxLayout(this);
+ //QHBoxLayout *contentslayout = new QHBoxLayout;
+
+// object type
+/*
+ mainlayout->addSpacing(5);
+ QLabel *objectlabel = new QLabel(this);
+ QFont labelfont(objectlabel->font());
+ labelfont.setPointSize(labelfont.pointSize()*3/2);
+ objectlabel->setFont(labelfont);
+ objectlabel->setText(QString(" ")+i18n("Object type: ")+QString(port->owner->name())+QString(" "));
+ objectlabel->setAlignment(AlignCenter);
+ min_size(objectlabel);
+ mainlayout->addWidget(objectlabel);
+*/
+
+// port description
+
+/*
+ mainlayout->addSpacing(5);
+ QLabel *portlabel = new QLabel(this);
+ labelfont.setPointSize(labelfont.pointSize()*4/5);
+ portlabel->setFont(labelfont);
+ portlabel->setText(i18n("Port description: ")+ port->description);
+ min_size(portlabel);
+ portlabel->setAlignment(AlignCenter);
+ mainlayout->addWidget(portlabel);
+
+ int labelwidth = imax(portlabel->sizeHint().width(),objectlabel->sizeHint().width());
+
+ portlabel->setMinimumWidth(labelwidth);
+ objectlabel->setMinimumWidth(labelwidth);
+
+// hruler
+
+ mainlayout->addSpacing(5);
+ KSeparator *ruler = new KSeparator( KSeparator::HLine, this);
+ mainlayout->addWidget(ruler);
+ mainlayout->addSpacing(5);
+ mainlayout->addLayout(contentslayout);
+*/
+// list
+
+ listbox = new QListBox(this);
+
+ update();
+
+ listbox->setMinimumSize(340,400);
+ mainlayout->addWidget(listbox);
+ connect( listbox, SIGNAL( doubleClicked ( QListBoxItem *)), this,
+ SLOT(accept()));
+// hruler
+
+ mainlayout->addSpacing(5);
+ KSeparator *ruler2 = new KSeparator( KSeparator::HLine, this);
+ mainlayout->addWidget(ruler2);
+
+// buttons
+
+ QHBoxLayout *buttonlayout = new QHBoxLayout;
+ mainlayout->addSpacing(5);
+ mainlayout->addLayout(buttonlayout);
+ mainlayout->addSpacing(5);
+
+ buttonlayout->addSpacing(5);
+ KButtonBox *bbox = new KButtonBox(this);
+
+ bbox->addButton(KStdGuiItem::help(), this, SLOT( help() ));
+ bbox->addStretch(1);
+
+ QButton *okbutton = bbox->addButton(KStdGuiItem::ok());
+ connect( okbutton, SIGNAL( clicked() ), SLOT(accept() ) );
+
+ QButton *cancelbutton = bbox->addButton(KStdGuiItem::cancel());
+ connect( cancelbutton, SIGNAL( clicked() ), SLOT(reject() ) );
+
+ bbox->layout();
+ //min_size(bbox);
+
+ buttonlayout->addWidget(bbox);
+ buttonlayout->addSpacing(5);
+
+ //mainlayout->activate();
+ mainlayout->freeze();
+}
+
+string InterfaceDlg::interfaceName()
+{
+ if(listbox->currentItem() != -1)
+ {
+ string s = listbox->text(listbox->currentItem()).local8Bit().data();
+ string::iterator j = s.begin();
+ while(*j == ' ') j++;
+ return string(j, s.end());
+ }
+ return "";
+}
+
+void InterfaceDlg::raise()
+{
+}
+
+void InterfaceDlg::lower()
+{
+}
+
+void InterfaceDlg::rename()
+{
+}
+
+void InterfaceDlg::update(const string& interface, const string& indent)
+{
+ listbox->insertItem((indent + interface).c_str());
+
+ vector<string> *children = Arts::Dispatcher::the()->interfaceRepo().queryChildren(interface);
+ for (vector<string>::iterator ci = children->begin(); ci != children->end(); ++ci)
+ update(ci->c_str(), indent+" ");
+ delete children;
+}
+
+void InterfaceDlg::update()
+{
+ update("Arts::Object", "");
+}
+
+void InterfaceDlg::help()
+{
+ KApplication::kApplication()->invokeHelp("", "karts");
+}
+
+#include "interfacedlg.moc"
diff --git a/arts/builder/interfacedlg.h b/arts/builder/interfacedlg.h
new file mode 100644
index 00000000..1cfd6a60
--- /dev/null
+++ b/arts/builder/interfacedlg.h
@@ -0,0 +1,52 @@
+ /*
+
+ Copyright (C) 1998-2001 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __INTERFACEDLG_H_
+#define __INTERFACEDLG_H_
+
+#include "structure.h"
+#include "structureport.h"
+#include <qdialog.h>
+#include <qlistbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <vector>
+
+class InterfaceDlg :public QDialog {
+ Q_OBJECT
+protected:
+ QListBox *listbox;
+
+public:
+ InterfaceDlg(QWidget *parent);
+
+ std::string interfaceName();
+ void update(const std::string& interface, const std::string& indent);
+ void update();
+
+public slots:
+ void raise();
+ void lower();
+ void rename();
+ void help();
+};
+
+#endif
diff --git a/arts/builder/main.cpp b/arts/builder/main.cpp
new file mode 100644
index 00000000..9c6d4277
--- /dev/null
+++ b/arts/builder/main.cpp
@@ -0,0 +1,958 @@
+/*
+
+ Copyright (C) 1998 - 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "main.h"
+
+#include "structure.h"
+#include "structureport.h"
+#include "menumaker.h"
+#include "session.h"
+#include "dirmanager.h"
+#include "moduleinfo.h"
+#include "qiomanager.h"
+#include "artsversion.h"
+#include "propertypanel.h"
+#include "module.h"
+#include "autorouter.h"
+#include "portposdlg.h"
+#include "interfacedlg.h"
+#include "execdlg.h"
+#include "retrievedlg.h"
+
+#include "config.h"
+
+#include <kdebug.h>
+#include <arts/debug.h>
+#include <kaction.h>
+#include <kstdaction.h>
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <klocale.h>
+#include <kinputdialog.h>
+#include <kstdaccel.h>
+#include <kfiledialog.h>
+#include <ksavefile.h>
+#include <kmessagebox.h>
+#include <kaboutdata.h>
+#include <kstandarddirs.h>
+#include <kartsserver.h>
+#include <qfile.h>
+#include <qpopupmenu.h>
+
+#include <soundserver.h>
+
+#include <list>
+#include <iostream>
+
+#include <unistd.h>
+#include <string.h> // strerror always here?
+//#include <errno.h>
+
+
+using namespace std;
+
+/*************************************************************/
+
+class ArtsBuilderApp :public KApplication
+{
+protected:
+ ArtsBuilderWindow *mainWindow;
+
+public:
+ ArtsBuilderApp();
+ ArtsBuilderApp(QString filename);
+ void start();
+ void end();
+};
+
+/*************************************************************/
+
+ArtsBuilderWindow::ArtsBuilderWindow(const char *name)
+ : KDockMainWindow(0, name),
+ mainDock(0),
+ modulewidget(0),
+ propertyDock(0),
+ propertyPanel(0),
+ menumaker(0),
+ structure(0),
+ execDlg(0)
+{
+#if 0 /* PORT */
+ ModuleBroker = Synthesizer->moduleBroker();
+ assert(ModuleBroker);
+
+//---- publish my widgets on the server ----
+
+ GUIServer = new GUIServer_impl(ModuleBroker, Synthesizer);
+ arts_debug("GUIServer:\n%s", ArtsOrb->object_to_string(GUIServer));
+ GUIServer->incRef();
+
+//---- trigger autoloading of all structures that are present in my dirs ----
+
+ list<string> datadirs = PortableKDE::globalDirs("data");
+ list<string>::iterator it;
+
+ for(it = datadirs.begin(); it != datadirs.end(); ++it)
+ {
+ string common = *it;
+ common += "artsbuilder";
+ if(chdir(common.c_str()) == 0)
+ ModuleBroker->addPublishingPath(common.c_str());
+ }
+ /*
+ string common = (const char *)PortableKDE::globalDir("data");
+ common += "/artsbuilder";
+ arts_debug("%s", common.c_str());
+ if(chdir(common.c_str()) == 0)
+ ModuleBroker->addPublishingPath(common.c_str());
+ */
+
+ // just make sure that the mapsDir exists
+ (void)DirManager::mapDir();
+
+ if(chdir(DirManager::structureDir()) == 0) // retry
+ {
+ ModuleBroker->addPublishingPath(DirManager::structureDir());
+ Synthesizer->addArtsDirectory(DirManager::baseDir());
+
+ }
+#endif
+
+ arts_debug("PORT: structure");
+ structure = new Structure();
+ arts_debug("PORT: structure ok");
+ //ModuleList = structure->getModuleList();
+
+ mainDock = createDockWidget("mainDockWidget", 0, 0, "main_dock_widget");
+
+ arts_debug("PORT: modulewidget");
+ modulewidget = new ModuleWidget(structure, mainDock, "mwidget");
+ mainDock->setWidget(modulewidget);
+ connect(modulewidget, SIGNAL(modified(bool)), SLOT(setModified(bool)));
+ arts_debug("PORT: modulewidget ok");
+
+ // allow others to dock to the 4 sides
+ mainDock->setDockSite(KDockWidget::DockCorner);
+ // forbit docking abilities of module widget itself
+ mainDock->setEnableDocking(KDockWidget::DockNone);
+
+ setView(mainDock);
+ setMainDockWidget(mainDock);
+
+ propertyDock = createDockWidget("propertyDock", 0, 0, i18n("Port Properties"));
+
+ propertyPanel = new PropertyPanel(propertyDock, "ppanel");
+
+ propertyDock->setWidget(propertyPanel);
+ propertyDock->manualDock(mainDock, // dock target
+ KDockWidget::DockBottom, // dock site
+ 80); // relation target/this (in percent)
+
+ // selection
+ connect(modulewidget, SIGNAL(portSelected(ModulePort *)),
+ propertyPanel, SLOT (setSelectedPort(ModulePort *)));
+ connect(propertyPanel, SIGNAL(portSelected(ModulePort *)),
+ modulewidget, SLOT (selectPort(ModulePort *)));
+ connect(modulewidget, SIGNAL(componentSelected(StructureComponent *)),
+ propertyPanel, SLOT (setSelectedComponent(StructureComponent *)));
+
+ // connection
+ connect(propertyPanel, SIGNAL(startConnection(ModulePort *)),
+ modulewidget, SLOT (startConnection(ModulePort *)));
+
+ // port properties changed
+ connect(propertyPanel, SIGNAL(portPropertiesChanged(ModulePort *)),
+ modulewidget, SLOT (portPropertiesChanged(ModulePort *)));
+
+ arts_debug("PORT: setcanvas");
+ structure->setCanvas(modulewidget);
+ arts_debug("PORT: setcanvas ok");
+
+ mbroker_updateCount = 0;
+
+ arts_debug("PORT: menumaker");
+ menumaker = new MenuMaker(new KActionMenu(i18n("Modules"), actionCollection(), "modulesmenu"));
+ //menumaker->addCategory("&Gui", "Gui_");
+ menumaker->addCategory(i18n("&Synthesis"), "Arts::Synth_");
+ menumaker->addCategory(i18n("&Synthesis/&Arithmetic + Mixing"), "Arts::Synth_ADD$");
+ menumaker->addCategory(i18n("&Synthesis/&Arithmetic + Mixing"), "Arts::Synth_AUTOPANNER$");
+ menumaker->addCategory(i18n("&Synthesis/&Arithmetic + Mixing"), "Arts::Synth_MUL$");
+ menumaker->addCategory(i18n("&Synthesis/&Arithmetic + Mixing"), "Arts::Synth_DIV$");
+ menumaker->addCategory(i18n("&Synthesis/&Arithmetic + Mixing"), "Arts::Synth_MULTI_ADD$");
+ menumaker->addCategory(i18n("&Synthesis/&Arithmetic + Mixing"), "Arts::Synth_XFADE$");
+ menumaker->addCategory(i18n("&Synthesis/&Busses"), "Arts::Synth_BUS_");
+ menumaker->addCategory(i18n("&Synthesis/&Delays"), "Arts::Synth_DELAY$");
+ menumaker->addCategory(i18n("&Synthesis/&Delays"), "Arts::Synth_CDELAY$");
+ menumaker->addCategory(i18n("&Synthesis/&Envelopes"), "Arts::Synth_PSCALE$");
+ menumaker->addCategory(i18n("&Synthesis/&Envelopes"), "Arts::Synth_ENVELOPE_");
+ menumaker->addCategory(i18n("&Synthesis/Effe&cts"), "Arts::Synth_FREEVERB$");
+ menumaker->addCategory(i18n("&Synthesis/Effe&cts"), "Arts::Synth_FX_");
+ menumaker->addCategory(i18n("&Synthesis/Effe&cts"), "Arts::Synth_PITCH_SHIFT$");
+ menumaker->addCategory(i18n("&Synthesis/Effe&cts"), "Arts::Synth_TREMOLO$");
+ menumaker->addCategory(i18n("&Synthesis/&Filters"), "Arts::Synth_ATAN_SATURATE$");
+ menumaker->addCategory(i18n("&Synthesis/&Filters"), "Arts::Synth_BRICKWALL_LIMITER$");
+ menumaker->addCategory(i18n("&Synthesis/&Filters"), "Arts::Synth_MOOG_VCF");
+ menumaker->addCategory(i18n("&Synthesis/&Filters"), "Arts::Synth_SHELVE_CUTOFF$");
+ menumaker->addCategory(i18n("&Synthesis/&Filters"), "Arts::Synth_RC$");
+ menumaker->addCategory(i18n("&Synthesis/&Filters"), "Arts::Synth_STD_EQUALIZER$");
+ menumaker->addCategory(i18n("&Synthesis/&Midi + Sequencing"), "Arts::Synth_MIDI");
+ menumaker->addCategory(i18n("&Synthesis/&Midi + Sequencing"), "Arts::Interface_MIDI");
+ menumaker->addCategory(i18n("&Synthesis/&Midi + Sequencing"), "Arts::Synth_SEQUENCE$");
+ menumaker->addCategory(i18n("&Synthesis/&Midi + Sequencing"), "Arts::Synth_SEQUENCE_FREQ$");
+ menumaker->addCategory(i18n("&Synthesis/&Midi + Sequencing"), "Arts::Synth_STRUCT_KILL$");
+ menumaker->addCategory(i18n("&Synthesis/Sam&ples "), "Arts::Synth_PLAY_");
+ menumaker->addCategory(i18n("&Synthesis/&Sound IO"), "Arts::Synth_AMAN_");
+ menumaker->addCategory(i18n("&Synthesis/&Sound IO"), "Arts::Synth_CAPTURE_WAV$");
+ menumaker->addCategory(i18n("&Synthesis/&Sound IO"), "Arts::Synth_PLAY$");
+ menumaker->addCategory(i18n("&Synthesis/&Sound IO"), "Arts::Synth_RECORD$");
+ menumaker->addCategory(i18n("&Synthesis/&Sound IO"), "Arts::Synth_FULL_DUPLEX_");
+ menumaker->addCategory(i18n("&Synthesis/&Sound IO"), "Arts::Synth_FILEPLAY");
+ menumaker->addCategory(i18n("&Synthesis/&Tests"), "Arts::Synth_NIL$");
+ menumaker->addCategory(i18n("&Synthesis/&Tests"), "Arts::Synth_DEBUG$");
+ menumaker->addCategory(i18n("&Synthesis/&Tests"), "Arts::Synth_DATA$");
+ menumaker->addCategory(i18n("&Synthesis/&Tests"), "Arts::Synth_MIDI_DEBUG$");
+ menumaker->addCategory(i18n("&Synthesis/&Oscillation && Modulation"), "Arts::Synth_FREQUENCY$");
+ menumaker->addCategory(i18n("&Synthesis/&Oscillation && Modulation"), "Arts::Synth_FM_SOURCE$");
+ menumaker->addCategory(i18n("&Synthesis/&Oscillation && Modulation"), "Arts::Synth_OSC$");
+ menumaker->addCategory(i18n("&Synthesis/&WaveForms"), "Arts::Synth_WAVE_");
+ menumaker->addCategory(i18n("&Synthesis/&WaveForms"), "Arts::Synth_NOISE$");
+ menumaker->addCategory(i18n("&Synthesis/&Internal"), "Arts::Synth_PARAM_");
+
+ menumaker->addCategory(i18n("&Examples"), "example_");
+ menumaker->addCategory(i18n("&Instruments"), "instrument_");
+ menumaker->addCategory(i18n("&Mixer-Elements"), "mixer_element_");
+ menumaker->addCategory(i18n("&Templates"), "template_");
+ menumaker->addCategory(i18n("&Other"), "*");
+ arts_debug("PORT: menumaker ok");
+
+/*
+ m_modules->insertItem(i18n("&Gui"), m_modules_gui);
+ m_modules->insertItem(i18n("&Synthesis"), m_modules_synth);
+ m_modules->insertItem(i18n("&Instruments"), m_modules_instruments);
+ m_modules->insertItem(i18n("&Other"), m_modules_other);
+ */
+
+#if 000
+ connect(menubar, SIGNAL(highlighted(int)), this, SLOT(activateMenu(int)));
+ connect(m_view, SIGNAL(activated(int)), modulewidget, SLOT(setZoom(int)));
+ connect(m_ports, SIGNAL(activated(int)), this, SLOT(addPort(int)));
+ connect(m_file_new, SIGNAL(activated(int)), this, SLOT(fileNew(int)));
+
+ //connect(m_modules, SIGNAL(activated(int)), this, SLOT(addModule(int)));
+ /*
+ connect(m_modules_synth, SIGNAL(activated(int)), this, SLOT(addModule(int)));
+ connect(m_modules_gui, SIGNAL(activated(int)), this, SLOT(addModule(int)));
+ connect(m_modules_instruments, SIGNAL(activated(int)), this, SLOT(addModule(int)));
+ connect(m_modules_other, SIGNAL(activated(int)), this, SLOT(addModule(int)));
+ */
+ connect(kapp, SIGNAL(lastWindowClosed()), this , SLOT(quit()));
+
+ // update the modules menu once for the start
+#endif
+
+ arts_debug("PORT: activatemenu");
+ connect(menumaker, SIGNAL(activated(const char *)), this, SLOT(addModule(const char *)));
+ fillModuleMenu();
+ arts_debug("PORT: activatemenu ok");
+ setupActions();
+
+ createGUI();
+
+ // connect to aboutToShow to correctly show state of dockwidget there:
+ QPopupMenu *viewmenu = (QPopupMenu*)factory()->container("view", this);
+ if (viewmenu)
+ connect(viewmenu, SIGNAL(aboutToShow()), this, SLOT(viewMenuAboutToShow()));
+ else
+ arts_debug("view menu not found!");
+
+ m_filename = QString::null;
+ setModified(false);
+
+ installEventFilter(propertyPanel);
+}
+
+void ArtsBuilderWindow::setupActions()
+{
+ // File menu
+ KStdAction::openNew(this, SLOT(fileNew()), actionCollection());
+
+ (void)new KAction(i18n("Open Session..."), 0, this, SLOT(openSession()),
+ actionCollection(), "file_open_session");
+ KStdAction::open(this, SLOT(open()), actionCollection());
+ (void)new KAction(i18n("Open E&xample..."), Qt::CTRL + Qt::Key_X, this, SLOT(openExample()),
+ actionCollection(), "file_open_example");
+ KStdAction::save(this, SLOT(save()), actionCollection());
+ KStdAction::saveAs(this, SLOT(saveAs()), actionCollection());
+ (void)new KAction(i18n("&Retrieve From Server..."), Qt::CTRL + Qt::Key_R, this, SLOT(retrieve()),
+ actionCollection(), "file_retrieve_from_server");
+ (void)new KAction(i18n("&Execute Structure"), "artsbuilderexecute", Qt::CTRL + Qt::Key_E, this, SLOT(execute()),
+ actionCollection(), "file_execute_structure");
+ (void)new KAction(i18n("&Rename Structure..."), Qt::CTRL + Qt::Key_R, this, SLOT(rename()),
+ actionCollection(), "file_rename_structure");
+ (void)new KAction(i18n("&Publish Structure"), Qt::CTRL + Qt::Key_P, this, SLOT(publish()),
+ actionCollection(), "file_publish_structure");
+ KStdAction::quit(this, SLOT(close()), actionCollection());
+
+ // Edit menu
+ (void)new KAction(i18n("&Delete"), Qt::Key_Delete, modulewidget, SLOT(delModule()),
+ actionCollection(), "edit_delete");
+ KStdAction::selectAll(modulewidget, SLOT(selectAll()), actionCollection());
+
+ // View menu
+ viewPropertiesAction= new KToggleAction(i18n("&Property Panel"), 0,
+ propertyDock, SLOT(changeHideShowState()),
+ actionCollection(), "view_properties");
+ (void)new KAction(i18n("200%"), 0, this, SLOT(viewAt200()),
+ actionCollection(), "view_200");
+ (void)new KAction(i18n("150%"), 0, this, SLOT(viewAt150()),
+ actionCollection(), "view_150");
+ (void)new KAction(i18n("100%"), 0, this, SLOT(viewAt100()),
+ actionCollection(), "view_100");
+ (void)new KAction(i18n("50%"), 0, this, SLOT(viewAt50()),
+ actionCollection(), "view_50");
+
+ // Ports menu
+ (void)new KAction(i18n("Create IN Audio Signal"), 0, this, SLOT(createInAudioSignal()),
+ actionCollection(), "ports_create_in_audio_signal");
+ (void)new KAction(i18n("Create OUT Audio Signal"), 0, this, SLOT(createOutAudioSignal()),
+ actionCollection(), "ports_create_out_audio_signal");
+ (void)new KAction(i18n("Create IN String Property"), 0, this, SLOT(createInStringProperty()),
+ actionCollection(), "ports_create_in_string_property");
+ (void)new KAction(i18n("Create IN Audio Property"), 0, this, SLOT(createInAudioProperty()),
+ actionCollection(), "ports_create_in_audio_property");
+ (void)new KAction(i18n("Implement Interface..."), 0, this, SLOT(addInterface()),
+ actionCollection(), "ports_implement_interface");
+ (void)new KAction(i18n("Change Positions/Names..."), 0, this, SLOT(changePortPositions()),
+ actionCollection(), "ports_change_positions");
+}
+
+void ArtsBuilderWindow::fillModuleMenu()
+{
+ long updateCount = 3; /* PORT: automatic update of menues missing */
+
+ if(updateCount != mbroker_updateCount)
+ {
+ mbroker_updateCount = updateCount;
+ //---- query all available objects ----
+ Arts::TraderQuery query;
+ query.supports("Buildable", "true");
+ vector<Arts::TraderOffer> *offers = query.query();
+
+ menumaker->clear();
+ //m_file_new->clear();
+
+ vector<Arts::TraderOffer>::iterator i;
+ long n = 1; /* TODO:PORT: is this necessary? I think not */
+ for(i = offers->begin(); i != offers->end(); ++i)
+ {
+ Arts::TraderOffer& offer = *i;
+ string name = offer.interfaceName();
+ menumaker->addItem(name.c_str(),n++);
+
+ /* PORT: templates missing
+ if(strncmp(name, "template_", strlen("template_")) == 0)
+ {
+ char *xname = strdup(&name[strlen("template_")]);
+ int x;
+ for(x = 0;xname[x] != 0; x++)
+ if(xname[x] == '_') xname[x] = ' ';
+
+ m_file_new->insertItem(xname, i);
+ }
+ */
+ }
+ delete offers;
+ }
+#if 0
+ if(0) /*item == modules_menu_item) PORT!!! */
+ {
+ long updateCount = ModuleBroker->updateCount();
+
+ // if the contents of the ModukeBroker changed, update our "modules"-Menu
+ if(updateCount != mbroker_updateCount)
+ {
+ mbroker_updateCount = updateCount;
+ //---- query all available objects ----
+ ArtsCorba::StringSeq_var Modules = ModuleBroker->publishedModules();
+ assert(Modules);
+
+ menumaker->clear();
+ m_file_new->clear();
+
+ unsigned long i;
+ for(i = 0; i < Modules->length();i++)
+ {
+ const char *name = (*Modules)[i];
+ menumaker->addItem(name, i);
+
+ if(strncmp(name, "template_", strlen("template_")) == 0)
+ {
+ char *xname = strdup(&name[strlen("template_")]);
+ int x;
+ for(x = 0;xname[x] != 0; x++)
+ if(xname[x] == '_') xname[x] = ' ';
+
+ m_file_new->insertItem(xname, i);
+ }
+ }
+ }
+ }
+#endif
+}
+
+void ArtsBuilderWindow::quit()
+{
+ if(execDlg) return;
+ arts_debug(">> ArtsBuilderWindow::quit() called");
+ kapp->quit();
+ arts_debug("<< leaving ArtsBuilderWindow::quit()");
+}
+
+ArtsBuilderWindow::~ArtsBuilderWindow()
+{
+ delete structure;
+}
+
+void ArtsBuilderWindow::viewMenuAboutToShow()
+{
+ viewPropertiesAction->setChecked(propertyDock->isVisible());
+}
+
+void ArtsBuilderWindow::publish()
+{
+ checkName();
+ structure->publish();
+ KMessageBox::information(this,
+ i18n("The structure has been published as: '%1' on the server.").arg( structure->name().c_str() ));
+}
+
+QString ArtsBuilderWindow::getOpenFilename(const char *pattern, const char *initialDir)
+{
+ arts_debug(">>>>> getOpenFilename");
+ QString filename = KFileDialog::getOpenFileName(initialDir, pattern, this);
+ arts_debug(">>>>> opendlg closed");
+ if(!filename.isEmpty())
+ {
+ arts_debug("open... %s", filename.local8Bit().data());
+
+ // check that the file is ok:
+
+ FILE *infile = fopen(QFile::encodeName(filename), "r");
+
+ if(infile)
+ {
+ fclose(infile);
+ return(filename);
+ }
+ }
+ return QString("");
+}
+
+void ArtsBuilderWindow::fileNew()
+{
+ if(!promptToSave())
+ return;
+
+ propertyPanel->setSelectedComponent(0);
+ structure->clear();
+ modulewidget->reInit();
+ m_filename = QString::null;
+ setModified(false);
+}
+
+void ArtsBuilderWindow::open()
+{
+ if(!promptToSave())
+ return;
+
+ open(getOpenFilename("*.arts", DirManager::structureDir()));
+}
+
+void ArtsBuilderWindow::open(QString filename)
+{
+ if(!promptToSave())
+ return;
+
+ if(!filename.isEmpty())
+ {
+ structure->load(QFile::encodeName(filename));
+ modulewidget->reInit();
+ if(!structure->valid())
+ {
+ KMessageBox::sorry(this,
+ i18n("The structure could not be loaded correctly. Maybe some of\n"
+ "the modules used in the file are not available in this\n"
+ "version of aRts."),
+ i18n("Arts Warning"));
+ }
+ m_filename = filename;
+ setModified(false);
+ setCaption(m_filename);
+ }
+}
+
+void ArtsBuilderWindow::openSession()
+{
+ if(!promptToSave())
+ return;
+
+ QString filename = getOpenFilename("*.arts-session", DirManager::sessionDir());
+
+ if(!filename.isEmpty())
+ {
+ Session *session = new Session();
+ session->loadSession(QFile::encodeName(filename));
+
+ assert(!execDlg);
+ execDlg = new ExecDlg(0, session);
+ assert(execDlg);
+
+ // this will create the widgets that will eventually get into the
+ // execdlg
+ session->startExecute();
+
+ execDlg->start();
+ execDlg->show();
+
+ connect(execDlg, SIGNAL(ready()), this, SLOT(endexecute()));
+
+ hide();
+ // m_filename = filename; FIXME: DOESN'T THIS BELONG HERE?
+ setModified(false);
+ }
+}
+
+void ArtsBuilderWindow::openExample()
+{
+ if(!promptToSave())
+ return;
+
+ QString dir = locate("data", "artsbuilder/examples/");
+ if(!dir)
+ KMessageBox::sorry(
+ this,
+ i18n("Unable to find the examples folder.\nUsing the current folder instead."),
+ i18n("aRts Warning"));
+
+ open(getOpenFilename("*.arts", QFile::encodeName(dir)));
+}
+
+void ArtsBuilderWindow::saveAs()
+{
+ checkName();
+ string defaultname = string(structure->name()) + string(".arts");
+
+ chdir(DirManager::structureDir());
+ KFileDialog *dlg = new KFileDialog(0, "*.arts", this, 0, true /*,false TODO: acceptURLs */);
+
+ dlg->setSelection(defaultname.c_str());
+ dlg->setCaption(i18n("Save As"));
+
+ QString filename;
+ if(dlg->exec() == QDialog::Accepted)
+ filename = dlg->selectedFile();
+
+ delete dlg;
+ // QString filename = KFileDialog::getSaveFileName(0, "*.arts", this);
+ // filename.detach();
+
+ if(!filename.isEmpty())
+ save(filename);
+}
+
+bool ArtsBuilderWindow::save(QString filename)
+{
+ arts_debug("trying to save structure as '%s'", filename.local8Bit().data());
+
+ KSaveFile file(filename);
+
+ if(file.status()) {
+ KMessageBox::sorry(this,
+ i18n("The file '%1' could not be opened for writing: %2")
+ .arg(filename).arg(strerror(file.status())),
+ i18n("aRts Warning"));
+ return false;
+ }
+
+ structure->saveInto(file.fstream());
+
+ if(!file.close()) {
+ KMessageBox::sorry(this,
+ i18n("Saving to file '%1' could not be finished correctly: %2")
+ .arg(filename).arg(strerror(file.status())),
+ i18n("aRts Warning"));
+ return false;
+ }
+
+ // tell the server to rescan for structures
+ Arts::SoundServerV2 server = KArtsServer().server();
+ if(!server.isNull()) server.checkNewObjects();
+
+ m_filename = filename;
+ setModified(false);
+ return true;
+}
+
+void ArtsBuilderWindow::save()
+{
+ if(m_filename.isEmpty())
+ saveAs();
+ else
+ save(m_filename);
+}
+
+void ArtsBuilderWindow::checkName()
+{
+ if(strncmp(structure->name().c_str(), "template_", strlen("template_")) == 0)
+ rename();
+}
+
+void ArtsBuilderWindow::rename()
+{
+ bool ok;
+
+ QString name = KInputDialog::getText( i18n( "Rename Structure" ),
+ i18n( "Enter structure name:" ), structure->name().c_str(), &ok, this );
+ if (ok)
+ {
+ arts_debug("rename OK...");
+ structure->rename(name.local8Bit());
+ }
+
+ setModified(true);
+}
+
+void ArtsBuilderWindow::retrieve()
+{
+ if(!promptToSave())
+ return;
+
+ RetrieveDlg rd(0);
+
+ if(rd.exec())
+ {
+ QString result = rd.result();
+ if(!result.isEmpty())
+ {
+ structure->retrieve(result.local8Bit());
+ modulewidget->reInit();
+ }
+ }
+ // maybe set m_filename to null or sth. here?
+ setModified(true);
+}
+
+void ArtsBuilderWindow::execute()
+{
+ assert(structure);
+ assert(!execDlg);
+ execDlg = new ExecDlg(0, structure);
+ assert(execDlg);
+
+ // this will create the widgets that will eventually get into the
+ // execdlg
+ if(structure->startExecute())
+ {
+ execDlg->start();
+ execDlg->show();
+
+ connect(execDlg, SIGNAL(ready()), this, SLOT(endexecute()));
+
+ hide();
+ }
+ else
+ {
+ delete execDlg;
+ execDlg = 0;
+
+ KMessageBox::sorry(this,
+ i18n("Could not execute your structure. Make sure that the\n"
+ "sound server (artsd) is running.\n"), i18n("aRts Warning"));
+ }
+}
+
+void ArtsBuilderWindow::endexecute()
+{
+ show();
+ assert(execDlg);
+ delete execDlg;
+ // will be done by the execDlg itself now
+ //structure->stopExecute();
+
+ execDlg = 0;
+}
+
+void ArtsBuilderWindow::oldFileNewWhatTheHellDoesItDo(int what)
+{
+ if(!promptToSave())
+ return;
+
+ const char *name = menumaker->findID(what);
+ assert(name);
+ structure->retrieve(name);
+ modulewidget->reInit();
+ setModified(false);
+}
+
+void ArtsBuilderWindow::createInAudioSignal()
+{
+ // data that goes into the structure
+ modulewidget->addPort(Arts::PortType(Arts::output, "float", Arts::conn_stream, false));
+ setModified(true);
+}
+
+void ArtsBuilderWindow::createOutAudioSignal()
+{
+ // data that goes out of the structure
+ modulewidget->addPort(Arts::PortType(Arts::input, "float", Arts::conn_stream, false));
+ setModified(true);
+}
+
+void ArtsBuilderWindow::createInStringProperty()
+{
+ // data that goes into the structure
+ modulewidget->addPort(Arts::PortType(Arts::output, "string", Arts::conn_property, false));
+ setModified(true);
+}
+
+void ArtsBuilderWindow::createInAudioProperty()
+{
+ // data that goes into the structure
+ modulewidget->addPort(Arts::PortType(Arts::output, "float", Arts::conn_property, false));
+ setModified(true);
+}
+
+void ArtsBuilderWindow::changePortPositions()
+{
+ PortPosDlg *ppd = new PortPosDlg(this, structure);
+ ppd->exec();
+ setModified(true);
+ // XXX: delete ppd?
+}
+
+void ArtsBuilderWindow::addInterface()
+{
+ InterfaceDlg *ifd = new InterfaceDlg(this);
+ ifd->exec();
+
+ Arts::ModuleInfo minfo = makeModuleInfo(ifd->interfaceName());
+ if(!minfo.name.empty())
+ modulewidget->addInterface(minfo);
+
+ delete ifd;
+}
+
+void ArtsBuilderWindow::viewAt50()
+{
+ modulewidget->setZoom(50);
+}
+
+void ArtsBuilderWindow::viewAt100()
+{
+ modulewidget->setZoom(100);
+}
+
+void ArtsBuilderWindow::viewAt150()
+{
+ modulewidget->setZoom(150);
+}
+
+void ArtsBuilderWindow::viewAt200()
+{
+ modulewidget->setZoom(200);
+}
+
+void ArtsBuilderWindow::addModule(const char *name)
+{
+ arts_return_if_fail (name != 0);
+
+ arts_debug("addModule(%s)", name);
+ Arts::ModuleInfo minfo = makeModuleInfo(name);
+
+ if(!minfo.name.empty())
+ modulewidget->addModule(minfo);
+#if 0
+ const char *name = menumaker->findID(module);
+ assert(name);
+
+ arts_debug("selected (%s) (module=%d)", name, module);
+
+ ArtsCorba::ModuleBroker_var ModuleBroker = Synthesizer->moduleBroker();
+ ArtsCorba::ModuleInfo_var minfo = ModuleBroker->lookupModule(name);
+
+
+ if(minfo)
+ {
+ modulewidget->addModule(minfo);
+
+/*
+ Module *m = structure->createModule(minfo);
+ modulewidget->addModule(m);
+*/
+ }
+#endif
+ setModified(true);
+}
+
+bool ArtsBuilderWindow::isModified()
+{
+ return modified;
+}
+
+void ArtsBuilderWindow::setModified(bool m)
+{
+ modified = m;
+ setCaption(m_filename, modified);
+ actionCollection()->action(KStdAction::stdName(KStdAction::Save))->setEnabled(modified);
+}
+
+bool ArtsBuilderWindow::queryClose()
+{
+ return promptToSave();
+}
+
+bool ArtsBuilderWindow::promptToSave()
+{
+ bool result;
+ int query;
+
+ if(!isModified())
+ return true;
+
+ query = KMessageBox::warningYesNoCancel(this,
+ i18n("The current structure has been modified.\nWould you like to save it?"), QString::null, KStdGuiItem::save(), KStdGuiItem::discard());
+
+ result = false;
+ switch(query)
+ {
+ case KMessageBox::Yes:
+ save();
+ result = !modified;
+ break;
+ case KMessageBox::No:
+ result = true;
+ setModified(false);
+ break;
+ case KMessageBox::Cancel:
+ break;
+ }
+ return result;
+}
+
+/*************************************************************/
+
+ArtsBuilderApp::ArtsBuilderApp()
+{
+ start();
+}
+
+ArtsBuilderApp::ArtsBuilderApp(QString filename)
+{
+ start();
+ if(QFile::exists(filename))
+ {
+ mainWindow->open(filename);
+ } else {
+ KMessageBox::sorry(0,
+ i18n("The specified file '%1' does not exist.").arg(filename),
+ i18n("aRts Warning"));
+ }
+}
+
+void ArtsBuilderApp::start()
+{
+ arts_debug("PORT: mainWindow");
+ mainWindow = new ArtsBuilderWindow("main");
+
+ arts_debug("PORT: mainWindow ok");
+ mainWindow->resize(680, 500);
+ arts_debug("PORT: mainWindow show");
+ mainWindow->show();
+ arts_debug("PORT: mainWindow show ok");
+
+#if 0 /* PORT */
+ ArtsCorba::ModuleBroker_var ModuleBroker = theSynthesizer->moduleBroker();
+ assert(ModuleBroker);
+#endif
+
+ setTopWidget(mainWindow);
+}
+
+void ArtsBuilderApp::end()
+{
+ delete mainWindow;
+}
+
+/*************************************************************/
+
+static KCmdLineOptions options[] =
+{
+ { "+[file]", I18N_NOOP("Optional .arts file to be loaded"), 0 },
+ KCmdLineLastOption
+};
+
+#ifdef COMMON_BINARY
+int artsbuilder_main(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif
+{
+ KAboutData aboutData("artsbuilder",
+ I18N_NOOP("artsbuilder"),
+ ARTS_VERSION,
+ I18N_NOOP("aRts synthesizer designer"),
+ KAboutData::License_GPL,
+ "(C) 1998-2001, Stefan Westerfeld",
+ I18N_NOOP("The analog real-time synthesizer graphical design tool."),
+ "http://www.arts-project.org/",
+ "submit@bugs.kde.org");
+
+ aboutData.addAuthor("Stefan Westerfeld", I18N_NOOP("Author"), "stefan@twc.de");
+ aboutData.addCredit("Waldo Bastian", 0, "bastian@kde.org");
+ aboutData.addCredit("Jens Hahn", 0, "Jens.Hahn@t-online.de");
+ aboutData.addCredit("Martin Lorenz", 0, "lorenz@ch.tum.de");
+ aboutData.addCredit("Hans Meine", 0, "hans_meine@gmx.net");
+ aboutData.addCredit("Jeff Tranter", 0, "tranter@pobox.com");
+
+ KCmdLineArgs::init(argc, argv, &aboutData);
+ KCmdLineArgs::addCmdLineOptions(options);
+ Arts::QIOManager iomanager;
+ Arts::Dispatcher dispatcher(&iomanager);
+
+ Arts::ObjectManager::the()->provideCapability("kdegui");
+
+ // check for one optional filename argument
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ if(args->count() > 1) {
+ args->usage("");
+ }
+ if(args->count() > 0)
+ {
+ ArtsBuilderApp Application(QFile::decodeName(args->arg(0)));
+ args->clear();
+ return Application.exec();
+ } else {
+ ArtsBuilderApp Application;
+ args->clear();
+ return Application.exec();
+ }
+}
+#include "main.moc"
diff --git a/arts/builder/main.h b/arts/builder/main.h
new file mode 100644
index 00000000..f7babc3a
--- /dev/null
+++ b/arts/builder/main.h
@@ -0,0 +1,118 @@
+ /*
+
+ Copyright (C) 1998-1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __MAIN_H__
+#define __MAIN_H__
+
+#include "mwidget.h"
+
+#include <kdockwidget.h>
+#include <kapplication.h>
+#include <kfiledialog.h>
+#include <ksimpleconfig.h>
+
+#include <list>
+
+class PropertyPanel;
+class Structure;
+class MenuMaker;
+class ExecDlg;
+class KToggleAction;
+
+class ArtsBuilderWindow: public KDockMainWindow
+{
+ Q_OBJECT
+
+protected:
+ KDockWidget* mainDock;
+ ModuleWidget *modulewidget;
+
+ KDockWidget* propertyDock;
+ PropertyPanel *propertyPanel;
+ KToggleAction *viewPropertiesAction;
+
+ MenuMaker *menumaker;
+
+ long mbroker_updateCount;
+ Structure *structure;
+
+ ExecDlg *execDlg;
+
+ QString m_filename;
+ bool modified;
+
+protected:
+ void setupActions();
+
+public:
+ ArtsBuilderWindow(const char *name);
+ ~ArtsBuilderWindow();
+
+ void clear();
+ void checkName();
+ QString getOpenFilename(const char *pattern, const char *initialDir = 0);
+ bool isModified();
+ bool promptToSave();
+ bool queryClose();
+
+public slots:
+ void fillModuleMenu();
+ void viewMenuAboutToShow();
+
+ /* ports menu */
+ void createInAudioSignal();
+ void createOutAudioSignal();
+ void createInStringProperty();
+ void createInAudioProperty();
+ void addInterface();
+
+ /* view menu */
+ void viewAt50();
+ void viewAt100();
+ void viewAt150();
+ void viewAt200();
+
+ /* file menu */
+ void fileNew();
+ void open();
+ void openSession();
+ void openExample();
+ void save();
+ void saveAs();
+ void quit();
+
+ void open(QString filename);
+ bool save(QString filename);
+ void setModified(bool m = true);
+
+ void execute();
+ void endexecute();
+ void rename();
+ void retrieve();
+ void publish();
+
+ void addModule(const char *module);
+ void changePortPositions();
+
+ void oldFileNewWhatTheHellDoesItDo(int what);
+};
+
+#endif
diff --git a/arts/builder/menumaker.cpp b/arts/builder/menumaker.cpp
new file mode 100644
index 00000000..54e32e2b
--- /dev/null
+++ b/arts/builder/menumaker.cpp
@@ -0,0 +1,212 @@
+#include "menumaker.h"
+#include <stdio.h>
+#include <assert.h>
+#include <arts/debug.h>
+
+using namespace std;
+
+MenuEntry::MenuEntry(MenuMaker *menumaker, KActionMenu *parent, const char *text)
+ : menumaker(menumaker), text(text)
+{
+ action = new KAction(QString::fromLocal8Bit(text));
+ parent->insert(action);
+ connect(action, SIGNAL(activated()), this, SLOT(activated()));
+}
+
+void MenuEntry::activated()
+{
+ menumaker->menuActivated(text);
+}
+
+MenuCategory::MenuCategory(const QString& name, const char *prefix, KActionMenu *menu)
+{
+ _menu = menu;
+ _name = name;
+ _catchall = (strcmp(prefix,"*") == 0);
+ addPrefix(prefix);
+}
+
+QString MenuCategory::name()
+{
+ return _name;
+}
+
+bool MenuCategory::catchall()
+{
+ return _catchall;
+}
+
+void MenuCategory::addPrefix(const char *prefix)
+{
+ prefixList.push_back(prefix);
+}
+
+bool MenuCategory::matches(const char *item)
+{
+ string pattern = string(item)+"$";
+ size_t patternlen = strlen(pattern.c_str());
+
+ list<string>::iterator i;
+
+ for(i=prefixList.begin();i != prefixList.end(); ++i)
+ {
+ const char *prefix = (*i).c_str();
+
+ if(patternlen >= strlen(prefix))
+ {
+ if(strncmp(prefix,pattern.c_str(),strlen(prefix)) == 0) return true;
+ }
+ }
+ return false;
+}
+
+KActionMenu *MenuCategory::menu()
+{
+ return _menu;
+}
+
+MenuMaker::MenuMaker(KActionMenu *root)
+{
+ categories.push_back(new MenuCategory("","",root));
+}
+
+// Add more specific categories later, more general categories first.
+//
+// for instance use
+// addCategory("&Synthesis", "Synth_");
+// addCategory("&Synthesis/&Waveforms", "Synth_WAVE");
+
+void MenuMaker::addCategory(const QString& name, const char *prefix)
+{
+ MenuCategory *mc = 0,*pc = 0;
+
+ mc = lookupCategoryByName(name);
+ if(mc)
+ {
+ mc->addPrefix(prefix);
+ return; // already exists
+ }
+
+ pc = lookupCategoryByName(basename(name));
+ if(pc)
+ {
+ KActionMenu *newMenu = new KActionMenu(catname(name));
+ pc->menu()->insert(newMenu);
+ /* 000 */
+ /*connect(newMenu,SIGNAL(activated(int)),this,SLOT(menuactivated(int)));
+ pc->menu()->insertItem(catname(name).c_str(), newMenu, CAT_MAGIC_ID);*/
+ arts_debug("inserting a menu called '%s' in the parent menu '%s'",
+ catname(name).local8Bit().data(),pc->name().local8Bit().data());
+ categories.push_back(new MenuCategory(name,prefix,newMenu));
+ }
+ else
+ {
+ arts_debug("Parent category '%s' for '%s' is missing.",
+ basename(name).local8Bit().data(),name.local8Bit().data());
+ }
+}
+
+MenuCategory *MenuMaker::lookupCategoryByName(const QString& name)
+{
+ MenuCategory *mc = 0;
+ list<MenuCategory *>::iterator i;
+ for(i=categories.begin();i != categories.end();++i)
+ {
+ if((*i)->name() == name) mc = (*i);
+ }
+ return mc;
+}
+
+void MenuMaker::addItem(const char *name, int index)
+{
+ MenuCategory *mc = 0;
+
+ list<MenuCategory *>::iterator i;
+ for(i=categories.begin();i != categories.end();++i)
+ if((*i)->matches(name)) mc = (*i);
+ assert(mc); // root category should always match
+
+ if(mc->name().isEmpty())
+ {
+ // if we hit the root category, it may be better to move the thing
+ // into the catchall category (looks cleaner)
+ for(i=categories.begin();i != categories.end();++i)
+ if((*i)->catchall()) mc = (*i);
+ }
+ //mc->menu()->insertItem(name,index); 000
+ //mc->menu()->insert(new KAction(name)); // index??
+ new MenuEntry(this, mc->menu(), name);
+ /*
+ KAction *action = new KAction(QString(name));
+ mc->menu()->insert(action);
+ */
+ //action->plug(mc->menu());
+ //mc->menu()->insert(new KAction(name)); // index??
+}
+
+QString MenuMaker::basename(const QString& name)
+{
+ QString result = "";
+
+ int i = name.findRev('/');
+ if(i != -1)
+ result = name.left(i);
+
+ arts_debug("basename(%s) => %s",name.local8Bit().data(),
+ result.local8Bit().data());
+ return result;
+}
+
+QString MenuMaker::catname(const QString& name)
+{
+ int i = name.findRev('/');
+ if(i >= 0)
+ return name.mid(i+1);
+
+ return name;
+}
+
+void MenuMaker::clear()
+{
+ list<MenuCategory *>::iterator i;
+ for(i=categories.begin();i != categories.end();++i)
+ {
+ /* 000
+ KActionMenu *m = (*i)->menu();
+ unsigned int k;
+
+ k = 0;
+ while(k<m->count())
+ {
+ if(m->idAt(k) != CAT_MAGIC_ID)
+ {
+ m->removeItemAt(k);
+ k = 0;
+ }
+ else
+ {
+ k++;
+ }
+ }
+ */
+ }
+}
+
+const char *MenuMaker::findID(int id)
+{
+ /* 000 ?
+ list<MenuCategory *>::iterator i;
+ for(i=categories.begin();i != categories.end();i++)
+ {
+ const char *name = (*i)->menu()->text(id);
+ if(name) return(name);
+ } */
+ return 0;
+}
+
+void MenuMaker::menuActivated(const char *text)
+{
+ emit activated(text);
+}
+
+#include "menumaker.moc"
diff --git a/arts/builder/menumaker.h b/arts/builder/menumaker.h
new file mode 100644
index 00000000..5b999dc5
--- /dev/null
+++ b/arts/builder/menumaker.h
@@ -0,0 +1,70 @@
+#ifndef __MENUMAKER_H__
+#define __MENUMAKER_H__
+
+#include <kaction.h>
+#include <qobject.h>
+#include <string>
+#include <list>
+
+class MenuMaker;
+
+class MenuEntry : public QObject
+{
+ Q_OBJECT
+
+protected:
+ MenuMaker *menumaker;
+ KAction *action;
+ QCString text;
+
+public:
+ MenuEntry(MenuMaker *menumaker, KActionMenu *parent, const char *text);
+
+public slots:
+ void activated();
+};
+
+class MenuCategory
+{
+protected:
+ KActionMenu *_menu;
+ QString _name;
+ std::list<std::string> prefixList;
+ bool _catchall;
+
+public:
+ MenuCategory(const QString& name, const char *prefix, KActionMenu *menu);
+
+ void addPrefix(const char *prefix);
+ QString name();
+ KActionMenu *menu();
+
+ bool catchall();
+ bool matches(const char *item);
+};
+
+class MenuMaker :public QObject
+{
+ Q_OBJECT
+
+ std::list<MenuCategory *> categories;
+public:
+ enum { CAT_MAGIC_ID = 10000 };
+
+ MenuMaker(KActionMenu *root);
+
+ void addCategory(const QString& name, const char *prefix);
+ MenuCategory *lookupCategoryByName(const QString& name);
+ void addItem(const char *name, int i);
+ QString basename(const QString& name);
+ QString catname(const QString& name);
+
+ void clear();
+
+ const char *findID(int id);
+
+ void menuActivated(const char *text);
+signals:
+ void activated(const char *text);
+};
+#endif
diff --git a/arts/builder/module.cpp b/arts/builder/module.cpp
new file mode 100644
index 00000000..250ee3a2
--- /dev/null
+++ b/arts/builder/module.cpp
@@ -0,0 +1,439 @@
+ /*
+
+ Copyright (C) 1998-1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include "module.h"
+#include "drawutils.h"
+#include <stdio.h>
+#include <arts/debug.h>
+
+#include <qpalette.h>
+#include <qdrawutil.h>
+#include <kiconloader.h>
+#include <algorithm>
+
+using namespace std;
+
+ModulePort::ModulePort(StructureComponent *owner, const string& description,
+ int drawsegment, Direction direction, Arts::PortDesc PortDesc)
+{
+ selected = false;
+
+ this->owner = owner; // whats the syntax for that again?
+ this->drawsegment = drawsegment;
+ this->direction = direction;
+ this->PortDesc = PortDesc;
+ this->description = description.c_str();
+
+ pdID = PortDesc.ID();
+
+ isinitarg = (PortDesc.type().connType == Arts::conn_property);
+ if(isinitarg) arts_debug("port %s is an init arg", (const char *)this->description.latin1());
+ arts_debug("port %s created", (const char *)this->description.latin1());
+ conntype = none;
+ route_owner = 0;
+}
+
+bool ModulePort::down()
+{
+ return (PortDesc.isConnected() || PortDesc.hasValue() || selected);
+}
+
+QColor ModulePort::color(bool isInterface)
+{
+ if(selected) return QColor(255, 165, 0);
+
+ if(PortDesc.hasValue())
+ {
+ if(isinitarg) return QColor(180, 180, 180);
+ return QColor(100, 100, 255);
+ }
+
+ if(isinitarg) return QColor(128, 128, 128);
+
+ if(isInterface) return QColor(100, 100, 100);
+ return QColor(43, 43, 168);
+}
+
+Module::Module(Arts::ModuleDesc module, Arts::StructureDesc structuredesc,
+ StructureCanvas *canvas) : StructureComponent(canvas)
+{
+ StructureDesc = structuredesc;
+ ModuleDesc = module;
+
+ _x = ModuleDesc.x();
+ _y = ModuleDesc.y();
+ initModule();
+}
+
+Module::Module(const Arts::ModuleInfo& minfo, Arts::StructureDesc structuredesc,
+ StructureCanvas *canvas) : StructureComponent(canvas)
+{
+ StructureDesc = structuredesc;
+ ModuleDesc = StructureDesc.createModuleDesc(minfo);
+
+ initModule();
+}
+
+void Module::initModule()
+{
+ QString iconname;
+ KIconLoader iconloader;
+
+ _selected = false;
+ _visible = false;
+ _height = 1;
+ _name = ModuleDesc.name().c_str();
+ _pixmap = NULL;
+
+// test if pixmap available
+
+ iconname = _name + ".xpm";
+
+ _pixmap = new QPixmap(iconloader.loadIcon(iconname, KIcon::User));
+ if(!_pixmap->height())
+ {
+ iconname = _name + ".png";
+ delete _pixmap;
+ _pixmap = new QPixmap( iconloader.loadIcon( iconname, KIcon::User ) );
+ if( !_pixmap->height() )
+ {
+ delete _pixmap;
+ _pixmap = 0;
+ }
+ }
+// try again without Arts:: - prefix
+
+ if(iconname.startsWith("Arts::"))
+ {
+ iconname = iconname.mid(6);
+
+ _pixmap = new QPixmap(iconloader.loadIcon(iconname, KIcon::User));
+ if(!_pixmap->height())
+ {
+ iconname.replace( iconname.length() - 4, 3, "png" );
+ delete _pixmap;
+ _pixmap = new QPixmap(iconloader.loadIcon(iconname, KIcon::User));
+ if( !_pixmap->height() )
+ {
+ delete _pixmap;
+ _pixmap = 0;
+ }
+ }
+ }
+/*
+ FILE *test = fopen(QFile::encodeName(iconname), "r");
+ if(test)
+ {
+ pixmap = new QPixmap(iconname);
+ fclose(test);
+ }
+*/
+
+// create lists with inports & outports for this module
+// and bind them to it ...
+
+ arts_debug("Getting ports...");
+ vector<Arts::PortDesc >*ports = ModuleDesc.ports();
+ unsigned long portpos;
+ long indraw = 1, outdraw = 2;
+
+ for(portpos = 0; portpos < ports->size(); portpos++)
+ {
+ Arts::PortDesc pd = (*ports)[portpos];
+ ModulePort *p;
+
+ arts_debug("CREATING %s", pd.name().c_str());
+ switch(pd.type().direction)
+ {
+ case Arts::input:
+ p = new ModulePort(this, pd.name(), indraw++,
+ ModulePort::in, pd);
+ inports.push_back(p);
+ break;
+ case Arts::output:
+ p = new ModulePort(this, pd.name(), outdraw++,
+ ModulePort::out, pd);
+ outports.push_back(p);
+ break;
+ default:
+ assert(false); // shouldn't happen!
+ }
+ }
+
+ delete ports;
+
+ _width = 1 + max(inports.size(), outports.size() + 1);
+
+ mdID = ModuleDesc.ID();
+ isInterface = ModuleDesc.isInterface();
+}
+
+Module::~Module()
+{
+ arts_debug("hide...");
+ hide();
+ arts_debug("sdfmd...");
+ list<ModulePort *>::iterator i;
+
+ for(i = inports.begin(); i != inports.end(); ++i) delete *i;
+ inports.clear();
+
+ for(i = outports.begin(); i != outports.end(); ++i) delete *i;
+ outports.clear();
+
+ StructureDesc.freeModuleDesc(ModuleDesc);
+ arts_debug("ok...");
+ delete _pixmap;
+}
+
+bool Module::moveInternal(int x, int y)
+{
+ return ModuleDesc.moveTo(x, y);
+}
+
+int Module::width() const
+{
+ return _width;
+}
+
+int Module::height() const
+{
+ return _height;
+}
+
+StructureComponent::ComponentType Module::type()
+{
+ return ctModule;
+}
+
+bool Module::drawNeedsBackground(int segment)
+{
+ return (segment == 0);
+}
+
+void Module::drawSegment(QPainter *p, int cellsize, int segment)
+{
+ int border = cellsize / 10; // for the logo
+ int ltop = (cellsize - border)/2;
+ int lbot = (cellsize + border)/2;
+
+ QColor mcolor(43, 43, 168);
+ QColor mcolorlight(164, 176, 242);
+
+ if(isInterface)
+ {
+ mcolor = QColor(100, 100, 100);
+ mcolorlight = QColor(160, 160, 160);
+ }
+ QColorGroup g( Qt::white, Qt::blue, mcolorlight, mcolor.dark(), mcolor,
+ Qt::black, Qt::black );
+ QBrush fill( mcolor );
+ QPen textpen(QColor(255, 255, 180), 1);
+
+ if(segment == 0)
+ {
+ qDrawShadePanel(p, border, border, cellsize - 2*border + 1, cellsize - 2*border + 1,
+ g, false, 1, &fill);
+ p->fillRect(cellsize - border - 1, ltop, cellsize, lbot - ltop + 1, fill);
+ p->setPen(g.light());
+ p->drawLine(cellsize - border, ltop - 1, cellsize, ltop - 1);
+ p->setPen(g.dark());
+ p->drawLine(cellsize - border, lbot + 1, cellsize, lbot + 1);
+ if(_pixmap)
+ {
+ int destsize = (cellsize - 4*border);
+ float sx = (float)destsize/(float)_pixmap->width();
+ float sy = (float)destsize/(float)_pixmap->height();
+
+ QWMatrix matrix;
+ matrix.scale(sx, sy);
+ QPixmap pmscaled = _pixmap->xForm(matrix);
+ p->drawPixmap(border*2, border*2, pmscaled);
+ }
+ return;
+ }
+
+ p->fillRect(0, 0, cellsize, cellsize, fill);
+
+ /*
+ * take care of the bevel lines around the module
+ */
+
+ p->setPen(g.light());
+ p->drawLine(0, 0, cellsize - 1, 0);
+ if(segment < 2)
+ p->drawLine(0, 0, 0, cellsize - 1);
+
+ p->setPen(g.dark());
+ p->drawLine(cellsize - 1, cellsize - 1, 0, cellsize - 1);
+ if(segment == 0 || segment == width() - 1)
+ p->drawLine(cellsize - 1, cellsize - 1, cellsize - 1, 0);
+
+ /*
+ * now draw the ports
+ */
+ int direction;
+
+ for(direction = 0;direction < 2; direction++)
+ {
+ ModulePort *port = findPort(segment, direction);
+
+ if(port)
+ {
+ int border = cellsize/7;
+ int textwidth;
+ QString label = DrawUtils::cropText(p, port->description,
+ cellsize/2, textwidth);
+
+ QBrush pbrush(port->color(isInterface));
+
+ port->clickrect = QRect(border, direction * cellsize/2 + border,
+ cellsize/2 - 2*border, cellsize/2 - 2*border);
+ qDrawShadePanel(p, port->clickrect, g, port->down(), 2, &pbrush);
+
+#if 0
+ QBrush fillport(fill);
+ if(port->isinitarg)
+ {
+ fillport = QColor(128, 128, 128);
+ }
+
+ if(port->selected)
+ {
+ QBrush fillorange(QColor(255, 165, 0));
+ qDrawShadePanel(p, port->clickrect, g, true, 2, &fillorange);
+ }
+ else
+ {
+ if(port->PortDesc->isConnected())
+ {
+ qDrawShadePanel(p, port->clickrect, g, true, 2, &fillport);
+ }
+ else if(port->PortDesc->hasValue())
+ {
+ QBrush fillp(QColor(100, 100, 255));
+ if(port->isinitarg)
+ {
+ fillp = QColor(180, 180, 180);
+ }
+ qDrawShadePanel(p, port->clickrect, g, true, 2, &fillp);
+ }
+ else // not connected and no value();
+ qDrawShadePanel(p, port->clickrect, g, false, 2, &fillport);
+ }
+#endif
+
+ p->setPen(textpen);
+ p->drawText((cellsize - border)/2,
+ (1 + direction) * (cellsize/2) - border, label);
+ }
+ }
+
+ /*
+ * if it was the rightmost part of the module, it has the module name
+ * and the connection to the logo as well
+ */
+
+ if(segment == 1)
+ {
+ // object type label
+ int textwidth;
+ QString label = DrawUtils::cropText(p, _name, cellsize - 4, textwidth);
+
+ p->setPen(textpen);
+ p->fillRect(1, cellsize - 16, textwidth + 7, 15, QBrush(g.dark()));
+ p->drawText(4, cellsize - 5, label);
+
+ // logo connection
+ p->setPen(mcolor);
+ p->drawLine(0, ltop, 0, lbot);
+ }
+
+ /*
+ * when selected, draw a line of white dots around the module
+ */
+
+ if(selected())
+ {
+ QPen pen(Qt::white, 1, Qt::DotLine);
+
+ p->setPen(pen);
+ p->drawLine(0, 0, cellsize - 1, 0);
+ p->drawLine(0, cellsize - 1, cellsize - 1, cellsize - 1);
+ if(segment == 1)
+ p->drawLine(0, 0, 0, cellsize - 1);
+ if(segment == _width - 1)
+ p->drawLine(cellsize - 1, 0, cellsize - 1, cellsize - 1);
+ }
+}
+
+ModulePort *Module::findPort(int xoffset, int direction)
+{
+ list<ModulePort *>*ports;
+ list<ModulePort *>::iterator i;
+
+ long n;
+
+ if(direction == 0) ports = &inports; else ports = &outports;
+
+ i = ports->begin();
+ n = xoffset - 1 - direction;
+
+ if(n < (long)ports->size() && n >= 0)
+ {
+ while(n > 0) { n--; i++; }
+ return (*i);
+ }
+ return(NULL);
+}
+
+ModulePort *Module::portAt(int segment, int x, int y)
+{
+ for(int direction = 0; direction < 2; direction++)
+ {
+ ModulePort *port = findPort(segment, direction);
+ if(port)
+ {
+ QPoint clickpoint(x, y);
+ if(port->clickrect.contains(clickpoint)) return port;
+ }
+ }
+ return 0;
+}
+
+void Module::dumpPorts(list<ModulePort *>& ports)
+{
+ list<ModulePort *>::iterator i;
+ for(i = inports.begin(); i != inports.end(); ++i) ports.push_back(*i);
+ for(i = outports.begin(); i != outports.end(); ++i) ports.push_back(*i);
+}
+
+QPixmap *Module::pixmap()
+{
+ return _pixmap;
+}
+
+QString Module::name()
+{
+ return _name;
+}
+
+// vim: sw=4 ts=4 noet
diff --git a/arts/builder/module.h b/arts/builder/module.h
new file mode 100644
index 00000000..ff19d44b
--- /dev/null
+++ b/arts/builder/module.h
@@ -0,0 +1,108 @@
+ /*
+
+ Copyright (C) 1998 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __MODULE_H_
+#define __MODULE_H_
+
+#include <list>
+
+#include <qpixmap.h>
+#include <qstring.h>
+#include <qrect.h>
+#include <ksimpleconfig.h>
+
+#include "artsbuilder.h"
+#include "scomponent.h"
+
+class ModulePort
+{
+ //ModulePort *connection;
+
+public:
+ Arts::PortDesc PortDesc;
+ long pdID;
+
+ enum ConnType {none, source, dest, value, conf};
+ enum Direction {in, out};
+
+ bool selected;
+ StructureComponent *owner;
+
+ QString description;
+ QRect clickrect;
+ ConnType conntype;
+ Direction direction;
+ int drawsegment;
+ bool isinitarg;
+
+ long route_owner;
+
+ ModulePort( StructureComponent *owner, const std::string& description,
+ int drawsegment, Direction direction, Arts::PortDesc PortDesc);
+
+ bool down();
+ QColor color(bool isInterface);
+};
+
+class Module :public StructureComponent
+{
+protected:
+ Arts::StructureDesc StructureDesc;
+ Arts::ModuleDesc ModuleDesc;
+
+ QPixmap *_pixmap;
+ QString _name;
+
+ int _width, _height;
+ bool moveInternal(int x, int y);
+
+ void initModule();
+
+public:
+ Module( Arts::ModuleDesc moduledesc, Arts::StructureDesc structuredesc,
+ StructureCanvas *canvas);
+ Module( const Arts::ModuleInfo& minfo, Arts::StructureDesc structuredesc,
+ StructureCanvas *canvas);
+ virtual ~Module();
+
+ ModulePort *findPort(int xoffset, int direction);
+
+ bool isInterface;
+
+ long mdID;
+ std::list<ModulePort *> inports, outports;
+
+// StructureComponent interface
+
+ int width() const;
+ int height() const;
+ ComponentType type();
+
+ ModulePort *portAt(int segment, int x, int y);
+ void dumpPorts(std::list<ModulePort *>& ports);
+
+ bool drawNeedsBackground(int segment);
+ void drawSegment(QPainter *dest, int cellsize, int segment);
+ QPixmap *pixmap();
+ QString name();
+ };
+
+#endif
diff --git a/arts/builder/mwidget.cpp b/arts/builder/mwidget.cpp
new file mode 100644
index 00000000..b6c3d841
--- /dev/null
+++ b/arts/builder/mwidget.cpp
@@ -0,0 +1,652 @@
+#include "mwidget.h"
+#include "autorouter.h"
+
+#include <arts/debug.h>
+
+//#include <kdebug.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+#include <qtimer.h>
+#include <qpainter.h>
+#include <qevent.h>
+
+#include "createtool.h"
+
+Structure *ModuleWidget::theStructure()
+{
+ return structure;
+}
+
+void ModuleWidget::addInterface ( const Arts::ModuleInfo& minfo )
+{
+ delete activeTool;
+ activeTool = new CreateInterfaceTool(this, minfo);
+}
+
+void ModuleWidget::addModule ( const Arts::ModuleInfo& minfo )
+{
+ delete activeTool;
+ activeTool = new CreateModuleTool(this, minfo);
+}
+
+void ModuleWidget::addPort ( const Arts::PortType& type )
+{
+ delete activeTool;
+ activeTool = new CreatePortTool(this, type);
+}
+
+StructurePort *ModuleWidget::insertPort( const Arts::PortType& type, int x, int y )
+{
+ StructurePort *port = structure->createStructurePort(type);
+ unselectAll();
+ port->move(x, y);
+ port->setSelected(true);
+ port->show();
+
+ return port;
+}
+
+void ModuleWidget::leaveTool(MWidgetTool *tool, bool wasModified)
+{
+ assert(tool == activeTool);
+ delete tool;
+ activeTool = 0;
+ if(wasModified)
+ emit modified(wasModified);
+}
+
+QPoint ModuleWidget::componentPos(const StructureComponent *component) const
+{
+ int cellx = 0, celly = 0;
+ colXPos(component->x(), &cellx);
+ rowYPos(component->y(), &celly);
+
+ return QPoint(cellx, celly);
+}
+
+QPoint ModuleWidget::portPos(const ModulePort *port) const
+{
+ int cellx = 0, celly = 0;
+ colXPos(port->owner->x() + port->drawsegment, &cellx);
+ rowYPos(port->owner->y(), &celly);
+
+ return QPoint(cellx, celly);
+}
+
+bool ModuleWidget::insertModule( Module *newModule )
+{
+ if(hasSpace(newModule, newModule->x(), newModule->y(), true))
+ {
+ newModule->show();
+ reRoute();
+ return true;
+ }
+ return false;
+}
+
+void ModuleWidget::findAt(int windowX, int windowY,
+ StructureComponent *&component, ModulePort *&port)
+{
+ int x = findCol(windowX);
+ int y = findRow(windowY);
+
+ component = structure->componentAt(x, y, false);
+
+ if(component)
+ {
+ int cellx = 0, celly = 0;
+ colXPos(x, &cellx);
+ rowYPos(y, &celly);
+
+ port = component->portAt(x - (component->x()),
+ windowX - cellx, windowY - celly);
+ }
+ else
+ port = 0L;
+}
+
+void ModuleWidget::selectComponent( StructureComponent *component, bool onlyThis )
+{
+ beginUpdate();
+ if(onlyThis)
+ unselectAll();
+
+ if(!(component->selected()))
+ {
+ component->setSelected(true);
+ emit componentSelected(component);
+ } else
+ if(!onlyThis)
+ {
+ component->setSelected(false);
+ emit componentSelected(0L);
+ }
+ endUpdate();
+}
+
+void ModuleWidget::mousePressEvent( QMouseEvent *e )
+{
+ if(activeTool)
+ {
+ activeTool->mousePressEvent(e);
+ return;
+ }
+
+ if( e->button() == LeftButton )
+ {
+ StructureComponent *component;
+ ModulePort *port;
+ findAt(e->x(), e->y(), component, port);
+
+ if(component)
+ {
+ if(port)
+ {
+ // user clicked in port
+ selectPort(port);
+
+ delete activeTool;
+ activeTool = new ConnectPortsTool(this, port);
+ }
+ else
+ {
+ // user clicked in component
+ activeTool = new MoveComponentsTool(this, e);
+
+ // maintain selected group when pressing the shift or control button
+ selectComponent(component, !((e->state() & ControlButton)
+ || (e->state() & ShiftButton)));
+ }
+ }
+ else
+ {
+ // unselect all if user clicks on background (without shift)
+ if(!(e->state() & ShiftButton))
+ {
+ beginUpdate();
+ unselectAll();
+ endUpdate();
+ }
+ }
+ }
+}
+
+void ModuleWidget::mouseMoveEvent( QMouseEvent *e )
+{
+ if(activeTool)
+ {
+ activeTool->mouseMoveEvent(e);
+ return;
+ }
+}
+
+void ModuleWidget::mouseReleaseEvent( QMouseEvent *e )
+{
+ if(activeTool)
+ {
+ activeTool->mouseReleaseEvent(e);
+ return;
+ }
+}
+
+// may be called with port == 0
+void ModuleWidget::selectPort( ModulePort *port, bool newMode )
+{
+ beginUpdate();
+
+ if(selectedPort && (selectedPort!= port))
+ {
+ // unselect previous
+ selectedPort->selected = false;
+ selectedPort->owner->redraw();
+ if(selectedPort->owner->selected())
+ emit componentSelected(selectedPort->owner);
+ else
+ emit portSelected(0L);
+ selectedPort = 0L;
+ }
+
+ if(port)
+ {
+ port->selected = newMode;
+ selectedPort = port;
+ selectComponent(selectedPort->owner);
+ selectedPort->owner->redraw();
+ }
+ emit portSelected(port); // FIXME: should be "portSelectionChanged"
+
+ endUpdate();
+}
+
+void ModuleWidget::startConnection( ModulePort *port )
+{
+ delete activeTool;
+ activeTool = new ConnectPortsTool(this, port);
+}
+
+void ModuleWidget::portPropertiesChanged( ModulePort *port )
+{
+ reRoute();
+}
+
+bool ModuleWidget::hasSpace(StructureComponent *c, int destx, int desty,
+ bool ignore_selected)
+{
+ if((destx < 0) || (desty < 0))
+ return false;
+ if((destx + c->width() > numCols()) || (desty + c->height() > numRows()))
+ return false;
+
+ for(int ddx = 0; ddx < c->width(); ddx++)
+ {
+ for(int ddy = 0; ddy < c->height(); ddy++)
+ {
+ if(structure->componentAt(destx + ddx, desty + ddy, ignore_selected))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void ModuleWidget::paintCellBackground(QPainter *p, int y, int x)
+{
+ QColor bgcolor;
+
+ if((y & 1) == 1)
+ bgcolor = QColor(168, 168, 168);
+ else
+ bgcolor = QColor(146, 168, 146);
+
+ p->fillRect(0, 0, cellsize, cellsize, QBrush(bgcolor));
+
+ p->setPen(bgcolor.dark(115));
+ p->drawLine(0, 0, 0, cellsize - 1);
+ p->drawLine(0, 0, cellsize - 1, 0);
+
+ if(x == (numCols() - 1))
+ p->drawLine(cellsize - 1, 0, cellsize - 1, cellsize - 1);
+ if(y == (numRows() - 1))
+ p->drawLine(0, cellsize - 1, cellsize - 1, cellsize - 1);
+}
+
+void ModuleWidget::unselectAll()
+{
+ setSelectAll(false);
+}
+
+void ModuleWidget::setSelectAll(bool newstate)
+{
+ std::list<StructureComponent *>::iterator module;
+
+ for(module = structure->getComponentList()->begin();
+ module != structure->getComponentList()->end(); module++)
+ {
+ (*module)->setSelected(newstate);
+ }
+}
+
+void ModuleWidget::beginUpdate()
+{
+ updateDepth++;
+}
+
+void ModuleWidget::endUpdate()
+{
+ if(!--updateDepth)
+ {
+ std::list<QRect>::iterator i;
+
+ for(i = UpdateList.begin(); i != UpdateList.end(); i++)
+ {
+ redrawCells(*i);
+ }
+
+ UpdateList.clear();
+ }
+}
+
+void ModuleWidget::redrawRect(int x, int y, int width, int height)
+{
+ QRect r = QRect(x, y, width, height);
+
+ if(!updateDepth)
+ {
+ redrawCells(r);
+ }
+ else
+ {
+ UpdateList.push_back(r);
+ }
+}
+
+void ModuleWidget::redrawCells(QRect &r)
+{
+ int x, y;
+
+ for(x = r.left(); x <= r.right(); x++)
+ {
+ for(y = r.top(); y <= r.bottom(); y++)
+ {
+ updateCell(y, x, false);
+ }
+ }
+}
+
+
+void ModuleWidget::reRoute()
+{
+// clear everything
+ autorouter->clear();
+
+// add structure components (external ports/modules) to the router, so that
+// cables won't be drawn over them
+
+ std::list<StructureComponent *>::iterator c;
+ std::list<ModulePort *> portlist;
+
+ for(c = structure->getComponentList()->begin();
+ c != structure->getComponentList()->end(); c++)
+ {
+ StructureComponent *sc = *c;
+ autorouter->set(sc->x()*2, sc->y()*2,
+ (sc->x() + sc->width())*2 - 1,
+ (sc->y() + sc->height())*2 - 1, AutoRouter::solid);
+
+ sc->dumpPorts(portlist);
+ }
+
+ std::list<ModulePort *>::iterator pi;
+
+// build a map with all input ports to find corresponding ports of connections
+
+ std::map<long, ModulePort *> portmap;
+
+ for(pi = portlist.begin(); pi != portlist.end(); ++pi)
+ {
+ ModulePort *port = *pi;
+
+ if(port->direction == ModulePort::in) portmap[port->pdID] = port;
+ }
+
+// add connections to the router
+
+ /*
+ * assign colors after the following algorithm:
+ *
+ * - initialize assuming that each port has its own color
+ * - if two ports are connected, they must have the same color, that
+ * is, all references to the two colors must be made the same
+ *
+ * these colors are not used for drawing, but for making lines of
+ * different groups of ports not collide in the autorouter (ownership)
+ */
+ std::map<ModulePort *, long> color;
+ vector<long> owner(portlist.size());
+
+ long maxcolor = 0;
+ for(pi = portlist.begin(); pi != portlist.end(); ++pi)
+ color[*pi] = maxcolor++;
+
+ for(pi = portlist.begin(); pi != portlist.end(); ++pi)
+ {
+ ModulePort *src = *pi;
+ unsigned long c;
+ if(src->direction == ModulePort::out && src->PortDesc.isConnected())
+ {
+ vector<Arts::PortDesc> *conn = src->PortDesc.connections();
+
+ for(c = 0; c < conn->size(); c++)
+ {
+ ModulePort *dest = portmap[(*conn)[c].ID()];
+ long color_src = color[src];
+ long color_dest = color[dest];
+
+ if(color_src != color_dest)
+ {
+ std::list<ModulePort *>::iterator pi2;
+
+ for(pi2 = portlist.begin(); pi2 != portlist.end(); pi2++)
+ {
+ ModulePort *p = *pi2;
+
+ if(color[p] == color_dest) color[p] = color_src;
+ }
+ }
+ }
+ }
+ }
+
+ for(pi = portlist.begin(); pi != portlist.end(); ++pi)
+ {
+ ModulePort *p = *pi;
+
+ if(p->direction == ModulePort::out && p->PortDesc.isConnected())
+ {
+ ModulePort *src = p, *dest;
+ long& route_owner = owner[color[src]];
+ unsigned long c;
+
+ vector<Arts::PortDesc> *conn = p->PortDesc.connections();
+
+ for(c = 0; c < conn->size(); c++)
+ {
+ dest = portmap[(*conn)[c].ID()];
+ if(dest) // otherwise something bad has happend?
+ {
+/*
+ arts_debug("autoroute add connection port %s.%s to %s.%s",
+ src->owner->type.local8Bit().data(),src->description.local8Bit().data(),
+ dest->owner->type.local8Bit().data(),dest->description.local8Bit().data());
+*/
+
+ int x1 = (src->owner->x() + src->drawsegment)*2;
+ int y1 = src->owner->y()*2 + 1;
+
+ int x2 = (dest->owner->x() + dest->drawsegment)*2;
+ int y2 = dest->owner->y()*2;
+
+ route_owner = autorouter->connect(x1, y1, x2, y2, route_owner);
+ }
+ }
+
+ delete conn;
+ }
+ }
+
+ autorouter->sync();
+}
+
+void ModuleWidget::redrawAll()
+{
+// redraw everything
+ QRect updaterect(0, 0, cols, rows);
+ redrawCells(updaterect);
+}
+
+void ModuleWidget::paintConnection(QPainter *p, int x, int y, int arx, int ary)
+{
+ long linetype = autorouter->get(arx, ary);
+ long ud_owner = -1, lr_owner = -1, lr_break = 0, ud_break = 0;
+
+ autorouter->getowners(arx, ary, ud_owner, lr_owner);
+
+ p->setPen(QColor(255, 255, 255));
+
+/*
+ if(linetype == AutoRouter::none)
+ {
+ p->drawPoint(x + cellsize/4, y + cellsize/4);
+ }
+ if(linetype & AutoRouter::solid)
+ {
+ QBrush whitefill(QColor(255, 255, 255));
+
+ p->fillRect(x + cellsize/6, y + cellsize/6, cellsize/6, cellsize/6, whitefill);
+ }
+*/
+ x += cellsize/4;
+ y += cellsize/4;
+
+ // both used?
+ if(ud_owner != -1 && lr_owner != -1)
+ {
+ // and not of the same owner?
+ if(ud_owner != lr_owner)
+ {
+ // then we'll have to paint one of them broken
+ if(ud_owner > lr_owner)
+ lr_break = cellsize/8;
+ else
+ ud_break = cellsize/8;
+ }
+ }
+
+ if(linetype & AutoRouter::left)
+ p->drawLine(x - cellsize/4, y, x - lr_break, y);
+ if(linetype & AutoRouter::right)
+ p->drawLine(x + cellsize/4, y, x + lr_break, y);
+ if(linetype & AutoRouter::up)
+ p->drawLine(x, y - cellsize/4, x, y - ud_break);
+ if(linetype & AutoRouter::down)
+ p->drawLine(x, y + cellsize/4, x, y + ud_break);
+}
+
+void ModuleWidget::paintConnections(QPainter *p, int y, int x)
+{
+ // paints connections in the given 2x2-autorouter-block being a 1x1 block to the user
+ for(int dx = 0; dx < 2; dx++)
+ for(int dy = 0; dy < 2; dy++)
+ paintConnection(p, (cellsize*dx)/2, (cellsize*dy)/2, x*2 + dx, y*2 + dy);
+}
+
+void ModuleWidget::paintCell(QPainter *p, int y, int x)
+{
+#if 0 /* PORT */
+ if(theArtsBuilderApp->eventStackDepth() > 1)
+ {
+ // FIXME: set some redraw flag or something like that
+ return;
+ }
+#endif
+
+ std::list<StructureComponent *>::iterator c;
+ for(c = structure->getComponentList()->begin();
+ c != structure->getComponentList()->end(); c++)
+ {
+ StructureComponent *mwc = *c;
+ if(y == mwc->y() && mwc->visible())
+ {
+ int xoffset = x - mwc->x();
+
+ if(xoffset >= 0 && xoffset < mwc->width())
+ {
+ if(mwc->drawNeedsBackground(xoffset))
+ paintCellBackground(p, y, x);
+
+ mwc->drawSegment(p, cellsize, xoffset);
+ paintConnections(p, y, x);
+ return;
+ }
+ }
+ }
+ paintCellBackground(p, y, x);
+ paintConnections(p, y, x);
+}
+
+// ---------------------------------------------------------------------------
+// public part of modulewidget
+// ---------------------------------------------------------------------------
+
+void ModuleWidget::setZoom(int zoom)
+{
+ cellsize = (int)(50.0 * (float)zoom/100);
+
+ setCellHeight(cellsize);
+ setCellWidth(cellsize);
+ updateTableSize();
+ resize(cellsize*cols, cellsize*rows);
+}
+
+void ModuleWidget::selectAll()
+{
+ setSelectAll(true);
+}
+
+void ModuleWidget::reInit()
+{
+ emit componentSelected(0);
+ selectedPort = 0L;
+
+ delete activeTool;
+ activeTool = 0L;
+
+ reRoute();
+}
+
+void ModuleWidget::delModule()
+{
+ int numSelected = structure->countSelected();
+
+ if(!numSelected) return;
+
+ if(KMessageBox::warningContinueCancel(0,
+ i18n("Delete %n selected module, port or connection? (No undo possible.)",
+ "Delete %n selected modules, ports and connections? (No undo possible.)",
+ numSelected), QString::null, i18n("&Delete")) == KMessageBox::Continue)
+ {
+ selectPort(0L);
+ emit componentSelected(0);
+ structure->deleteSelected();
+ reRoute();
+ }
+}
+
+void ModuleWidget::autoRedrawRouter()
+{
+ if(autorouter->needRedraw()) redrawAll();
+}
+
+ModuleWidget::ModuleWidget(Structure *structure, QWidget *parent, const char *name, WFlags f)
+ : QtTableView( parent, name, f),
+ updateDepth( 0 ),
+ activeTool( 0L ),
+ structure( structure ),
+ selectedPort( 0L )
+{
+ arts_debug("PORT: mw; getmodulelist");
+ this->ModuleList = structure->getModuleList();
+ arts_debug("PORT: mw; cols&rows");
+
+ cols = 24;
+ rows = 32;
+
+ setNumCols(cols);
+ setNumRows(rows);
+ setTableFlags(Tbl_autoScrollBars);
+ setZoom(100);
+
+ setFocusPolicy( NoFocus );
+
+ arts_debug("PORT: mw; bgmode");
+ setBackgroundMode(NoBackground);
+
+ arts_debug("PORT: mw; new ar %d,%d", cols, rows);
+ autorouter = new AutoRouter(cols*2, rows*2);
+
+ arts_debug("PORT: mw; new ar ok - qtimer");
+ QTimer *timer = new QTimer( this );
+ connect( timer, SIGNAL(timeout()),
+ this, SLOT(autoRedrawRouter()) );
+
+ arts_debug("PORT: mw; tstart");
+ timer->start( 100, FALSE ); // 100 ms reoccurring check
+}
+
+ModuleWidget::~ModuleWidget()
+{
+ delete autorouter;
+}
+
+#include "mwidget.moc"
diff --git a/arts/builder/mwidget.h b/arts/builder/mwidget.h
new file mode 100644
index 00000000..e6716e3e
--- /dev/null
+++ b/arts/builder/mwidget.h
@@ -0,0 +1,129 @@
+ /*
+
+ Copyright (C) 1999 Stefan Westerfeld <stefan@space.twc.de>,
+ Hans Meine <hans_meine@gmx.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef MWIDGET_H
+#define MWIDGET_H
+
+#include "structure.h"
+#include "module.h"
+#include "scomponent.h"
+
+#include "qttableview.h"
+
+class AutoRouter;
+class MWidgetTool;
+
+class ModuleWidget :public QtTableView, public StructureCanvas
+{
+ Q_OBJECT
+ friend class MWidgetTool;
+ friend class CreateTool;
+ friend class CreateInterfaceTool;
+ friend class CreateModuleTool;
+ friend class CreatePortTool;
+ friend class MoveComponentsTool;
+ friend class ConnectPortsTool;
+
+protected:
+ int cellsize, cols, rows;
+ int updateDepth;
+
+ MWidgetTool *activeTool;
+ AutoRouter *autorouter;
+ Structure *structure;
+
+// for connecting ports
+
+ ModulePort *selectedPort;
+
+ std::list<Module *> *ModuleList;
+ std::list<QRect> UpdateList;
+
+ void paintCell(QPainter *p, int y, int x);
+ void paintCellBackground(QPainter *p, int y, int x);
+ void paintConnection(QPainter *p, int x, int y, int arx, int ary);
+ void paintConnections(QPainter *p, int y, int x);
+ void mousePressEvent( QMouseEvent *e );
+ void mouseMoveEvent( QMouseEvent *e );
+ void mouseReleaseEvent( QMouseEvent *e );
+
+ bool hasSpace(StructureComponent *c, int destx, int desty,
+ bool ignore_selected = false);
+
+ void reRoute();
+ void setSelectAll(bool newstate);
+
+ void beginUpdate();
+ void redrawCells(QRect &r);
+ void redrawAll();
+ void endUpdate();
+
+// for StructureComponents:
+
+ void redrawRect(int x, int y, int width, int height);
+
+// for CreateTool:
+
+ bool insertModule(Module *newModule);
+ StructurePort *insertPort(const Arts::PortType& type, int x, int y);
+
+// for this and ConnectTool:
+
+ void findAt(int windowX, int windowY,
+ StructureComponent *&component,
+ ModulePort *&port);
+
+signals:
+ void portSelected( ModulePort * );
+ void componentSelected( StructureComponent * );
+ void modified(bool); // the bool mod. flag is always true for easier connects
+
+public:
+ Structure *theStructure();
+
+ void addModule(const Arts::ModuleInfo& minfo);
+ void addInterface(const Arts::ModuleInfo& minfo);
+ void addPort(const Arts::PortType& type);
+ void reInit();
+ void leaveTool(MWidgetTool *tool, bool wasModified= false);
+
+ QPoint componentPos(const StructureComponent *component) const;
+ QPoint portPos(const ModulePort *port) const;
+
+ ModuleWidget( Structure *structure, QWidget *parent = 0,
+ const char *name = 0, WFlags f = 0);
+
+ ~ModuleWidget();
+
+public slots:
+ void autoRedrawRouter();
+ void setZoom(int zoom);
+ void delModule();
+ void selectAll();
+ void unselectAll();
+
+ void selectPort( ModulePort *port, bool newMode = true );
+ void selectComponent( StructureComponent *component, bool onlyThis = true );
+ void startConnection( ModulePort * );
+ void portPropertiesChanged( ModulePort *port );
+};
+
+#endif // MWIDGET_H
diff --git a/arts/builder/pics/Makefile.am b/arts/builder/pics/Makefile.am
new file mode 100644
index 00000000..26e29f8f
--- /dev/null
+++ b/arts/builder/pics/Makefile.am
@@ -0,0 +1,24 @@
+# this 10 paths are KDE specific. Use them:
+# kde_htmldir Where your docs should go to. (contains lang subdirs)
+# kde_appsdir Where your application file (.kdelnk) should go to.
+# kde_icondir Where your icon should go to.
+# kde_minidir Where your mini icon should go to.
+# kde_datadir Where you install application data. (Use a subdir)
+# kde_locale Where translation files should go to.(contains lang subdirs)
+# kde_cgidir Where cgi-bin executables should go to.
+# kde_confdir Where config files should go to.
+# kde_mimedir Where mimetypes should go to.
+# kde_toolbardir Where general toolbar icons should go to.
+# kde_wallpaperdir Where general wallpapers should go to.
+
+pix_DATA = Synth_ADD.xpm Synth_ATAN_SATURATE.xpm Synth_BUS_DOWNLINK.xpm \
+ Synth_BUS_UPLINK.xpm Synth_DEBUG.xpm Synth_ENVELOPE_ADSR.xpm \
+ Synth_FILEPLAY.xpm Synth_MIDI_DEBUG.xpm Synth_MUL.xpm Synth_PLAY.xpm \
+ Synth_PLAY_WAV.xpm Synth_PSCALE.xpm Synth_SEQUENCE.xpm Synth_WAVE_SAW.xpm \
+ Synth_WAVE_SIN.xpm Synth_WAVE_SQUARE.xpm Synth_WAVE_TRI.xpm Synth_XFADE.xpm \
+ Synth_MOOG_VCF.xpm Synth_RC.xpm Synth_SHELVE_CUTOFF.xpm Synth_MULTI_ADD.xpm \
+ Synth_AMAN_PLAY.xpm Synth_SEQUENCE_FREQ.png Synth_DIV.xpm
+
+pixdir = $(kde_datadir)/artsbuilder/pics/
+
+KDE_ICON = artsbuilder action-artsbuilderexecute
diff --git a/arts/builder/pics/Synth_ADD.xpm b/arts/builder/pics/Synth_ADD.xpm
new file mode 100644
index 00000000..d3ff5f82
--- /dev/null
+++ b/arts/builder/pics/Synth_ADD.xpm
@@ -0,0 +1,305 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 234 2",
+/* colors */
+" c #535B83",
+" . c #34427F",
+" X c #DBDDE4",
+" o c #303C7B",
+" O c #2E3A79",
+" + c #4A517A",
+" @ c #2C3877",
+" # c #4D589E",
+" $ c #2C356D",
+" % c #354283",
+" & c #B8BAC8",
+" * c #334081",
+" = c #1E2869",
+" - c #283476",
+" ; c #3F4A7C",
+" : c #475591",
+" > c #37437E",
+" , c #232E71",
+" < c #202A6E",
+" 1 c #43518D",
+" 2 c #1F2A6D",
+" 3 c #1E286C",
+" 4 c #1D286B",
+" 5 c #2B367C",
+" 6 c #46517C",
+" 7 c #4D5D9A",
+" 8 c #1A235E",
+" 9 c #394783",
+" 0 c #485795",
+" q c #27316E",
+" w c #465593",
+" e c #525A81",
+" r c #515A80",
+" t c #34417E",
+" y c #323F7C",
+" u c #212B68",
+" i c #606BB3",
+" p c #2E3978",
+" a c #252F6F",
+" s c #344181",
+" d c #323F7F",
+" f c #303D7D",
+" g c #2F3B7C",
+" h c #2D397A",
+" j c #3D498D",
+" k c #293576",
+" l c #283375",
+" z c #232D70",
+" x c #202B6D",
+" c c #53649F",
+" v c #1E296B",
+" b c #B2B5C4",
+" n c #1D276A",
+" m c #2D377D",
+" M c #2B377B",
+" N c #4E5E9A",
+" B c #2A357A",
+" V c #293379",
+" C c #283378",
+" Z c #979AB0",
+" A c #4B5A97",
+" S c #495895",
+" D c #485894",
+" F c #475693",
+" G c #455491",
+" H c #43528F",
+" J c #33407C",
+" K c #C5C8D3",
+" L c #30396F",
+" P c #3F4B81",
+" I c #717591",
+" U c #313E7D",
+" Y c #202A69",
+" T c #D7D9E1",
+" R c #D6D7E0",
+" E c #2C3878",
+" W c #273273",
+" Q c #48529A",
+" ! c #253071",
+" ~ c #6A6F8D",
+" ^ c #232E6F",
+" / c #3A4475",
+" ( c #434E95",
+" ) c #B6B8C7",
+" _ c #35417A",
+" ` c #212C6D",
+" ' c #202A6C",
+" ] c #232D65",
+" [ c #1F2A6B",
+" { c #374072",
+" } c #2C387B",
+" | c #1C2668",
+". c #9A9DB2",
+".. c #3B468D",
+".X c #29336E",
+".o c #384580",
+".O c #232E72",
+".+ c #465591",
+".@ c #333E85",
+".# c #212C70",
+".$ c #384276",
+".% c #202A6F",
+".& c #323F7A",
+".* c #2F3A81",
+".= c #1E286D",
+".- c #777C96",
+".; c #404F8B",
+".: c #3E4D89",
+".> c #3D4B88",
+"., c #A9ACBD",
+".< c #6671BA",
+".1 c #313D7C",
+".2 c #4D547D",
+".3 c #D9DAE2",
+".4 c #2F3B7A",
+".5 c #D6D8DF",
+".6 c #2D3978",
+".7 c #D5D6DE",
+".8 c #2C3777",
+".9 c #2B3776",
+".0 c #2B3576",
+".q c #283373",
+".w c None",
+".e c #242F6F",
+".r c #444F95",
+".t c #222D6D",
+".y c #EEEFF3",
+".u c #B4B7C4",
+".i c #404B91",
+".p c #1D2768",
+".a c #2B3779",
+".s c #3C478D",
+".d c #333B6D",
+".f c #2A3578",
+".g c #293577",
+".h c #7E839C",
+".j c #36427D",
+".k c #333D84",
+".l c #303B81",
+".z c #1F296D",
+".x c #42508C",
+".c c #1E296C",
+".v c #51629E",
+".b c #2E397F",
+".n c #51609E",
+".m c #1D276B",
+".M c #404E8A",
+".N c #2A357B",
+".B c #4C5C99",
+".V c #29337A",
+".C c #4A5A97",
+".Z c #364280",
+".A c #9094AA",
+".S c #303C7A",
+".D c #1D2664",
+".F c #5D68B0",
+".G c #293473",
+".H c #273271",
+".J c #5762AA",
+".K c #334080",
+".L c #323E7F",
+".P c #45538B",
+".I c #303C7D",
+".U c #2B3678",
+".Y c #1B2465",
+".T c #2A3677",
+".R c #3C4982",
+".E c #273274",
+".W c #384288",
+".Q c #263273",
+".! c #263073",
+".~ c #253072",
+".^ c #171F57",
+"./ c #222C6F",
+".( c #B5B8C7",
+".) c #313C81",
+"._ c #1E286B",
+".` c #2D387D",
+".' c #343E70",
+".] c #1C2669",
+".[ c #4F5F9B",
+".{ c #2C367C",
+".} c #293479",
+".| c #2C3772",
+"X c #979BB0",
+"X. c #4B5B97",
+"XX c #273277",
+"Xo c #4A5996",
+"XO c #9499AD",
+"X+ c #253075",
+"X@ c #475793",
+"X# c #222C72",
+"X$ c #445390",
+"X% c #1F2A6F",
+"X& c #42518E",
+"X* c #787E98",
+"X= c #727692",
+"X- c #2B3574",
+"X; c #555FA7",
+"X: c #232D6C",
+"X> c #2F3B7B",
+"X, c #515BA3",
+"X< c #4B527C",
+"X1 c #293575",
+"X2 c #3A4589",
+"X3 c #4A559C",
+"X4 c #263172",
+"X5 c #465198",
+"X6 c #B7B9C8",
+"X7 c #424D94",
+"X8 c #1F296B",
+"X9 c #2D397C",
+"X0 c #1D2769",
+"Xq c #2A3579",
+"Xw c #454E79",
+"Xe c #3B4883",
+"Xr c #273376",
+"Xt c #38438A",
+"Xy c #273176",
+"Xu c #364188",
+"Xi c #9498AC",
+"Xp c #3C477A",
+"Xa c #242F73",
+"Xs c #475692",
+"Xd c #343F86",
+"Xf c #36427E",
+"Xg c #323D84",
+"Xh c #212B70",
+"Xj c #44528F",
+"Xk c #43528E",
+"Xl c #1F296E",
+"Xz c #323E7A",
+"Xx c #1E296D",
+"Xc c #41508C",
+/* pixels */
+".w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.!XX C V CXyX+XaX# < v.p.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.|.1.WXuXg.* m 5.VXXX+X+.OX#.#Xh.%.z 8 8.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.>.r.i.sXtXuXg.* m 5.VXXX+X+.OX#.#Xh.%X%XlXl._ 8.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w > # # Q.r.i.sXtXdXg.* m.N CXXX+Xa.OX#.#Xh.%X%XlXx.=.= 3.] 8.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.wX;.JX, # Q (.i..XtXdXg.b m.N CXXX+Xa.OX#XhXh.%XlXlXx.= 3 3 3.m |.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.w.w.w.w A i.FX;X, # Q (.i...WXdXg.b 5.}Xy.! , ,X#XhXhXh.%XlXlXx.= 3 3 4.m.m.] 8.w.w.w.w.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.w.w.w.<.<.F.JX;X,X3X5X7 j..Xu.@.).` 5 C.! ! a z.#XhXh.%.%XlXlXx.= 3 3.m.m.m n n |.w.w.w.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.w.P.<.< i.F.JX; #X3X5.i jXtXu.k.l m.f.|.' {Xp $ u '.%XlX%Xl.z.= 3 3 3.m.m n n n n |.^.w.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.wXo.<.<.< i.JX;X, # Q (.i.sXtXuXg.* }.0 { ~.hXw q u <XlXlXlXx.= 3 3 4.m.m n n nX0.] |.^.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w A.<.<.< i.F.JX;X,X3X5X7.i...WXdXg.b.U.0 ;.-.A., $ u 2.zXlXlXx.= 3 3 4.m.m n n nX0.].] |.^.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.wXo.<.<.< i.F.JX;X, # Q.r.i.sXtXu.k.l.b.U.0X<XO b.7 ~.d ] '.zXl.zXx 3 3 4.m.m n n nX0.].].] |.Y.^.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.P.<.<.< i.F.J.JX, #X3X5X7.i...WXdXg.*.`.f.0.2X .u.7 I.d ].z.cXl.z.= 3 3 3._.m.m n n nX0X0.] | |.Y.^.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.<.<.< i.F.F.JX;X,X3 Q.r.i.sXtXu.@.).b m.g.G.2. &.3X=.d ].z.cXl.zXxXx 3.c.c.c._._._._._ nX0X0 | |.Y.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.<.<.< i.F.J.JX;X, # Q.rX7.i...WXdXg.l.` 5Xr.G.2. &.3X=.d ].z.z < < < < < < < < < < ' '.zX8._._._X0.p.Y.w.w.w.w.w.w",
+".w.w.w.w.w A.< i i.F.J.JX;X, # QX5X7.i.sXtXu.k.).b m.N l.qX<. &.3X=.d ] x <.#.#.#.#.#.#././.# ` ` ` ` x ' 'X8X8 v = 8.w.w.w.w.w",
+".w.w.w.w.w i.F.F.J.JX;X,X, # QX5X7.i.sX2XuXdXg.*.` 5.}.E.HX<. X6.3 I.d ] `./ , , , , , , , , , , z z./.t./ ` ` ' ' [ =.w.w.w.w.w",
+".w.w.w.wX;.F.J.JX;X;X, #X3 QX5X7.i.sX2.WXdXg.l.b.{.N V.!.HX<X ).3X=.d q , ,XaXaXaXa.!.!.!.~.~.~ , , ,.e , ^ ^.t ` ' ' =.w.w.w.w",
+".w.w.w >.JX;X;X;X,X, #X3 Q.rX7.i.s...WXd.k.).b m.N.} C.~.HX<X X6.3X=.d q ,.~.!.!.!.!.!.!.E.E.E.Q.!.!X4.~ ! !.e.e ^.t ` `.D.w.w.w",
+".w.w.w #X,X,X, # #X3 QX5.rX7.i.sX2.WXd.k.).b.` 5 B CXX.!.HX<X X6.3X=.'.X.!.!XrXrXrXrXrXrXr - - l l.q.E.E WX4X4 ! a.e ^X: Y.w.w.w",
+".w.w.w # # #X3X3 QX5.rX7.i.i.sX2.WXd.k.).*.`.{ B VXXXX.!.qX<X ) TX=.'.X.E l.g.g.f.f.f.f.f.f.g.g k k -X1.q.q.q WX4 ! !.e ^.w.w.w",
+".w.w.> Q Q QX5X5 (X7.i.i.s..XtXuXd.k.).*.`.{ B V CXXXX.Q.GX<X X6.3X= { $X1.gXq.U.a.a.a.a.a.a.a.U.U.U.U.T.0X1X1.q.q W.H ! a ].w.w",
+".w.w.r.r ( (X7.i.i.i.s..Xt.WXuXdXg.).b.`.{.N V C C C C.E.GX<X ).3X= { $.T.U } } }X9X9X9X9X9 h h h.6 E E.U.9.U.0X1.G.q WX4 a.w.w",
+".w.|.i.i.i.i j j.s..Xt.WXuXd.kXg.l.b.`.{ B V C C C C.} l.G.2X X6.3X= { $ E }X9X9X9X9 g g g g g gX>X> O h.6.6 E.8.0X1X1.G.q.H ].w",
+".w.1.s.s......XtXt.WXuXd.@Xg.).*.b m 5 B V C C C V.}XqX1X-.2X ).3X= / L hX9 g.I.I.I.I f f f.I.I.I.I g gX> O O.6 E.8.0X1.G.q ].w",
+".w.WXtXtXt.WXuXuXuXd.kXg.).l.b.`.{.N B V C C C V.}Xq B -.9.2X ).3.- / LX> g f.L.L.L.L.L d.L.L.L.L U U U f.IX>.4 O.6 @.9.0X-.H.w",
+".wXuXuXdXdXd.@.kXgXg.l.*.b.` m 5.N.} CXXXX C C.}Xq B B.0 @.2X ).3.- / L g f.L d * * * * * s * *.K.K d d.L U.1.IX>.4 O.6 @.0X-.w",
+".!XgXgXgXgXg.).l.*.b.b.` m 5.N.} V CXXXXXX C.}Xq B B M.0 p.2X ).3.- /.' U.L * s s % % % % % % % % s s s.K d d U.1 o.4 O.6 @.9.G",
+"XX.*.*.*.b.b.` m }.U.U.f.gXr l.E.!.~.!.!.Q.E lX1 -.0.0.9.| r. & XX*Xw {Xz y t.K . . . . . . . . t t t J J yXzXz U.1.S.S.4 p @X-",
+" C m m m m 5 5.f.0.0.0.0.G.G.q.H.H.H.H.q.G.G.GX-.9 @ p.| L e., & X.h +.$Xz _.jXf > > > > > > > > > >.j.j.j _ _.&Xz y.1 o.S.4 O.9",
+" V 5 5.N.N.} C.| { ;X<.2.2.2X<X<X<X<X<X<X<X<.2.2.2.2.2 r e.h K.7.y.,.- ~.2 r e e e e e e e r r r r.2 + /.'Xz y UXz.S.4 @",
+" C.V.V C CXy.!.' .-XOX . . . . X X X X X X X X X X X . ., K.y.y.y R &.,. X X ZX XO ZXOXOXOXOXiXiXiXiXiXi.h.h.2 {Xz J y y U.S O",
+"XyXXXXXXXX.! ! { ~.A b.u & & &X6 )X6X6 )X6 )X6 ) ) ) ) & &.7.y.y.y X.7 KX6.(.u.u.(.u.u.u.u b b b b b b b b.,X /.$ t t t y.1.4",
+"X+X+X+X+X+ , aXp.h.,.7.7.3.3.3.3.3.3.3 T.3.3.3.3.3.3.3 X X.y.y.y.y.y.y X T T.5.5.5.5 T T T.5.5.5.5.7.7.7.7 K.u ~ /.$XfXf . t y.S",
+"XaX+X+XaXa , z $Xw ~ IX=X=X= IX=X=X=X=X=X=X=X=.-.-.-X*.h., R X.y K. .AX*X*X*X*X*X*X*X*X*X*X*X*X*X*.-.-.- I ~ +.$ _.o.Z.Z . J.1",
+"X#.O.O.O.OX#.# u q $.d.d.d.d.d.d.d.d.'.' { { { / / / /Xw +.- &.7.y. ~ 6 6Xw 6 6 6 6 6 6 6 6 6 6 6 6XwXwXwXwXp >.o 9.o.o.Z t y",
+" <X#X#X#X#XhXh ' u u ] ] ] ] ] ] q q.X.X $ $ $ L L L.' {.$ ~., K X.A XwXpXp ; ; P P P P P P P P P P P ; ; ;Xp.o 9 9 9 9.o.Z . J",
+" v.#.#.#XhXhXh.% < 2 '.z.z.z x ` , ,.!.EX1.T E hX> g UXzXz.2. X6 TX* 6XpXe.>.:.;.;Xc.xX&XkXkXkXk 1 1.xXc.;.:.:.>.>.>.>Xe 9.o.Z J",
+".pXhXhXhXhXh.%XlXl.z.z.c.c.z <./ ,.~.! l.g.U }X9 g f.L y _ rX .( TX* 6Xp.>.MXcX& H HX$ G G G G G G GX$ HX&.x.;.M.:.:.>Xe 9 9.o t",
+".w.%.%.%.%.%.%X%XlXlXlXlXl <.# ,Xa.!Xr.gXq }X9 g f.L * t.j eX .u.5X*Xw ;.:Xc H G w w w 0 0 0 0 0X@ F F.+ GX$Xk.x.;.:.:.>Xe 9.o.w",
+".w.zX%X%XlXlXlXlXlXl.z.z.z <.# ,Xa.!Xr.g.U }X9.I.L d s.KXf e Z.u.5X* 6 ;.;X& G w w 0 0 S S.C.CXo S S 0 F.+ GX$Xk.x.;.:.>.> 9.o.w",
+".w 8XlXlXlXlXl.zXxXxXx.=Xx <.# ,Xa.!Xr.f.a }X9.I.L * s . > eX .(.5X* 6 P.; H w w 0 0 S.C.C A A A A.CXo D F.+ GXj 1Xc.:.:.>XeXz.w",
+".w 8XlXxXxXxXx.=.=.= 3 3Xx <.# ,Xa.!Xr.f.aX9X9.I.L * % . > XO.u.5X* 6 PXc H w 0 0.C.CX..B.B.B.B.B.B AXo D F.+X$Xk.x.;.:.>Xe _.w",
+".w.w._.=.=.=.= 3 3 3 3 3 3 <.# ,.!.!Xr.f.aX9 g.I.L * % . > Z.u TX* 6 P.xX$ w 0 S.C.B.B 7 7 N N N 7.B AXo DXs GXj 1.;.:.>Xe.w.w",
+".w.w 8.= 3 3 3 3 3 3 4 3.c <.# ,.!.!Xr.f.aX9 g f.L * % . > XO.u TX* 6 PX& G 0 S.CX..B 7 N.[.[.[.[ N 7.B A SX@.+X$Xk.;.:.: _.w.w",
+".w.w.w 3 3 3 3 3 4 4.m._.c <./ ,.!.EXr.f.aX9 g f d * % . > XO.u TX* 6 PXk G 0 S.C.B 7 N.[.n.n.n.n.[ N 7X.XoX@Xs GXk.x.M.:.w.w.w",
+".w.w.w.] 3 4.m.m.m.m.m.m.c <./ ,.~.E -.f.aX9 g f.L s % . > eXO b.5X* 6 PXk G 0.C A.B 7.[.n.v c c.v.n.[ N.B.C DXs GXk.x.M.>.w.w.w",
+".w.w.w 8.m.m.m.m.m.m n.m._ <.# ,.~.E -.g.a h g.I.L * % . > eXO b.5X* 6 PXk G 0.C A.B N.[.n c c c c.v.[ N.B A DXs GXj.x.M.o.w.w.w",
+".w.w.w.w |.m.m n n n n n._ < ` ,.~.Q l.g.U h g.I.L * % . > eXi b.5X* 6 PXk G 0Xo A.B N.[.n c c c c.v.[ N.B A DXs GXk.x.>.w.w.w.w",
+".w.w.w.w.w.] n n n n n n._ ' ` z ,.! l k.U hX>.I.L.K % t > eXi b.5X* 6 P 1 GX@ S A.B N.[.n.v c c c.n.[ NX.Xo DXsX$Xk.M.w.w.w.w.w",
+".w.w.w.w.w 8 n n n nX0 n._ ' ` z ,.!.q k.U.6X>.I U.K s t > rXi b.7X* 6 P 1 G F S.C.B 7 N.[.n.v.v.n.[.[.BX.XoX@.+X$Xk.R.w.w.w.w.w",
+".w.w.w.w.w.w | nX0X0.]X0._.z `./ ,X4.E -.U E O g U d s t.j rXi b.7.- 6 P.xX$ F 0Xo A.B 7 N.[.[.[.[.[ 7X. A DXs.+Xj.M.w.w.w.w.w.w",
+".w.w.w.w.w.w.w |.].].]X0 nX8 x.t.e.~.EX1.T E h g U d s J.j rXi b.7.-Xw ;Xc H.+ F DXo A.B 7 N N N N.BX. A SX@ :X$.x.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.^ |.].].]X0._ './ , ! W.q.0.U.6X> f.L.K J.j rXi b.7.-Xw ;.;X& G.+ F DXo AX..B.B.BX.X. A SX@Xs G 1Xp.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.^ | | |X0._ ' ` ^ !X4.qX1.9.6 O.I U d y _.2.h., K IXw ;.:.xX$ G.+ F D SXo.C A AXoXo DX@Xs G 1Xp.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.^.Y | |._X8 ` ^.eX4.qX1.U E OX>.1 dXz _ +.hX .u ~XwXp.:.;XkX$ G.+XsX@X@ D D D DX@Xs : G 1 /.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.^.Y |X0X8 '.t.e ! W.q.0.8.6.4.I UXz.& /.2 ~ +Xp.o.>.M.xXkXjX$ G.+XsXsXsXsXs.+.+X$ 1Xp.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.w.^.Y.p v ' ` ^ aX4.qX1.0 E OX>.1 UXz.' { / /.$ > 9.>.:.;.x 1XkXjX$ G G G GX$X$Xj.xXp.w.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.w.w.w.Y = [ '.t.e ! W.GX1.8.6.4 o.1 yXzXz.$.$ _.o 9.>.:.:.;Xc.x 1XkXkXkXjXkXkXk.M.w.w.w.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.w.w.w.w 8 = ' ` ^ !.H.qX1.0 @ O.4.S.1 y J tXf.o 9 9.>.>.:.:.:.;.;.;.x.x.x.x.M.R.w.w.w.w.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w = `X:.e ! W.GX1.9.6 O.S o U y tXf.Z.o 9XeXe.>.>.:.:.:.:.M.M.M.>.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.D Y ^ aX4.q.G.0 @.6.4.SXz y t ..Z.o.o 9 9Xe.>.>.>.>.:.:.>.o.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w ] a.H.qX-.0 @ p.4.S U y t ..Z.Z.o 9 9 9XeXeXe _.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w ] ].HX-.9 @ O.4.S.1 y J t ..Z.o.o.oXz _.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w",
+".w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.GX-.9 @ O.4.S.1 y J J t.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w"
+};
diff --git a/arts/builder/pics/Synth_AMAN_PLAY.xpm b/arts/builder/pics/Synth_AMAN_PLAY.xpm
new file mode 100644
index 00000000..3ad46f6e
--- /dev/null
+++ b/arts/builder/pics/Synth_AMAN_PLAY.xpm
@@ -0,0 +1,316 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 245 2",
+/* colors */
+" c #B1B1B1",
+" . c #BFBFC2",
+" X c #ADADAD",
+" o c #A9AAB3",
+" O c #ABABAB",
+" + c #323E7D",
+" @ c #5F6792",
+" # c #71789D",
+" $ c #2F3A7A",
+" % c #3E4C8C",
+" & c #A5A5A5",
+" * c #3A4488",
+" = c #273272",
+" - c #8D93B5",
+" ; c #78787C",
+" : c #253070",
+" > c #616B97",
+" , c #344082",
+" < c #232E6E",
+" 1 c #313C7F",
+" 2 c #B0B5CA",
+" 3 c #1F286A",
+" 4 c #959595",
+" 5 c #1C2667",
+" 6 c #5F6BAC",
+" 7 c #696A6D",
+" 8 c #374288",
+" 9 c #8D8D8D",
+" 0 c #36417D",
+" q c #6F79AB",
+" w c #43518D",
+" e c #1F2A6D",
+" r c #1E286C",
+" t c #414F8B",
+" y c #2D3774",
+" u c #1A235E",
+" i c #9599AF",
+" p c #D1D2D6",
+" a c #64666B",
+" s c #475394",
+" d c #777777",
+" f c #767DA1",
+" g c #536299",
+" h c #2F3B79",
+" j c #8E8F94",
+" k c #2A3574",
+" l c #5D68A6",
+" z c #4B5891",
+" x c #50598C",
+" c c #273171",
+" v c #575D7F",
+" b c #222D6C",
+" n c #212B6B",
+" m c #303B7D",
+" M c #404B90",
+" N c #1D2767",
+" B c #3C478C",
+" V c #4C5A95",
+" C c #38447E",
+" Z c #38427E",
+" A c #343E7A",
+" S c #858CAF",
+" D c #42508B",
+" F c #2E397E",
+" G c #1D276A",
+" H c #404E89",
+" J c #1C2769",
+" K c #303A76",
+" L c #2C377C",
+" P c #3E4C87",
+" I c #C7C7C8",
+" U c #AFB0B7",
+" Y c #E4E5EB",
+" T c #29326F",
+" R c #384481",
+" E c #DCDDE3",
+" W c #303C79",
+" Q c #3E4C8A",
+" ! c #3D4A89",
+" ~ c #414B83",
+" ^ c #3A4886",
+" / c #686971",
+" ( c #7B84A8",
+" ) c #515C8C",
+" _ c #656F99",
+" ` c #7880A5",
+" ' c #4A578F",
+" ] c #424C91",
+" [ c #202A69",
+" { c #3E488D",
+" } c #2C3878",
+" | c #1B2464",
+". c #797A7E",
+".. c #3A477F",
+".X c #9D9D9E",
+".o c #39457E",
+".O c #47558F",
+".+ c #D0D0D0",
+".@ c #212C6D",
+".# c #1E286A",
+".$ c #CACACA",
+".% c #283277",
+".& c #3B4783",
+".* c #253074",
+".= c #485793",
+".- c #BEBEBE",
+".; c #222C71",
+".: c #44538F",
+".> c #BCBCBC",
+"., c #6974B0",
+".< c #BABABA",
+".1 c #1E286D",
+".2 c #3E4D89",
+".3 c #848AA6",
+".4 c #5F6585",
+".5 c #4F599D",
+".6 c #B4B4B4",
+".7 c #B2B2B2",
+".8 c #394784",
+".9 c #ABADB5",
+".0 c #34417F",
+".q c #ACACAC",
+".w c #87878B",
+".e c #58649F",
+".r c #AAAAAA",
+".t c #414D8F",
+".y c #2D3978",
+".u c #6F6F70",
+".i c #57608A",
+".p c #A0A0A0",
+".a c #666871",
+".s c #283373",
+".d c None",
+".f c #CFD0D8",
+".g c #364184",
+".h c #465197",
+".j c #242F6F",
+".k c #BBBCC1",
+".l c #9A9A9A",
+".z c #313D7F",
+".x c #989898",
+".c c #A8A8AB",
+".v c #4D5480",
+".b c #52609C",
+".n c #A3A4A6",
+".m c #4E5E98",
+".M c #2B3579",
+".N c #6B739A",
+".B c #293577",
+".V c #293377",
+".C c #273175",
+".Z c #495893",
+".A c #394680",
+".S c #475691",
+".D c #717482",
+".F c #E0E1E5",
+".G c #42508C",
+".H c #DADBDF",
+".J c #1D276B",
+".K c #979DBB",
+".L c #8088AB",
+".P c #2C3673",
+".I c #5C6281",
+".U c #242F75",
+".Y c #3C457C",
+".T c #33407D",
+".R c #747474",
+".E c #41508E",
+".W c #B8B9BA",
+".Q c #646FAD",
+".! c #2E3A78",
+".~ c #808083",
+".^ c #2C3876",
+"./ c #2B3675",
+".( c #293473",
+".) c #384485",
+"._ c #242E6E",
+".` c #45518B",
+".' c #424F88",
+".] c #465082",
+".[ c #414D87",
+".{ c #2D387A",
+".} c #9FA2AB",
+".| c #2B3678",
+"X c #384288",
+"X. c #171F57",
+"XX c #343E84",
+"Xo c #DEDEE2",
+"XO c #353F7B",
+"X+ c #2F3A7F",
+"X@ c #1C2669",
+"X# c #2F3975",
+"X$ c #3E4B87",
+"X% c #D7D8DB",
+"X& c #C4C4C5",
+"X* c #4A5996",
+"X= c #36437F",
+"X- c #48548A",
+"X; c #202A70",
+"X: c #F1F1F1",
+"X> c #1F2A6F",
+"X, c #515BA0",
+"X< c #B4B4B5",
+"X1 c #3B4987",
+"X2 c #4C579B",
+"X3 c #7D7D7F",
+"X4 c #B2B2B3",
+"X5 c #3E4880",
+"X6 c #384584",
+"X7 c #495598",
+"X8 c #364382",
+"X9 c #5661A8",
+"X0 c #434F92",
+"Xq c #374079",
+"Xw c #53597A",
+"Xe c #A5A7B0",
+"Xr c #3E498D",
+"Xt c #5966A4",
+"Xy c #1E296A",
+"Xu c #1D2769",
+"Xi c #C9C9C9",
+"Xp c #929293",
+"Xa c #3B458D",
+"Xs c #3D4A85",
+"Xd c #4C5C97",
+"Xf c #E6E7EC",
+"Xg c #D4D5D7",
+"Xh c #C3C3C3",
+"Xj c #C1C1C1",
+"Xk c #232D72",
+"Xl c #465491",
+"Xz c #455490",
+"Xx c #212B70",
+"Xc c #34407C",
+"Xv c #43528E",
+"Xb c #CCCDCF",
+"Xn c #1F296E",
+"Xm c #323E7A",
+"XM c #1E296D",
+"XN c #525EA0",
+"XB c #313C79",
+"XV c #B7B7B7",
+"XC c #676A79",
+"XZ c #2A3472",
+"XA c #7C7C7D",
+/* pixels */
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d c.%.V.V.%.C.U.U.;XnXy N.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.P +X 8XXX+ L L.V.%.U.UXk.;.;XxX;Xn | u.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.dX1X0 M BX 8XXX+ L L.V.%.U.UXk.;.;XxX>X>XnXn r u.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d ZX,.5X7.h MXaX XXXXX+ L L.V.%.U.UXk.;.;XxX>X>XnXM.1.1 rX@ u.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.dX9X9X,.5X7X0 MXaX XXXXX+ L.M.V.%.U.UXk.;XxXxX>XnXnXM.1 r r r.J 5.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.dXd 6 6X9X,X2.hX0 MXa 8XXXXX+ L.M.V.C.*.UXk.;XxXxX>XnXnXM.1 r r.J.J.JX@ u.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.,., 6X9X9X,X2.h ] {Xa 8XX 1 F L.M.V.s = c :.;XxX;X>XnXnXM.1 r r.J.J.J G G 5.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.`.,.,.Q 6X9XN.5X7.h ] {Xa 8XX 1 F L m 0XOXOXB K.s.;XnX>XnXn.1 r r r.J.J G G G G 5X..d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d z.,.,., 6X9X9X,X2.hX0 MXaX 8XXX+ m Z x # f `.N @ ~ c.@XnXnXM.1 r 3 [ G G G G GXuX@ 5X..d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d V.,.,.,.Q 6X9X9X,X2.hX0 MXa 8XX 1X+ Z.' (.fX% E .Xe @ y.@XnXnXM r e._ T b rXu G GXuX@X@ 5X..d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d z.,.,.,.Q 6X9X9X,X2X7.h M {Xa 8XX , R.i ( U E.f I o j.4 y.@XnXnXM 3._Xq ).Y T [XuXu JX@X@ 5 5X..d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.`.,.,.,.Q 6X9X9XN.5X2.hX0 MXaX XXXX.&X-.L.f EXf.$ X j. Xw.P nXnXn.1 [ T ) - @Xq T.#XuXuXuX@ 5 5 5X..d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.,.,.,.Q 6 6X9XNX,X2.hX0 M {Xa 8.gX$ @ S 2 EXo.FXh &.w.RXwX# T.@ e r.@._.Y @ @ @X5 T n.# GXuXu 5 5 5.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.,.,.,.Q 6X9X9X9X,X2X7.h ] MXaX .gX$ ' S.f E YXo.H.>.X.~ / v KXBXm.(Xx.@.@.PXq @ i @XqXZ e 3 r.#.#XuXu |.d.d.d.d.d.d",
+".d.d.d.d.dXd.,.Q 6 6X9X9XNX,X2X7.hX0 MXaX *.[ > S 2X%Xb ..$XgXV.l.~ / vXqX- _X-Xm.( < c y.] @ > _.] c.@ e e 3 3Xy.# u.d.d.d.d.d",
+".d.d.d.d.d 6 6 6X9X9X9XNX,X2X7.hX0 M B *X H z S.fX%.H.W.xX4Xb.6.l.~ / v.Y >.K fX- A : : :X#.Y.N.9 @ K._.@.@.@ n nXyXu.d.d.d.d.d",
+".d.d.d.dX9 6X9X9X9XNX,.5X2X7 sX0.tXrX1 !.G > S 2.H IX4.p 9.qXbX4.l.~ /Xw A.v _ # ( x.y = :XZXq _.9 _XqXZ < < < <.@ n nXu.d.d.d.d",
+".d.d.d ZX9X9X9XNX,X9 lXtXt.e.b.b V V z z ) -.f.H.H.6 9.wX3 &.$.7.l.~ /.v yXq ~ # 2.N 0.(.C.sXB @.9.NX5 K c :.j.j < <.@.@ |.d.d.d",
+".d.d.dX,X,X,X,.5XN q.K.K.K.K.K.K.K - - -.K 2 EXbX<.xX3X3XA.n.$ .x.~ /Xw K A.o.N 2 f.[XB.s./.y.].N.N.N.]X# c c : :.j < b [.d.d.d",
+".d.d.d.5.5X2X2X7XN -X% EXfXfXfXfXfXf YXfXfXf Y.W 9.~.R dXA.pXi .x.~ /XwXm AXO _ 2.L ).&.|.|.BXO ~.N.9 _XqXZ.s = c : :.j <.d.d.d",
+".d.dX1X7X7.h.h s.b - E YXf Y.FXoXo E.H.H EXoXoXVXp.wXA.~.w &Xi .x.~ /Xw AXm $X- # `.L ) +.y.|XBX5 @ i @ Z.P k.(.s = c : : N.d.d",
+".d.dX0.hX0X0 ] ].m.KXfXf YXoX%XgXg p.+.+.+Xg.HXV 4 9.w.w 9.q.$ .x.~ /XwXOXm.{ Z.] f 2.N.& $.{ K.o.i (.i.o.^.|.B k.(.s = c.j.d.d",
+".d.P M M M M {Xr V -Xf.FXoXg.+Xb.$Xi I IXiXgXo p IXj.-XjXj.$.+.6.x.~ /Xw 0 W.{XO ~ _.K _X5XB m W.o @ i > ~Xm } }././ k.(.s c [.d",
+".d + BXaXaXaXa *Xl -XfXoXgXbX&XhXj.-.-.-Xj p YX:X:X:X:X:X:XfX%XV.x.~ /Xw Z h m WX5 @.L @ ~Xm mXB.. _ 2 #.].o h.y } }./ k.(.s [.d",
+".dX X X X 8 8.).` S YXoXg.$XjXj.-.-.>.-.-.+.F YXfXfXfXfXfXoXgXV 4X3 /Xw.oXB.z +X5 >.K.N.' Z +.TX= x # # # xXc h.!.y }.^./ k =.d",
+".d 8 8XXXXXXXX ,.[ S Y E.+XiXj.-.-.<.<.<.-XbXo.H.H.HX%X%X%Xg p.6 4X3 /Xw.o +.z.TXs.N 2 fX- ~ , ,.0X5X- # 2.NX5Xm $ $.!.y.^./ k.d",
+" cXXXXXXXXXX 1 +X$ S Y.H.+ I.-.>.<.WXV.W.<XiXgX& X.c O X.-Xb 4X3 / v.&.T ,.0.8 ) f f f ).&X8X8...' _ i _ ~Xm + W $.!.y.^./XZ",
+".%X+X+X+X+X+ F mXs.L Y.HXbX&.<.<.WXVXVXV.<X&.+.r.wX3 dXA.~ &X& X 4X3 / v.&.0X8X8.).[ x f 2 #.' RX8X=.[ @.3 @.[ 0 + +Xm W h.y.y k",
+".V L L L L L L.{.&.L YX%.$Xj.WXVXVX<.6XV.WXhXb &X3 d.u.RXA.pXh.q 4X3 / vXs.0X8.).)XsX-.N.K.N.` R.).A.' @.L @.' 0.0.T + + W h.!.^",
+".V L L L.M.M.M.| R (.FX% I.-XVXVX<.6X4X<XVXj.$.p d.u a.u.R.lXj O 4X3 / vXsX8.).).).&.` > S >X-.8 ^.&.' @.3 >.`X=.0.0.T +Xm W h.^",
+".%.V.V.V.V.V.%.B Z (.FXg I.-X<.6X4.7.7.6XVXj.$.p d.u a.u.R.lXj.rXpX3.a v.[ R ^ ^X1.&.` > S _.OXsX1.&.` @.L >.`.AX8X8.0.T + + W.!",
+".C.%.%.%.%.C.C.s 0 (.FXgX&.>.6X4.7 X4X<.-Xi.p d.u a.u.R.lXj.rXpX3.a v.[.8X1X1 !XsX- > S _ 'X$ !XsX- >.3 >X-.AX6X8X8.0.T +Xm h",
+".U.U.U.U.U.*.U = A `.F pXj.<.7 .7.6.- I.X.R.u a 7.R.lXj.rXpX3.aXw.[.8 ! ! QX$.O > S _ z.[ Q PX- >.3 >X-.&.8X6X8X=.0.0 + W",
+".U.U.U.U.U.U.U :Xm ` E pXj.W X4.- I.X.R.u a 7.R.xXj.rXpX3 /Xw P.& Q % %.2 ' _ S _ z H.t.[ ' > S _X-Xs ^.8X6X8X=.0XcXm",
+".;XkXkXkXkXkXk :XB f E pXjXV X X .7.- I.nX3 d.u dXA.pXj.rXp. .a v.'X1 % %.t.` ) #.K # z D.E H ' _ S _ 'XsX1 ^.8X6X8X=.0 +",
+"Xn.;.;.;.;.;.;.j K f E p.-XV X X X X .7.-Xi.c.w.~XA.~.w &Xj.rXp. .a.I.` P %.t.E z g ( 2 f z wXv D z _ S _ z PX$X1 ^.8 RX8.0Xc",
+"Xy.;.;.;XxXxXx bX# # E.+.-XV X X X.q.q X Xj.+ I.>.WXV.W.<XjXi XXp. .a.IX-.2.E.E.O > ( ( ( >.ZXl.:.O ) #.K.NX- P QX$X1 ^.8 RX=Xc",
+" NXxXxXxXxXxX; nXZ.N EXb.-X< X.q.q O O X X&X%.FX:X:X:X:X:Xo.+ Xp. .a.I.O H.E w V ` 2 ( g VXlXlXl V g ( 2.NX-.[ Q Q !X1.8.A RXc",
+".dX;X>X>X>X>X>.@ y # EXb.>.6.q.q O O.r X XjXg.H.F.F.FXoXoXgXb Xp. .a.I.O DX0.:.m f.K f g z.=.Z V > ( ( ( @.: t t Q PXs ^.8 R.d",
+".dXnX>X>XnXnXn.@ K ` EXb.<X4.q O O.r.r.q Xj.+.+.+.+.+.+.+Xb.$ XXp. .a.I '.GXl.O g # -.N g.ZX*.Z g ` 2 ( g z.: w.G t.2X$X1.8.A.d",
+".d |XnXnXnXnXn b K f E.$XV X & & & & &.c O.<.$.W.c &.p.n &X<X&.rXp. .a.4 '.:Xl z g `.K f g zX* V g f.K f g 'Xz.: w t Q PXs ^Xm.d",
+".d uXnXMXMXMXM nX# f.H I .r.p.p.p.p.p.n &X<Xh.pX3 d.u dXA.X.- &Xp. .a.4 '.SXl.m.e.L 2 ( g VXd V.e # -.N.m.OXlXzXv.G t QX$ ^Xq.d",
+".d.d r.1.1.1.1 [ y.N.kXe j.w.w.~.~.~.~.w 9.n.W.lXA.R 7.u d.x.- & 9. .a.4 ' z V _.L -.K q.b.m.m.m.e `.K # g.O.SXl.: w t.2X$.&.d.d",
+".d.d u.1 r r r [.P.4.} j.D.u / / / / /.u d j 4 ;.u a 7.u 4.> & 9. .a.4 z V.m ( 2.K q.e.m.m.m g >.L 2 ` g z.=Xl.: w t.2 PXq.d.d",
+".d.d.d r r r rXy._.Y.i vXwXwXwXwXwXwXwXw v.D j j 9X3.u.u.u 4.< & 9 ;.a.I z.m g.L 2 - l g.m.b.e.N.L.L.L _.m.Z.=.SXzXv.G H P.d.d.d",
+".d.d.dX@ r.J.J G r._ T TXZ.P yX# K KXmXq.Y v.D.w & 9 d.R.u 4.< & 9 ;.a.I '.m @.L 2.L.e.m.b.bXt.L 2.L > gXdX*.Z.SXzXv.G HXs.d.d.d",
+".d.d.d u.J.J.J.J G G 3 3 [ n b._ : =XZX#XO.] v.D.w 9 9.~ ;.l.< & 9 ; a.4 ) > ( S.K q.b.m.b g l.L 2.L.e.mXdX*.Z.SXzXv.G H...d.d.d",
+".d.d.d.d 5.J.J G G G G G r e.@.j : =.s.B } 0X5 v.D.w.nXp.~.p.> & 9 ; a.4 g ` 2 - q.e.m.m.b.e _ S 2 (.eXdXdX*.Z.SXzXv.G P.d.d.d.d",
+".d.d.d.d.dX@ G G G G G G r e.@.; :.*.s.B.| W 0.] v.D.w j.x &XV.p 9 ; a.4 ) _.L q.e.b.m.b.e.N (.L.L _ gXdXdX*.Z.SXz w H.d.d.d.d.d",
+".d.d.d.d.d u G G G GXu G r e.@ < :.*.s.B.|.y $ Z ~.I.D j X .X 9 ; a.4 z g.e.mXdXd.m g > (.K ( >.e.mXdXdX*.=Xl.: w...d.d.d.d.d",
+".d.d.d.d.d.d 5 GXuXu JXu.# e.@ < : c.C.B.| }.!Xm.o.v.I.D j.X .X.w d a.4 ' ' z.=X* V.m > ` ` ( _ g.mXdXdX*.Z.S.O.: H.d.d.d.d.d.d",
+".d.d.d.d.d.d.d 5X@X@X@Xu G 3.@ <.j :.C k.B }.{ $ +...].I.D j X.l.w d a.I ' wXl.=.Z z g f.K ` > g.mXdXdX*.Z.=.SXz D.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.dX. 5X@X@X@Xu r e.@.j : =.(.B.|.y $ mXc...v.I.D.w.~ d / a.IX- DXlXl.=.=Xd > # > gXdXdXdX*.Z.=.SXz w.Y.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.dX. 5 5 5Xu.# e.@ < : c.s k.|.{ $ m +.0X5.] vXC.a a a a vX- D.:XlXl.S.= V.mXd VX*X*X*.Z.=.SXl w.Y.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.dX. 5 5 5.# 3.@ <.j c.s k.| }.! $ + + 0X5.v v v v v v x.` D w.:XlXl.S.S.S.Z.=.Z.Z.=.S.SXz w.Y.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.dX. 5 5Xu 3 n <.j : =.(.B }.y $ m +.T.0.A ~ ~ ~.[.'.' Q t.G w.:XzXlXl.S.S.S.S.SXl.OXz w.Y.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.dX. 5XuXy n.@ < : c.s k./ }.! $ + +.0.0 0 C.A.&.&XsX$ Q t.G wXv.:.:XzXzXzXzXz.:.: D.Y.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d |.#Xy n <.j : =.(./ }.y $ W +.T.0X8X8X6.8 ^X1X$ Q Q t t.G w wXvXvXvXv w w H.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d uXu n.@ < : c.s k./ }.! $Xm +.T.0X8X8X6.8 ^X1 ! P.2 Q t t t.G.G.G.G H...d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.dXu.@ b.j : =.( k.^.y.! W + +.T.0X=X8X6.8 ^X1XsX$ P Q.2.2 H H H P.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d | [ < : c.s.(./.^.y h WXm +.T.0X=X8 R.8.8 ^X1XsX$X$ P PXs...d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d N.j c.s k./.^.y h W + +.0.0X=X8 R.A.8.8 ^ ^.&Xq.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d [ [ = k./.y.! h WXm +Xc.0.0X= R R.AXmXq.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.dXZ k.^.^.! h WXm +XcXcXc.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d"
+};
diff --git a/arts/builder/pics/Synth_ATAN_SATURATE.xpm b/arts/builder/pics/Synth_ATAN_SATURATE.xpm
new file mode 100644
index 00000000..153b5bfd
--- /dev/null
+++ b/arts/builder/pics/Synth_ATAN_SATURATE.xpm
@@ -0,0 +1,310 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 239 2",
+/* colors */
+" c #485896",
+" . c #364281",
+" X c #33407E",
+" o c #327F37",
+" O c #313E7C",
+" + c #31694A",
+" @ c #2E3A79",
+" # c #8088AF",
+" $ c #4F5AA0",
+" % c #1D2865",
+" & c #273272",
+" * c #253070",
+" = c #455296",
+" - c #838CB5",
+" ; c #2E3A7C",
+" : c #1E2869",
+" > c #2A3678",
+" , c #283276",
+" < c #273275",
+" 1 c #3A4781",
+" 2 c #475591",
+" 3 c #323E83",
+" 4 c #45538F",
+" 5 c #747AA6",
+" 6 c #212C6F",
+" 7 c #5363A0",
+" 8 c #42518C",
+" 9 c #1E286C",
+" 0 c #2D387E",
+" q c #2B367C",
+" w c #29347A",
+" e c #1A235E",
+" r c #384582",
+" t c #475794",
+" y c #232E74",
+" u c #465593",
+" i c #357943",
+" p c #35417F",
+" a c #233F56",
+" s c #656FB8",
+" d c #20345D",
+" f c #4D599D",
+" g c #2B3775",
+" h c #394786",
+" j c #768C9A",
+" k c #848DB5",
+" l c #3A478A",
+" z c #232D70",
+" x c #222D6F",
+" c c #313B81",
+" v c #1E296B",
+" b c #316D45",
+" n c #2E397E",
+" m c #405089",
+" M c #414E8A",
+" N c #2D397D",
+" B c #1D276A",
+" V c #2D3C73",
+" C c #2A357A",
+" Z c #4C5C98",
+" A c #293379",
+" S c #283378",
+" D c #4B5A97",
+" F c #4A5A96",
+" G c #2A3F66",
+" H c #263176",
+" J c #485894",
+" K c #242F74",
+" L c #475693",
+" P c #232D73",
+" I c #455491",
+" U c #33427C",
+" Y c #202B70",
+" T c #2D3876",
+" R c #3C4A88",
+" E c #3B4887",
+" W c #2B3674",
+" Q c #374483",
+" ! c #222C6B",
+" ~ c #2F3C7B",
+" ^ c #3D4C8C",
+" / c #1C2665",
+" ( c #4B569D",
+" ) c #28396A",
+" _ c #48529A",
+" ` c #747CA4",
+" ' c #434E95",
+" ] c #212C6D",
+" [ c #1C2668",
+" { c #4E5D99",
+" } c #293478",
+" | c #2B5452",
+". c #273276",
+".. c #374289",
+".X c #253074",
+".o c #485793",
+".O c #222C71",
+".+ c #212C70",
+".@ c #44538F",
+".# c #737AA6",
+".$ c #202A6F",
+".% c #43518E",
+".& c #1F2A6E",
+".* c #2F3A81",
+".= c #1D286C",
+".- c #3D4B88",
+".; c #37843C",
+".: c #435191",
+".> c #333F7E",
+"., c #414F8F",
+".< c #303D7B",
+".1 c #515DA2",
+".2 c #1E2B66",
+".3 c #2D3978",
+".4 c #2D5B50",
+".5 c #2C3777",
+".6 c #3B4989",
+".7 c #1B2563",
+".8 c #293574",
+".9 c #3A8F38",
+".0 c #294C56",
+".q c None",
+".w c #263171",
+".e c #242F6F",
+".r c #314B6B",
+".t c #404B91",
+".y c #1F296A",
+".u c #1C2767",
+".i c #2B3779",
+".p c #1B2566",
+".a c #3A458B",
+".s c #283376",
+".d c #384389",
+".f c #364187",
+".g c #353F86",
+".h c #26346A",
+".j c #757BA7",
+".k c #44528E",
+".l c #7379A5",
+".z c #1E296C",
+".x c #1D276B",
+".c c #404E8A",
+".v c #2C377D",
+".b c #4E5E9B",
+".n c #3E4C88",
+".m c #2A357B",
+".M c #283379",
+".N c #263177",
+".B c #28465B",
+".V c #475694",
+".C c #7684A1",
+".Z c #455492",
+".A c #445291",
+".S c #323E7C",
+".D c #439F36",
+".F c #404E8D",
+".G c #303C7A",
+".H c #3F4E8C",
+".J c #1F2A66",
+".K c #5F6AB2",
+".L c #2A3674",
+".P c #3A992D",
+".I c #283472",
+".U c #5560A8",
+".Y c #838CB4",
+".T c #327243",
+".R c #2D3F70",
+".E c #2D6148",
+".W c #49549C",
+".Q c #242E71",
+".! c #232E70",
+".~ c #171F57",
+".^ c #34457A",
+"./ c #348434",
+".( c #323C82",
+".) c #202A6D",
+"._ c #1F2A6C",
+".` c #424F8B",
+".' c #51619D",
+".] c #1D286A",
+".[ c #1C2669",
+".{ c #4F5F9B",
+".} c #2B367B",
+".| c #4B5B97",
+"X c #6E79C0",
+"X. c #283278",
+"XX c #273277",
+"Xo c #399332",
+"XO c #495995",
+"X+ c #253075",
+"X@ c #384581",
+"X# c #6A75BC",
+"X$ c #465592",
+"X% c #222C72",
+"X& c #455391",
+"X* c #212C71",
+"X= c #33417C",
+"X- c #202A70",
+"X; c #333F7C",
+"X: c #1D286D",
+"X> c #3F4D8B",
+"X, c #5A65AC",
+"X< c #364382",
+"X1 c #5761A9",
+"X2 c #344180",
+"X3 c #222D6B",
+"X4 c #323D7E",
+"X5 c #2C3978",
+"X6 c #3C478B",
+"X7 c #7D85AD",
+"X8 c #394588",
+"X9 c #388B37",
+"X0 c #767FA6",
+"Xq c #333F82",
+"Xw c #488654",
+"Xe c #424D94",
+"Xr c #1F296B",
+"Xt c #203062",
+"Xy c #3E4990",
+"Xu c #1D2769",
+"Xi c #2C377B",
+"Xp c #293578",
+"Xa c #293378",
+"Xs c #263175",
+"Xd c #495894",
+"Xf c #252F74",
+"Xg c #242F73",
+"Xh c #475692",
+"Xj c #343F86",
+"Xk c #222D71",
+"Xl c #747BA7",
+"Xz c #212B70",
+"Xx c #43528E",
+"Xc c #1F296E",
+"Xv c #1E296D",
+"Xb c #3E4C89",
+"Xn c #4D5C9B",
+"Xm c #3C4A87",
+"XM c #3A4885",
+/* pixels */
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.w ,Xa AX..N K y.O.$ v.u.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q W.S...f 3.* 0 q wXXX+ K PX%X* YX-Xc.7 e.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q E '.tX6.d.f 3.* 0.Q w.jXl K PX%X* Y.$.$XcXc 9 e.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q p $ $ _ '.tX6.d.g.(.* 0.Q.M.jXl y PX%X* Y.$.$XcXv 9 9 9.[ e.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.qX1X1.1 f _ '.tX6..Xj.(.*.v.Q.M.jXl y PX%Xz Y.$.&XcXv 9 9 9.=.x [.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q D.KX,.U.1 ( _ 'Xy.a..Xj.(.*.v.Q.M.jXl y PX%Xz Y.$XcXcXv 9 9 9.].x.x.[ e.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q s s.KX,.U $ ( =XeXy.a.fXj c n.v.mX..NXf y P.OXzX-.$XcXcXv 9 9 9.x.x.x B B.p.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.`X# s.KX,X1.1 $.W =.tXy.a.f 3 c 0 q wX. HXf PX%X*Xz.$.$XcXc 9 9 9.=.x.x B B B B [.~.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.qXdX X# s.KX,.U.1 ( _ '.tX6.d.f 3.* 0 q zXX.j.# PX%X*Xz.$.&XcXv 9 9 9.].x.x B B BXu.[ [.~.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q {X X# s.KX,X1.U $.W =XeXy.a..Xj.(.*.v.m zXXXl.# PX%Xz Y.$.&XcXv 9 9 9.].x.x B B BXu.[.[ [.~.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.qXdX X# s s.KX,.U.1 ( _ '.tXy.a.f 3 c n q w z.NXl.# P.OXz.$.$XcXcXv 9 9.].x.x B B BXuXu.[.[ [.p.~.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.`X X# s s.KX,X1.1 $.W =XeXyX6...g 3.* 0 q w 6 HXl.#X%X*Xz.$.&XcXc 9 9 9 9 9.x.x B B BXuXu.[ [ [.p.~.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.qX#X# s s.KX,X1.1 $ ( _ '.tXy.a.fXj c n.v.m.MXXX+ K PX%X* Y.$.&XcXcXvXv 9.z.z.z 9 9 9 9.] BXuXu [ [.p.q.q.q.q.q.q.q",
+".q.q.q.q.q.q s s s.K.KX,X1.U $ ( _ 'XeXy.a...g 3.* 0 q wX. HXfXg P.OXz Y.$.$.$.$.$.$.$.$.$.).).).)._._Xr 9.].]XuXu.p.q.q.q.q.q.q",
+".q.q.q.q.q D s.K.KX,X,X1.1 $ (.W =XeXyX6.d.f 3 c n.v.m AXX ] K.#.l.O.+.+.+.+.+.+.+.+ 6 6 6 6 6 ] ] ] ].).).)Xr.y.y : e.q.q.q.q.q",
+".q.q.q.q.q.K.KX,X,X1.U.1 $ (.W =Xe.tX6.a.fXj.(.* 0 q wX. H.) y.#.l PXkXkXk z z.Q.Q.Q.Q.Q.Q.Q.!.! z z x x ] ].)._.y._ :.q.q.q.q.q",
+".q.q.q.qX1X,X,X1.U.U.1 $ ( _ =Xe.tXy.a...g 3 c 0 q.m AXX H.) y.#.#XgXgXgXgXgXgXgXfXf.X.XXg.Q.e.Q.eX3.eX3X3X3X3X3.J.J.J %.q.q.q.q",
+".q.q.q pX1.U.U.1.1 $ (.W _ 'Xe.tXy.a...g 3 c n.v.} wX. HX+ ]Xf 5Xl.X.X.X.XXsXsXsXsXsXs.X.X.w.w.e.e.e.h.h.h.hXtXtXtXtXt.J e.q.q.q",
+".q.q.q $.1.1 $ $ (.W _ = 'XeXyX6.a...g 3.(.* 0 q w SXX. H HXsXsXsXsXs. . . . < < < &.w.h ) ) G a.B.0.0.0 | | | |.0 a d.J.q.q.q",
+".q.q.q $ f ( (.W _ = 'Xe.tXyX6.a...g 3.(.* 0 q w AXXXXXXXX. . . XXXX S S } } }.s.s.I.I ) G.B.0.4.E b.T i o o./ o o b.E aXt.q.q.q",
+".q.q E _ _ _ = = 'Xe.tXyXy.a.d.f.g 3.(.* 0 q C AX.XXXXXX S x S.jX0 }XpXp }Xp.8.I ) G.B |.4 +.T.T.T o./././././ o o b.E.B.hXt.q.q",
+".q.q ' ' ' 'Xe.t.tXyXyX6.a...fXj 3 c.* 0 q.m A S S S S S }.! wX0X0 > > > > g g ) G | + iX9.P.PXoX9Xo.PXoXoX9././ o.T.E.B.hX3.q.q",
+".q W.t.t.tXyXyXyX6.a.a...f.g 3.( c n 0 q C A S SXaXa } w w.e CX0X0 >.i g g G.B | +.T.;X9.9X9.; i b + +.E.E.4.4 | |.0.B ).h *.J.q",
+".q.SX6X6X6.a.a.a.d...f.gXj 3 c.* 0.v q w A S SXa A w C C C *.iX0X0.iX5 V.R.0 + iXo.P.P.P.9.; b +.4.r.r.r G G.R ) ) ) ).I.I &.J.q",
+".q...d.d.....f.f.fXj 3 3 c.* n 0 q.} w AX. SXa A w C C C.}XiXiXiXiX5 V G.4 +.;.9.9X9.;.T + |.B.r.R.R.R.R V V V V V W W.L.8.8.I.q",
+".q.f.f.gXjXjXj 3 3.( c.* n 0.v q.m w SXXXX SXa w C C C.}XiXi N ;.3 V.r.4 i.9.D.P.9 i +.r.r.R.< O O.S.SX4X4.<.< ~ @ @ @.3 T W.8.q",
+".w 3 3.(.(.( c c.*.* n 0.v q.m w AX.XXXXXX S } C C C.}Xi N * ; `.C.r.4 i.9.9.9 i + |.r.r.^X=X= pX2 pX2 X.>.>.>.S O.< ~ @.3 T g.I",
+" ,.*.*.*.*.* n 0 0.v q q.m w AX.XX H. XXXX S w C C.}Xi N ;.w @.C j +.;Xo.P.9 i.4.r.^X= pX<X< Q QX<X<X< . .X2X2 X.> O.<.G @.3 T.L",
+"Xa 0 0 0.v.v.v q q.m w w.MX.XX H HX+ HXX S } w C.}Xi N N ;.h.R jXw iXo.9.; +.4.r.^ UX< Q Q hX8 Q Q Q Q QX<X< .X2 p.>.S O.G @ @ g",
+" A q.Q.Q.Q.Q.m w z z z 6XX H ].).) ] H. x.!.e *XiXi.w.w.w.h.rXw.DXo.D.; +.r.^.^ Q Q h E E E E h h h h h Q Q QX< p p X.S O.G @ T",
+"X. w w.M.M.MX.X.XXXX.N HX+Xf K y yXfXs. S w C.iXiXi ;.3.R.r.4 iXo.9.; +.r.rX@ r h h.6.6.6.6.6.6.6 E E E h h Q QX< .X2 X.S O.G @",
+".NXX.j.j.j.j.N H.jXlXlXl KXg.#.#.# 5Xs. .jX0X0X0Xi ;X0 ` jXw.;Xo.D.;Xw j.CX7 h E.Y.Y.Y - ^ ^.Y.Y.Y.Y R.6.Y.Y # # r Q #X7X7X7.< @",
+" KX+XlXlXlXlXfXf.#.#.#.# P P.l.l.#XlXsXXX0X0X0X0Xi T ` j jXwXo.9.9 + j jX7X7 l ^ - - k k.H.H k k k kXbXb.Y.Y.Y.Y h r # #X7X7.S.G",
+" y K K y y y y P P P PX%X%.O.O PXg.XXsXX } >.i.i @ V.r.4.;.9.D.9 i.r.^X@ E.6 ^ ^ ^.H.H.F.F.F.F.F.F.H.HX>Xb.- R EXM h r Q . p X.<",
+".O P P P P P PX%X%X%.OX*X*Xz.+XkXg.XXs SXpXp.i g.R.r.4 i.9.9.9Xw j.r V T @.< ^.H.S.SX;X;.,.,X;X;X;X;.F.H O O.<.GXm E T T g W p.S",
+".$X%X%X%X%X%.OX*X*XzXzXz Y Y.+XkXg.X. S } > g.R.r.4.;Xo.D.9 i j.CX@ @.6 ^.H.H.,.,.,.:.:.A.A.A.A.:.%.%.,.F.HX>Xb.-XmXMXM r . pX;",
+" vX*X*X*XzXzXzXzXz Y.$.$.$.$.+XkXgXgXs <.8 ) G.0 + i.9.9.9 +.4 jX0 h @ ^.H.F.,.,.:.A.AX&.Z.Z.ZX&X&X&.AXx.% 8.HX>Xb.- EXM r r .X;",
+".u Y Y Y Y YX-.$.$.$.$.&.&.$.+ z.Q.w &.I.I G.0 +.9Xo.P.9 i.4.^.C #.6.<.H.F.,.,.:.AX&.Z u u u u u uX$.ZX&.A.% 8.`X>Xb.- EXM rX@X=",
+".qX-.$.$.$.$XcXcXvXv 9 9 9Xr.)X3.e.h.h G.0.4.T.;XoX9.; +.r.r.^ r E.6 ^.H.,.,.:X&.Z u u.V t t t t t.V LX$ I.@.% 8 MX>.nXmXM rX@.q",
+".qXc.$.$.& 9XvXvXv.z v.].].y !X3.h G.B.4.T.;.P.P.P.; +.r.^ p h E ^ ^.H.,.,.:X&.Z u.V t F FXO XO t.VX$ I.@.% 8.cXb.-XmXMX@.q",
+".q.7Xc.z.y.J.2.2.2XtXtXt d d a a.0.4 b iX9X9Xo.; i.4.r.r U Q h.Y - ^.S.,.:.A.Z u.V F D D D D D FXO J LX$ I.k 8.`X>.nXmXM.G.q",
+".q eX:.].2Xt d d d d a a.0.4.E.T oX9.P.P.PXo.; +.4.r U p QX8 E.Y -.H.S.,.AX& u.V F F.| Z Z Z Z Z Z D F J LX$ 4Xx 8.cXbXmXMX=.q",
+".q.qXu.2 d a |.E.E.E.E.E b.T o././X9X9.; i +.4.B.R.RX= . Q h.6.Y k.HX;.:.A.Z u t F ZXnXn.b.b.b.bXn Z D F tXh I.k 8.`Xb.-XM.q.q",
+".q.q e d.0 b./XoXo.P.PXo./Xo.P.PXo./ o +.4.B.R V.<.>X2 QX8 E.6 - k.FX;.:X& u.V F.|XnXn.b.{.{.{.{.bXn Z DXO.oX$.@.%.`Xb.n.^.q.q",
+".q.q.q d.0.E o o./././ o.T.T.T b.E |.0.B G ) V @X4.>X< QX8 E.6 ^.H.F.,.A.Z u t D ZXn.b.{.'.'.'.'.{.b {.|XO.oXh IXx 8.c.n.q.q.q",
+".q.q.q d a | b.T.T.T b.E.E |.0.B G ) ).I.8X5 ; ~X4X2X< Q h E.6 ^.H.F.,.A.Z u t F D Z.b.{.'.' 7 7.'.'.{.b Z FXdXh IXx 8.cXm.q.q.q",
+".q.q.q.~ d d a a a a a a d d dXt.h.h.w.I gX5 ;.<X4Xq . QX8 E.6.Y k.FX;.A.Z u t F D Z.b.{.' 7 7 7 7.'.{.b Z FXdXh I.k 8.c 1.q.q.q",
+".q.q.q.q.7 % % % % % % /.u.y._ x.Q.w.sXp.i @ ;.<X4Xq . Q Q h.6.Y k.FX;.AX& u tXO D Z.b.{.' 7 7 7 7.'.{.b Z FXdXh IXx 8.n.q.q.q.q",
+".q.q.q.q.q.p.u.u /.u.u [Xu.y.) 6.! &.sXp.i @ ;.<X4X2 .X< Q h.6.Y k.FX;.:X& u t D Z.b.{.'.' 7 7 7.'.{ { Z FXdXh 4Xx.c.q.q.q.q.q",
+".q.q.q.q.q e B B B BXu B 9._ ] z.Q & <Xp.iX5 ;.<X4X2 .X< Q h E.Y k.HX;.%X&X$.VXO F ZXn.b.{.'.'.'.'.{.{ Z.|XO.oX$ 4Xx 1.q.q.q.q.q",
+".q.q.q.q.q.q.p BXuXuXuXu.]._ ] x.Q.w <.s >X5 @ ~X4.>X2X< Q h E RXb.H.F.%.A.Z L tXO D ZXn.b.{.{.{.{.{ { Z FXdXh 2.k m.q.q.q.q.q.q",
+".q.q.q.q.q.q.q [.[.[.[Xu BXr.) x.e.w <.8 >X5 @ ;X4.>X2 . Q h E.6XbX>.H.,XxX&X$.V J F D Z {.b.b.b { Z Z FXO.o 2 4 8.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.~ [.[.[.[Xu 9.) ].! * &.8Xp.i.3 ~ OX4X2 .X< Q h.Y.YXb O.F.%.A IX$ L J F D.| Z Z Z Z.| FXO.oXh I 8 1.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.~ [ [ [Xu.].) ].!.Q.w <.8.5.3 @.< O.>X2X< Q h.Y.Y.- O.H 8.%.@ IX$ L tXOXO F F F FXOXd.oXh I 8.^.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.~.p [ [.]Xr ] x.e.w &.8 >X5 @ ~ O.>X2 . Q Q #.Y R.<X>.H 8.%.@ IX$Xh.o.oXdXdXdXd.oXh 2 I 8.^.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.~.p [Xu.y ] x.e * &.8Xp.5.3 ~.<.S XX2X< Q #.Y E.GXbX>.` 8.%.k 4 IX$XhXhXhXhXhX$ 2 4 8.^.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.~.pXu.y._ ].! *.w.I.8 gX5 @ ~ O.> p pX< r hXMXm.-XbX> M 8 8Xx.k.@ I I I I 4 4.k 8 1.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.p :._ ] x.e.w &.8.L.5.3 @.< O.> p . Q r h EXm.-XbX>.c.` 8 8.%XxXx.kXxXxXx m.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q e :._ ].e *.w.I.8 g.5 @ ~.<.S XX2 # # r TXM E.-.nXbX>.c.`.` 8 8 8 8.c 1.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q : ]X3.e.w &.I.8 g.3 @.G O.S XX7 # Q TXMXM EXm.-.nXbXbXb.c.c.c.n.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.7.y.e *.w.I.8 W T.3 @.G O.SX7X7 . g r rXMXMXmXmXm.-.n.nXm 1.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.J.e &.I.8 W T.3 @.G OX7X7 p W . r r rXMXMXMXM.^.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.J.J.I.8 g T @ @.G.<.S X p p .X@X@X@.GX=.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.I.L g T @ @.G.<.SX;X;X=.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q"
+};
diff --git a/arts/builder/pics/Synth_AUTOPANNER.xpm b/arts/builder/pics/Synth_AUTOPANNER.xpm
new file mode 100644
index 00000000..89506f3b
--- /dev/null
+++ b/arts/builder/pics/Synth_AUTOPANNER.xpm
@@ -0,0 +1,292 @@
+/* XPM */
+static char * Synth_AUTOPANNER_xpm[] = {
+"64 64 225 2",
+" c None",
+". c #161E54",
+"+ c #B2821C",
+"@ c #465284",
+"# c #2E3A74",
+"$ c #D2B624",
+"% c #8A662C",
+"& c #32465C",
+"* c #5E6AB4",
+"= c #CE9E14",
+"- c #222E64",
+"; c #4E5E94",
+"> c #42528C",
+", c #364684",
+"' c #36324C",
+") c #424A7C",
+"! c #CE8A14",
+"~ c #2A3674",
+"{ c #32427C",
+"] c #FACE14",
+"^ c #F6A204",
+"/ c #4E568C",
+"( c #2A2E5C",
+"_ c #1A2664",
+": c #3E4E84",
+"< c #CA9614",
+"[ c #363A64",
+"} c #F6B60C",
+"| c #3A468C",
+"1 c #D2AA1C",
+"2 c #4A5A94",
+"3 c #22265C",
+"4 c #FAC20C",
+"5 c #AA7E24",
+"6 c #5A62AC",
+"7 c #4A529C",
+"8 c #2E3A7C",
+"9 c #2A3274",
+"0 c #AE922C",
+"a c #222E74",
+"b c #3E467C",
+"c c #424A94",
+"d c #324284",
+"e c #FEDA14",
+"f c #FABE0C",
+"g c #222A6C",
+"h c #52526C",
+"i c #6A76BC",
+"j c #DEA214",
+"k c #525EA4",
+"l c #F6B20C",
+"m c #4E569C",
+"n c #2A325C",
+"o c #D69A14",
+"p c #AE8A2C",
+"q c #46568C",
+"r c #DE920C",
+"s c #FEB604",
+"t c #222A54",
+"u c #BA8224",
+"v c #926E34",
+"w c #D2A61C",
+"x c #CE9214",
+"y c #D29614",
+"z c #B27A24",
+"A c #2E3E7C",
+"B c #222A64",
+"C c #B2861C",
+"D c #4A567C",
+"E c #6672BC",
+"F c #D69E14",
+"G c #26326C",
+"H c #46529C",
+"I c #3A4A7C",
+"J c #2A367C",
+"K c #3A4274",
+"L c #FED614",
+"M c #FEAA04",
+"N c #3A4A8C",
+"O c #D2B224",
+"P c #424E8C",
+"Q c #2A326C",
+"R c #162254",
+"S c #323E74",
+"T c #926A34",
+"U c #3E4674",
+"V c #666EB4",
+"W c #D2A21C",
+"X c #262E64",
+"Y c #4E629C",
+"Z c #46528C",
+"` c #424E7C",
+" . c #FED214",
+".. c #F6A604",
+"+. c #4E5A8C",
+"@. c #1E2A6C",
+"#. c #363E84",
+"$. c #F6BA0C",
+"%. c #DAAA1C",
+"&. c #FECA0C",
+"*. c #4A568C",
+"=. c #263274",
+"-. c #3E4A7C",
+";. c #3A428C",
+">. c #FEE21C",
+",. c #5662A4",
+"'. c #4E5A9C",
+"). c #262A54",
+"!. c #B27E24",
+"~. c #464E8C",
+"{. c #B6821C",
+"]. c #4A527C",
+"^. c #323A6C",
+"/. c #8E6A2C",
+"(. c #626EB4",
+"_. c #D29E14",
+":. c #3A467C",
+"<. c #32366C",
+"[. c #CE8E14",
+"}. c #2E366C",
+"|. c #364274",
+"1. c #FECE0C",
+"2. c #2A2E6C",
+"3. c #1E2664",
+"4. c #CE9A14",
+"5. c #3A3E64",
+"6. c #D2AE1C",
+"7. c #FEC60C",
+"8. c #5A66AC",
+"9. c #BA961C",
+"0. c #4E567C",
+"a. c #3A4674",
+"b. c #FEAE04",
+"c. c #DE9614",
+"d. c #6E7ABC",
+"e. c #DAA61C",
+"f. c #3A364C",
+"g. c #FEDE14",
+"h. c #FEBA04",
+"i. c #D29A14",
+"j. c #D69214",
+"k. c #FEB204",
+"l. c #1A2264",
+"m. c #363E74",
+"n. c #4A569C",
+"o. c #8E6624",
+"p. c #AE7E1C",
+"q. c #323A84",
+"r. c #364284",
+"s. c #2E325C",
+"t. c #323E7C",
+"u. c #3E4A8C",
+"v. c #1A225C",
+"w. c #42466C",
+"x. c #464E7C",
+"y. c #525A94",
+"z. c #525AA4",
+"A. c #B67E1C",
+"B. c #626AB4",
+"C. c #FAA204",
+"D. c #CE9614",
+"E. c #FAB60C",
+"F. c #3E468C",
+"G. c #FEC20C",
+"H. c #262E74",
+"I. c #FEBE0C",
+"J. c #565EA4",
+"K. c #966E34",
+"L. c #D29214",
+"M. c #262A64",
+"N. c #B6861C",
+"O. c #2E367C",
+"P. c #2E326C",
+"Q. c #52629C",
+"R. c #FAA604",
+"S. c #FABA0C",
+"T. c #D28E14",
+"U. c #5E66AC",
+"V. c #222E6C",
+"W. c #4E5E9C",
+"X. c #425294",
+"Y. c #4E5694",
+"Z. c #2A2E64",
+"`. c #3E4E8C",
+" + c #4A5A9C",
+".+ c #2E3A84",
+"++ c #2A327C",
+"@+ c #3E4684",
+"#+ c #222A74",
+"$+ c #2A3264",
+"%+ c #465694",
+"&+ c #222A5C",
+"*+ c #4A5684",
+"=+ c #3A4A84",
+"-+ c #3A427C",
+";+ c #424E94",
+">+ c #262E6C",
+",+ c #465294",
+"'+ c #4A5694",
+")+ c #26327C",
+"!+ c #3E4A84",
+"~+ c #5662AC",
+"{+ c #4E5AA4",
+"]+ c #262A5C",
+"^+ c #464E94",
+"/+ c #B68224",
+"(+ c #4A5284",
+"_+ c #323A74",
+":+ c #D29E1C",
+"<+ c #3A4684",
+"[+ c #2E3674",
+"}+ c #36427C",
+"|+ c #FECE14",
+"1+ c #1E266C",
+"2+ c #D2AE24",
+"3+ c #4E5684",
+"4+ c #6E7AC4",
+"5+ c #FEDE1C",
+"6+ c #FEBA0C",
+"7+ c #D29A1C",
+"8+ c #36428C",
+"9+ c #323E84",
+"0+ c #3E4A94",
+"a+ c #464E84",
+"b+ c #B67E24",
+" =.9 9 ++++=.H.a #+g @.3. ",
+" &+_+r.r.q..+8 J )+H.=.H.a a g a l.. . . ",
+" <.) 0+F.;.r.9+.+O.O.J )+=.H.#+a @.@.@.1+l.l.. . ",
+" _+'.n.%+;+c | 8+#.q..+8 J )+H.a a a #+a a #+@.@._ l.. . . . ",
+" y.J.k m 7 ;+0+| 8+d q.O.J J J ++=.H.a #+@.@.@.@.#+@.@.1+1+l.. . ",
+" Y.B.8.~+z.m H ;+c F.8+#.9+.+O.++=.=.H.a V.a #+#+#+1+@.@.1+@.1+@.l.. . . ",
+" (.(.* 6 J.{+n.^+c F.| 8+9+q..+O.++)+)+H.H.#+V.@.@.#+1+@.@.1+@.1+@.1+_ l.. . ",
+" P i E B.U.~+k {+n.H 0+N ;.#.q.A 8 J J 9 =.=.a a #+a #+@.#+1+1+@.1+@.1+1+1+1+l.. . . ",
+" K i E E * 8.~+z.m H ^+c F.| r.q..+8 J )+)+H.a H.a #+V.#+@.@.@.1+@.1+1+_ 1+1+_ 1+l.. . . ",
+" / d.E E * 8.6 k {+n.,+;+0+| 8+#.9+O.J ++++H.)+H.a g #+@.@.@.@.@.@.1+@.@.@.1+@.@.1+@.l.. . . ",
+" K E i V V * 8.k z.n.7 ;+0+F.;.8+9+9+.+O.~ ++H.H.a a V.#+a #+@.@.1+#+1+_ 3 @._ 1+@._ 1+_ l.. . . ",
+" x.d.i E V * 8.J.k '.n.H ;+u.| r.9+9+8 O.J ++=.=.=.H.a @.#+@.@.1+1+@._ 3.% < 5 3._ 1+1+@.1+1+l.. . . ",
+" V E V (.U.U.~+J.{+n.,+^+c 0+| 8+9+q.8 8 J J )+a a a a a @.@.#+@.#+@.@.@.t C $.9.& @._ 1+_ 1+_ l.. . ",
+" E E E (.* 8.~+k {+n.7 ^+`.u.;.8+#.q..+.+J J =.H.H.X Z.B @.M.B @.@.3.@.M.3.3 ' j 4 9.&+@.@.@.1+1+@.l.. . ",
+" ) V B.B.U.8.J.k z.m 7 ^+c F.| ;.r.#.q.O.J ++++=.=.>+p 1 w 1 W W W W _.W = = 4.F S.G.E.+ ]+@.a @.@.@.@._ l.. ",
+" B.* U.8.~+k k z.n.7 H ;+c N | r.#.9+8 8 J J =.)+a Z.1 L L . .1.&.&.&.7.7.G.G.G.G.I.G.l o.- g V.#+g g @.. . ",
+" Y.U.8.~+J.J.z.{+n.%+;+;+0+F.| ;.9+9+q.O.O.J ++=.H.H.X 1 L &.1 w w W W = _._._._.F f I.E.+ ]+a a V.a V.#+V.@._ . ",
+" #.6 ,.k z.k {+ +n.7 ^+;+0+0+| ;.9+#.8 8 8 J =.=.)+=.=.Q 1 .6.s.n X $+Z.$+$+$+$+X f.j S.+ ( G G =.=.>+a >+a g g v.. ",
+" ~.z.z.{+m n.7 H H ;+c 0+| ;.8+r.9+q..+J J J ++=.=.)+=.s.1 .w Z.9 =.=.9 =.)+=.=.n + l {.n 9 9 =.=.=.=.=.>+=.G V.g _ ",
+" {+n.n.m n.7 H ^+;+c 0+F.;.8+#.9+q..+O.O.++++=.9 ++=.++Q w .W }.=.~ ~ J J ~ J Q % D.p.n 9 ~ J 9 9 ~ 9 =.=.H.H.V.G v. ",
+" }.n.n.H H ,+;+;+0+0+F.;.| ;.#.q.A q.8 J J 9 ++)+=.=.=.~ P.w .W }.++J ~ ~ J ~ ~ ~ ~ }.}.~ J ~ ~ ~ ~ ~ ~ ~ ~ =.9 >+Q V._ ",
+" ^+;+;+;+c 0+c 0+F.| | r.#.9+9+9+.+8 J J 9 )+~ 9 )+++++9 }.w .w ~ # J J J O.O.8 8 [+# 8 8 8 8 8 8 J J ~ ~ ~ ~ ~ ~ =.- . ",
+" 3 0+c 0+u.F.N | | ;.r.8+#.9+9+q.O.J O.J ++~ )+)+9 ~ ~ J ~ }.w 1.W }.~ 8 8 8 8 8 8 A 8 8 8 8 8 8 8 # 8 8 O.~ ~ ~ ~ ~ 9 ~ G 3. ",
+" q.F.| F.| | ;.;.8+r.#.#.9+9+8 O.8 O.++9 ~ )+9 9 J )+J ++J <.w 1.w <.8 8 8 8 A q.t.q.9+A A 8 A A 8 A 8 8 8 8 8 J J ~ ~ Q X . ",
+" S ;.8+;.;.8+r.#.9+9+9+q.q.O.8 O.J J )+)+=.++J 9 J 9 J J 8 <.w &.W ^.8 A A q.A A A t.t.9+t.t.t.t.t.t.t.A t.8 _+8 [+~ J ~ 9 G ",
+" 8+9+#.9+9+#.9+9+9+q..+8 J 8 J ++J =.9 9 ++~ =.J J J 8 ~ J ^.W 1.W _+9+9+9+t.t.#.r.d #.}+r.#.9+d 9+9+t.t.A t.A 8 A 8 # ~ ~ 9 ",
+"H.9+9+q.9+q.q.q..+8 8 8 O.J J J )+++)+=.=.)+J ~ J ~ J 8 8 J ^.W 1.W ^.t.t.d r.9+t.#.d d d d }+r.}+}+d r.#.t.t.t.8 t.8 # # # # ~ ",
+"9 q..+.+.+8 8 8 O.J J J J ++++=.9 =.=.)+J ++9 )+J 8 J 8 8 q.^.W &.W m.9+d 9+d r., , r.r.;.<+, r.r.r.r.}+d }+r.}+{ t.t.t.8 # J ~ ",
+"=.O.8 O.J J J J O.++++J )+=.)+H.H.H.H.=.=.J ~ ++J 8 J 8 A 8 m.W &.W m.#.r.r., r.r.<+<+, , <+<+<+, <+, <+r.r.d #.t.t.t.A 8 _+# [+",
+"J J ++J J J ++J )+J =.$+~ Q s.Q Q $+Q $+}.Q }.}.}.}.^.^.^.m.[ w 7._.K , , , r.<+<+<+| <+<+<+| , <+<+<+, , , -+, }+r.t.t.t.A 8 # ",
+"9 J ++++++J ++9 =.)+Q 0 $ O O O O O 2+6.6.1 1 1 1 w w W W W e.4 7.= m.r.;.<+, , N =+N N N =+u.N N | <+<+<+, r., r.r.}+{ t.A 8 8 ",
+")+H.)+=.=.H.=.)+H.H.2.$ >.>.>.5+g.e e L L L L .|+ .|+1.1.&.&.7.7.:+K <+, , | u.| N u.u.u.u.N u.u.=+u.N =+N =+<+, , r.#.{ t.t.# ",
+"=.H.=.H.=.a H.H.H.a 2.0 O O O 6.2+2+2+1 1 1 w 1 w W w W W _.e.4 7.W K N N u.N N u.u.u.`.`.P `.`.`.`.: u.!+F.=+<+<+, , r.}+{ { t.",
+"a a a a a H.a a a H.g X X X X Z.Z.Z.$+P.P.}.^.<.^.^.^.S m.|.5.j G._.:.| @+N u.`.`.`.`.`.`.`.P `.P `.c `.u.: u.=+<+<+<+-+r.#.#.8 ",
+"a a a a a a a a V.a #+V.g #+#+V.=.H.=.=.++~ 8 J A 9+t.t.t.d |._.G.i.U N u.N u.u.`.P P ;+> > P ;+P > `.`.u.u.`.!+!+<+=+, , }+}+t.",
+"g #+#+#+#+#+V.a @.#+V.#+a V.V.a a =.=.J ~ J J 8 8 8 9+d r.r.K :+G.:+:.N N `.P > P X.X.> X.X.,+> X.P > > > : c `.N =+<+<+:.r.}+t.",
+"@.a V.a V.#+@.a @.@.@.@.@.@.#+V.a =.=.J ~ J 8 8 t.q.t.9+r.r.|.:+G.i.b `.`.`.`.X.> > ,+,+Z %+%+,+%+X.X.X.> > `.P u.N =+<+<+, , }+",
+"3.g #+@.#+g #+g #+#+#+@.@.#+V.#+H.H.=.=.J 8 8 8 8 t.9+r.r., -+_.G.:+-.`.P X.;+X.X.,+%+%+%+,+,+%+,+q ,+> ,+> > `.P : u.=+=+<+-+t.",
+" @.#+@.@.@.@.@.@.@.1+1+@.@.a a =.H.9 =.~ J 8 A A 9+{ r.r.<+K i.I.i.b `.`.> P ,+X.,+,+%+2 2 %+2 %+%+'+%+,+Z Z > P `.u.=+<+, <+ ",
+" @.@.@.@.#+1+@.@.@.#+#+1+#+g V.a =.~ J J 8 8 q.9+{ 9+d , , :._.G.7+) `.;+X.%+,+%+%+2 2 %+%+2 %+n.2 %+%+%+X.X.P P P : !+!+<+, ",
+" . 1+#+1+#+#+1+@.@.@.@.@.g a a H.H.=.9 J O.8 8 9+#.r.r.r.<+:.i.I.4.) > P X.%+%+%+%+%+ + + ++. +2 2 2 %+'+q %+Z > P `.`.!+<+S ",
+" v.@.@.@.@.1+@.1+1+1+1+1+@.g V.=.=.9 J ~ 8 8 t.t.{ r.r.| <+K i.I.i.) ;+,+Z %+%+2 + +2 W. +W.; '.'.2 2 2 %+q %+> > P !+!+a.X ",
+" l.@.1+@.1+@.@.@.@.@.@.@.#+a =.=.=.J J 8 8 8 9+t.r.r., N :.i.6+7+: > X.X.%+%+'+2 +*++.*+W.W.W.'.W.2 +%+%+,+X.P P `.=+<+ ",
+" v.1+@.1+@.1+1+1+1+1+@.#+V.V.a =.~ ~ # J 8 9+t.d d , ;.<+U 4.I.4.) > ,+%+%+n.2 2 *.T [.!.].; Y W. +2 2 '+%+q Z > > : `.n ",
+" l.@.1+@.@.@.@.@.1+@.@.#+H.a =.=.++# 8 8 A 9+r.r., <+| b i.h.i.) > ,+,+2 %+ ++.W.@ u ^ /+].Y Q.W.'.W.2 %+%+%+> P P : ",
+" _ _ @.1+1+_ _ _ 1+@.g V.V.=.=.++~ J 8 8 q.t.t.d r., =+a.D.h.o ) ` @ @ @ q *.*+*+(+h c.R.b+D W.Y ; 2 2 2 %+> X.> `.|. ",
+" . l.1+_ 1+1+1+@._ 1+g a V.a =.~ ~ ~ 8 A t.9+#.}+r.8+N b 7+h.k.o D.y L.L.L.x L.L.x y R.M C.u ].Y W.'.2 2 '+Z Z P P :. ",
+" 1+@.@.@.@.1+_ 1+@.@.@.H.H.=.=.)+J # 8 8 t.{ r., <+<+a.D.6+6+s s k.s k.k.k.b.b.b.M M M M ^ K.+.W.W.+.'+%+%+> > I ",
+" . 1+1+@.1+1+1+1+g @.V.G =.~ ~ J 8 8 t.9+{ r.r., <+:.5 D.y L.D.x L.L.L.L.x T.T.j.R.M ^ A.].; W. +2 2 q ,+Z : ",
+" _ 1+_ _ 1+@._ @.@.V.a a H.=.~ ~ [+8 8 t.9+r., ;.N <+b b -.` a+x.@ @ @ *+3+*+D h c.C.A.].k W.2 2 2 %+,+q > }. ",
+" l.1+@._ @.1+@.@.g V.=.=.=.~ J # 8 8 t.t.t., }+<+<+u.u.u.`.X.> Z '+%+%+ + +].A.^ A.].; Q.; W.2 '+%+Z > P ",
+" _ _ 1+_ 3.1+1+@.g V.H.=.9 ~ J 8 8 t.t.r.r., <+<+=+u.`.P P X.%+%+%+2 2 *+T ! z ].; W.2 W.2 2 2 q q > ",
+" . l.1+_ _ @.@.@.g V.H.=.~ ~ ~ 8 8 t.t.t.r.r., <+=+N !+`.P P X.,+%+'+%+%+@ @ *+'.; W.2 2 '+%+%+X.P a. ",
+" . _ 1+1+1+1+g V.a G =.=.~ J # 8 8 A 9+}+r.<+| =+!+`.`.`.> > q ,+%+%+'+2 2 +2 2 2 2 '+2 q q @ }. ",
+" . . 3.3.@.@.g #+V.=.=.~ J # 8 q.S t.{ d , ;.<+<+!+u.`.`.P > > %+q %+'+'+2 '+'+'+2 %+'+,+> a. ",
+" v._ _ 1+1+V.V.H.>+=.9 9 ~ # A A t.9+}+}+, , <+| : u.P `.P > Z ,+,+q q %+%+%+%+,+Z > > }. ",
+" . R @.1+@.V.a >+=.~ ~ J ~ 8 8 t.t.#.}+r., <+<+=+N `.`.P P > > X.X.Z q q q q %+Z > a. ",
+" l.@.g @.V.=.G =.=.~ O.[+8 t.t.{ { r.<+, | @+!+!+`.`.`.`.> > Z X.> X.> > > > ",
+" . @.@.g V.>+9 =.~ ~ # # 8 q.t.}+t.}+, , <+=+<+!+`.: c P `.> P P P P : :. ",
+" @.V.g a G G ~ ~ J J # A t.t.{ r.}+, , <+N <+!+!+: !+P !+`.P `.: ",
+" _ - a =.>+9 ~ [+8 # 8 A t.t.{ }+r.r.<+<+<+=+=+!+=+`.: : !+:. ",
+" @.G =.=.~ ~ ~ # # q.t.t.#.}+}+}+<+, <+<+=+!+<+}+ ",
+" &+- =.~ ~ O.# # q.A t.}+r.{ }+r.<+, S { ",
+" 9 ~ # # # _+8 A S #.}+}+ "};
diff --git a/arts/builder/pics/Synth_BUS_DOWNLINK.xpm b/arts/builder/pics/Synth_BUS_DOWNLINK.xpm
new file mode 100644
index 00000000..60596d77
--- /dev/null
+++ b/arts/builder/pics/Synth_BUS_DOWNLINK.xpm
@@ -0,0 +1,323 @@
+/* XPM */
+static char * BUS_DOWNLINK_xpm[] = {
+"64 64 256 2",
+" c None",
+". c #161E54",
+"+ c #828698",
+"@ c #35427C",
+"# c #8A4664",
+"$ c #F5C224",
+"% c #52629C",
+"& c #96162C",
+"* c #CA8419",
+"= c #5C4644",
+"- c #612244",
+"; c #43528C",
+"> c #28326C",
+", c #C6A254",
+"' c #3A3658",
+") c #E0E2E4",
+"! c #A0A2B4",
+"~ c #52424C",
+"{ c #303A73",
+"] c #8E6644",
+"^ c #3C4A84",
+"/ c #EC920C",
+"( c #BEBEC9",
+"_ c #525A7C",
+": c #6D7294",
+"< c #EEA20C",
+"[ c #ECB624",
+"} c #BEC2CC",
+"| c #B68234",
+"1 c #D70A14",
+"2 c #9E6624",
+"3 c #D1D2D6",
+"4 c #565A7C",
+"5 c #62668C",
+"6 c #343267",
+"7 c #3E4274",
+"8 c #BE9644",
+"9 c #741E3C",
+"0 c #B0B2C0",
+"a c #4E2C54",
+"b c #515677",
+"c c #F1F2F4",
+"d c #F5AA16",
+"e c #9396A5",
+"f c #2E3A7D",
+"g c #202A6D",
+"h c #273276",
+"i c #EA1214",
+"j c #A27A4C",
+"k c #364285",
+"l c #3E4A8E",
+"m c #F69604",
+"n c #DADADD",
+"o c #5662AB",
+"p c #455295",
+"q c #3C366A",
+"r c #4B5A97",
+"s c #EB060C",
+"t c #CD8A1D",
+"u c #6F4E37",
+"v c #464A7C",
+"w c #B8BAC4",
+"x c #7A5A4C",
+"y c #552E54",
+"z c #F6BA24",
+"A c #C7CAD3",
+"B c #565A8C",
+"C c #525AA1",
+"D c #868AA4",
+"E c #AE2C40",
+"F c #E9EAEC",
+"G c #F8A208",
+"H c #262E73",
+"I c #363A6B",
+"J c #7A7EA4",
+"K c #EA9A14",
+"L c #6672BC",
+"M c #BA923C",
+"N c #6A6E97",
+"O c #841E38",
+"P c #B6B6C5",
+"Q c #FAFAFC",
+"R c #FBAA04",
+"S c #363E82",
+"T c #B57E35",
+"U c #866284",
+"V c #AE0E1C",
+"W c #2E3264",
+"X c #A6AABC",
+"Y c #966634",
+"Z c #C29A4C",
+"` c #9A9EAD",
+" . c #222E71",
+".. c #2E367A",
+"+. c #3A4586",
+"@. c #424E8E",
+"#. c #5E6AB4",
+"$. c #4A5597",
+"%. c #3B3E6C",
+"&. c #EE0E14",
+"*. c #464E92",
+"=. c #1E266B",
+"-. c #7C82A4",
+";. c #D68611",
+">. c #682644",
+",. c #B98A41",
+"'. c #AE6E1C",
+"). c #D6D6DE",
+"!. c #722644",
+"~. c #B2B6C0",
+"{. c #323E7E",
+"]. c #DEDEE1",
+"^. c #5A62AC",
+"/. c #F70204",
+"(. c #8A5E34",
+"_. c #CECED5",
+":. c #FEA304",
+"<. c #3A4279",
+"[. c #664E44",
+"}. c #424A7C",
+"|. c #FEB204",
+"1. c #323666",
+"2. c #3E468A",
+"3. c #7A203A",
+"4. c #4E569B",
+"5. c #F6F6F7",
+"6. c #9A9AAC",
+"7. c #2A3678",
+"8. c #4E5E9C",
+"9. c #9E9EAC",
+"0. c #7A5234",
+"a. c #464E6C",
+"b. c #764E74",
+"c. c #6A5684",
+"d. c #66565C",
+"e. c #CE9224",
+"f. c #4A3E48",
+"g. c #A21224",
+"h. c #D29A28",
+"i. c #926E44",
+"j. c #965A7C",
+"k. c #DA8E14",
+"l. c #662A44",
+"m. c #E2060C",
+"n. c #BE0E1C",
+"o. c #5E6A9C",
+"p. c #747A9C",
+"q. c #866E54",
+"r. c #865A30",
+"s. c #BE7A1C",
+"t. c #926A4C",
+"u. c #A66E2C",
+"v. c #585E7C",
+"w. c #FA9E07",
+"x. c #6E7AC0",
+"y. c #EA1A24",
+"z. c #626AB4",
+"A. c #5D6284",
+"B. c #636EB4",
+"C. c #3E3E5C",
+"D. c #4A4668",
+"E. c #B28E5C",
+"F. c #654A39",
+"G. c #AE7C3C",
+"H. c #F29A07",
+"I. c #FEC214",
+"J. c #565EA4",
+"K. c #6A1E3C",
+"L. c #463A64",
+"M. c #8E6244",
+"N. c #F6B21C",
+"O. c #4A5281",
+"P. c #F2A214",
+"Q. c #FEBD14",
+"R. c #D2821C",
+"S. c #E6E6E9",
+"T. c #A6A6BC",
+"U. c #C6C6D2",
+"V. c #5E5674",
+"W. c #F20204",
+"X. c #EEEEF1",
+"Y. c #B61224",
+"Z. c #AEAEC4",
+"`. c #8285AC",
+" + c #B6721C",
+".+ c #FE0204",
+"++ c #C20E1C",
+"@+ c #FEB614",
+"#+ c #727694",
+"$+ c #A66A24",
+"%+ c #E6060C",
+"&+ c #19225C",
+"*+ c #EAA61C",
+"=+ c #656A91",
+"-+ c #A67E3C",
+";+ c #474E81",
+">+ c #F7BE1F",
+",+ c #CACED8",
+"'+ c #9A6A34",
+")+ c #525E8C",
+"!+ c #525EA3",
+"~+ c #868EAC",
+"{+ c #363E6D",
+"]+ c #2E3666",
+"^+ c #3A467C",
+"/+ c #BE7E2C",
+"(+ c #F29E10",
+"_+ c #921A34",
+":+ c #A2A6B5",
+"<+ c #323E74",
+"[+ c #3E4E84",
+"}+ c #B8863C",
+"|+ c #D2D6DC",
+"1+ c #414679",
+"2+ c #F2F6F4",
+"3+ c #F6AE14",
+"4+ c #969AAA",
+"5+ c #EE161C",
+"6+ c #364684",
+"7+ c #3E4E8C",
+"8+ c #DADEDE",
+"9+ c #5366A4",
+"0+ c #465694",
+"a+ c #3A3A64",
+"b+ c #CE8E1C",
+"c+ c #72523C",
+"d+ c #7E5E44",
+"e+ c #585E86",
+"f+ c #EAEEF0",
+"g+ c #F9A606",
+"h+ c #FDAE08",
+"i+ c #AF7224",
+"j+ c #F6060C",
+"k+ c #72527C",
+"l+ c #BA1224",
+"m+ c #662240",
+"n+ c #FAB614",
+"o+ c #46568C",
+"p+ c #2A366C",
+"q+ c #EE960C",
+"r+ c #C2C6CC",
+"s+ c #76223C",
+"t+ c #FA9A04",
+"u+ c #BABEC4",
+"v+ c #E69E14",
+"w+ c #6A76BC",
+"x+ c #FEFEFC",
+"y+ c #AAAEBC",
+"z+ c #C49E4C",
+"A+ c #7E86A4",
+"B+ c #5B66AC",
+"C+ c #D29624",
+"D+ c #DE0A0C",
+"E+ c #423E74",
+"F+ c #DE860C",
+"G+ c #925E2C",
+" &+h h h h h H .g g g =. ",
+" =.H ..{.S f f ..h H h H H .=.. . . . . ",
+" > <.1++.k k S f ....7.h h .g .g g =.=.&+. . . ",
+" W *.4.p *.l l k S f f f 7.h H .H H g .g g g g =.. . . . . ",
+" v !+C 4.p @.l 2.k k f ..7.7.7.h h . .g g .g g g =.=.&+&+&+. . ",
+" ;+B+B+J.!+4.$.*.2.2.k S S f ..h h h .H . . .g g =.g g g g g =.. . . . ",
+" J.o.#.B+!+C $.*.*.l 2.k S f f ..h h h .H g g g g g =.g g =.=.g =.=.&+&+. . ",
+" 7 L B.B.B+o !+4.$.p l 2.k S f S f 7.7.h h h . . .g g g g g =.g g =.=.=.g =.. . . . ",
+" 7 w+w+B.z.^.J.!+4.p *.l 2.6+k f f f ..h h H H H g .g g g =.g =.=.g g =.=.=.=.=.&+. . . ",
+" 4.x.L B.B.#.o !+4.4.*.7+l 2.k S S ..7.h h H h . . .g g g g g g g g =.=.=.=.=.=.=.g &+. . . ",
+" 7 : w+L z.B+B+o !+4.0+*.l 2.k k S {.f ....h H H . . . . .g g =.g =.g g g &+g =.=.=.=.=.&+. . . ",
+" @.x.w+L B.z.B+o C 4.4.*.7+l 2.k S S f ..7.h h h H H g g g g g g g =.g &+=.=.g =.g =.=.=.=.=.&+. . . ",
+" B+w+B.B.#.B+o !+C 0+p *.l 2.2.k {.f f f 7.7.h h .H .g g g g g g g g g g g =.&+g g g =.=.=.=.&+. . ",
+" B.B.B.B.z.B+o !+C 4.$.p l l 2.k S f f f 7.7.h . . . .g .g g g g g g g g g g . .g g g g g =.=.g . . . ",
+" 1+z.z.z.B+o o !+C r p *.*.l 2.k k S f ....h h h h H . .g . .g g g g .g .g g g .g g .g .g g g =.=.. . ",
+" #.#.B+o J.!+C 4.4.*.*.l l k k S S {.f 7.h h H h g . .g .g g . . . .g .g . . .g . .g .g g g =.g =.. . ",
+" v % B+o.`.~+D `.-.-.J J #+#+: : =+o.5 5 5 A.A.e+e+4 B 4 b b 4.b o+b o+_ o+b o+b o+_ O.b O.b b O.b b b a.g g =.. ",
+" S ^.J.C J F c c c c c c X.f+F X.F X.F F F S.S.) ].].].n n n n n ).).|+|+3 |+3 3 3 3 ,+3 3 3 3 ,+3 ,+,+,+y+{+g &+. . ",
+" }.J.C 4.J X.Q x+x+Q Q Q Q x+Q x+Q Q x+Q Q x+Q Q 5.5.c c c X.f+X.X.F F F F F F S.S.S.F F ) S.) S.) S.) ) r+}. . .g =. ",
+" $.4.$.$.N A |+3 3 3 3 3 _.,+,+A A A U.U.U.} r+} } ( ( u+w w w w w w ~.w ~.~.~.~.~.~.0 0 ~.~.~.0 ~.0 0 0 :+b > H =.. ",
+" W @.$.p p *.*.O.*.;+v 1+1+7 7 S %.I I I { 1.6 6 W ]+]+W W h W ]+W 6 1.]+]+1.1.1.]+W ]+1.]+]+]+]+W W 1.]+W > > > > . .. ",
+" *.*.*.*.l V.E.z+, z+z+z+Z Z 8 ,.d.D.j ,.,.,.,.,.}+}+| | x a+t.T | | | T T | T G.] I d+G.T T T T T T G.s.'+W > > > > g . ",
+" &++.l l l 2.v t.[ $ $ $ $ >+z z N.T M.-+*+3+3+3+3+d d *+g+* u u ;.K P.g+< < G G (+k.u F. +q+w.G G (+w.(+(+/ u W p+p+> > H &+ ",
+" f l 2.k 2.+.k v E.$ I.I.I.Q.Q.Q.n+3+C+t.$+v+|.|.h+h+h+h+g+G R.~ r.;.H.:.g+:.g+G G m ;.= u +t+:.w.:.:.:.w.m F+F.W h 7.> .. ",
+" > k 2.k k k S 7 q.[ >+Q.Q.Q.z n+n+3+v+Y ~ ;.3+h+R R R R R G H.G+f.$+H.:.:.:.g+:.G G t+2 = 0./ :.w.w.w.w.w.w.m '.f.]+f p+> H ",
+" S k S S S S S %.-+h.h.C+h.e.e.e.e.t (.' '+t t b+t t * t * * 2 ' r.s.* * * * R.* * * '.C.F.i+s.* * R.R.* * s. +f.]+f 7.]+> &+ ",
+"=...{.f S f f f I I I {+I I I ' ]+]+> > H W 1.]+1.1.I I { 1.6 6 1.1.I {+{+I {+I {+{+{+{+<+<+7 {+a+{+{+a+I {+a+I { f {.f f { p+g ",
+"h f f f f f ..;+T.P P ~.0 ~.0 0 0 0 0 0 0 0 y+Z.y+y+X ` B b.E Y.Y.E c.=+! X :+X :+T.X :+:+X :+:+:+:+:+:+:+:+:+4+_ {.{ <+f { p+..",
+"7...f ........e+) 2+c 5.c 5.2+c X.X.c X.X.X.F f+F F S.n N j.5+j+j+y.U -.|+) ].) ].].].].n ].].) 8+8+8+8+n n n A _ {.{.{.f { { 7.",
+"h h ..7.7.7.h B n c 5.5.5.2+5.c c c X.c X.X.X.F X.F S.A B # &././.i b.: _.) ) ].].].].8+].n ].n n n n n n n n u+a.{.{.{.{.{.{.{ ",
+"h h h h h h H 1+e ! ! ! 9.9.! 9.9.` ` ` ` ` 9.6.` ` ` + I >.s .+/.m.y v D 4+6.4+4+4+4+4+4+4+4+4+4+4+4+e e e e -.^+@ @ @ {.{.f { ",
+"h h h h h h h h H h h H h H H H H > > > > > 7.{ 7.{ { {.{ - W..+.+m.a {+<.@ ^+^+^+6+1+^+1+^+1+^+1+^+^+^+6+^+@ <.@ @ @ {.@ {.{.f ",
+"H H H H . . .h H .H H . . . . .H h h 7.7.7.f 7.f f {.f - %+.+.+m.a k ^ +.^ ^ l ^ 7+7+7+7+7+7+l ^ 7+[+^ ^ ^ 6+6+6+6+@ @ @ @ {.",
+" . .h .H H H . .g . . .g . .H h H h h 7.7.7.f f {.{.{ - W..+.+m.a 6++.7+l l 7+7+7+7+7+7+@.7+7+@.7+l l ^ ^ ^ +.+.6+k k {.{.f ",
+" .g . . . .g .H .g g .g g g .h h 7.h 7.f f f f f {.{ - %+/..+m.a +.^ 7+7+7+@.@.@.@.; ; @.; ; 7+; 7+@.7+l 7+^ 2.^ 6+6+@ @ {.",
+"g . . .g g H . .g g g g g . . . .h h 7.7.7.f f {.{.{.{.- %+.+/.m.a ^ ^ l 7+@.; 7+p p p p ; p ; p 7+; @.7+7+^ ^ ^ +.6+^+k @ {.",
+"g g g .g g g g g . .g g g . .h .h 7.7.f f f {.{.k {.{.- W..+/.m.a ^ 7+7+7+7+p ; ; p ; 0+p p ; 0+p ; @.; ; 7+^ [+^ +.+.+.6+@ ",
+"=.g g g .g g g g g g g g g g H .h h h 7.7.7.{.f {.{.k {.- %+.+.+m.a +.7+@.p p p p 0+0+0+p 0+0+0+; p ; p @.@.@.7+l ^ ^ ^ 6+<.{.",
+" . g g g g g g g g g g g g g .H h h h 7.f 7.f {.f { S {.- %+.+/.m.y ^ 7+l @.; 0+p p 0+r 0+0+$.r 0+0+0+o+p ; ; 7+7+[+^ ^ 6+^+ ",
+" g g g g g g g =.=.g g =.g . .h H 7.7...7.f {.f 1.9 { <+- W..+.+1 y ^ E+s+[+0+p 0+r r 0+r r r 0+r r 0+0+o+p @.; @.l ^ 2.@ > ",
+" . &+g =.=.g g g =.=.g g g g .h .h 7.f f f f f 6 n.K.1.m+%+.+.+D+y L.s+Y.}.0+0+0+0+r r r r r r r r 0+0+0+0+; @.; 7+[+^ ^ { ",
+" &+g g g g =.g g g g =.g g . . .h 7.h 7.f f {...6 1 1 K.& W..+.+W.O 3.D+++v 0+r r r r r r r 8.r r r r 0+o+0+; ; @.7+^ ^ @ H ",
+" . =.g g =.=.=.=.g =.=.g g H h H 7.7.7.7.f {.{ 6 g.W.%+W././..+/.W.W.%+_+@.0+0+r r 8.8.8.8.8.8.8.r r r 0+$.o+; ; ; @.^ ^ ",
+" &+g =.=.g g g g =.g g g . . .h h h 7.f f {.{.{.6 V /./..+.+.+/.W.%+_+}.p 0+r r 8.8.8.8.8.8.8.8.8.8.r $.0+0+; @.@.[+}.H ",
+" . g =.=.=.=.g =.=.=.g g .h h 7.7.7.f f {.{.k k 1.& %+/./..+W.1 3.1+o+r 0+r r r 8.% 8.% % 8.% 8.r 8.r o+0+o+; @.[+^ ",
+" =.=.g =.g g =.=.g g g . . .h h 7.f f f f {.{.k @ q 9 m././.1 >.1+; 0+0+r r 8.8.8.8.% % % % 8.8.8.r r $.0+p ; ; 1+p+ ",
+" . &+g =.&+g &+=.=.=.g . . .h h h 7.f {.f {.{.k k <.' 9 m.m.>.E+@.p 0+0+r r 8.8.8.% 9+9+9+9+% % 8.8.8.r o+p ; ; 7+^+ ",
+" &+=.=.g =.g g g g g g H h h h 7.7.f f {.{.k k k k <.q 3.s+7 7+; ; p r r r r 8.% % % % 9+% % 8.)+r r 0+0+o+; 7+I ",
+" . =.&+g &+=.=.=.g .g .h h 7.7.f f {.{.@ k k k +.+.<.1+l @.p o+p 0+0+r 8.8.8.% % % 9+% % % 8.r r r o+p ; [+ ",
+" &+=.g =.g =.=.g g g .> > p+7.7.7.f f {.{.@ 6++.+.^ ^ l 7+; ; p 0+0+r r r r 8.8.% % % % % 8.8.r r 0+0+; [+W ",
+" . &+=.=.=.=.g g g g . .h 7.7.f f { {.k {.6+6+6+^ ^ 7+l 7+; ; 0+0+0+r r 8.8.8.8.8.% 8.8.8.8.r r o+o+; ; ",
+" =.&+=.=.=.=.g . . .h > h p+7.f f {.{.@ k 6++.6+^ ^ 7+@.7+p ; p 0+0+r r r 8.8.8.8.8.8.r r r 0+; o+@ ",
+" . &+=.&+=.=.=.g . . .h 7.7.7.f f {.{.{.k k +.6+^ ^ l 7+7+p ; 0+o+0+0+r r 8.8.r r r r r o+o+$.; ; @ ",
+" . g g &+=.g g g .> > h p+7.f f f {.{.{.k 6++.+.^ 7+7+@.7+; ; p o+0+0+0+o+r r r r r o+r o+o+O.]+ ",
+" . &+&+=.g g g g .h h 7.7.f f { {.@ k k 6+6+6++.l [+7+7+; ; p o+o+o+r o+r r r o+r o+$.o+; @ ",
+" &+g &+=.g g .H .> > > p+f {.{.{.{.@ k 6++.^ +.^ ^ 7+7+; ; p p 0+; 0+o+o+o+r ; o+o+@.]+ ",
+" . &+=.g g . . .h 7.7.7.7.f f {.{.k k 6+k ^ ^ l l l l 7+@.; ; p ; ; ; ; ; o+p ; ; ^+ ",
+" =.g g g . .> > h p+7.7.f {.{.{.@ @ 6+k 6+^ ^ [+[+[+7+7+7+; ; ; p ; p ; ; @ ",
+" . =.g . . .> h 7.7.{ f f <+{.{.@ k k k +.+.^ l [+[+@.7+@.@.; ; ; @.[+1+ ",
+" g g g .h > p+7.p+7.f f {.{.{.@ ^+6+6+^ +.+.^ l ^ 7+[+[+7+7+[+@ ",
+" . g .> .h h 7.f { f {.{.{.{.@ 6+k 6+^ +.^ ^ ^ l ^ ^ ^ ^ ^+ ",
+" g > > p+p+p+f { f <+{.{.S S @ @ k ^++.+.+.^ ^ ]+ ",
+" . .> h 7.f f <+<+{.@ @ @ @ k 6+^+^+<+@ ",
+" > p+7.7.f { { f {.@ @ > "};
diff --git a/arts/builder/pics/Synth_BUS_UPLINK.xpm b/arts/builder/pics/Synth_BUS_UPLINK.xpm
new file mode 100644
index 00000000..3c4b45ca
--- /dev/null
+++ b/arts/builder/pics/Synth_BUS_UPLINK.xpm
@@ -0,0 +1,323 @@
+/* XPM */
+static char * BUS_UPLINK_xpm[] = {
+"64 64 256 2",
+" c None",
+". c #161E54",
+"+ c #727A8C",
+"@ c #8E162C",
+"# c #3A4A7C",
+"$ c #561A3C",
+"% c #2E3668",
+"& c #B5B6BC",
+"* c #52629C",
+"= c #6C4A34",
+"- c #C27A19",
+"; c #525274",
+"> c #3E364C",
+", c #3E1E4C",
+"' c #4A567C",
+") c #8E5664",
+"! c #35427C",
+"~ c #F29604",
+"{ c #1E2A64",
+"] c #3A4A86",
+"^ c #D00A14",
+"/ c #3A366C",
+"( c #D2D6D4",
+"_ c #2A2E5C",
+": c #8E92A4",
+"< c #DE860C",
+"[ c #4E3A3C",
+"} c #8A623C",
+"| c #464E8C",
+"1 c #DE1A24",
+"2 c #323E7C",
+"3 c #EE464C",
+"4 c #6E728C",
+"5 c #9D6A2C",
+"6 c #ED060C",
+"7 c #DA9A9C",
+"8 c #464A6C",
+"9 c #263273",
+"0 c #2B367C",
+"a c #C4C6CC",
+"b c #4E5E9A",
+"c c #F9A204",
+"d c #6C1E3C",
+"e c #6A564C",
+"f c #D28612",
+"g c #322A5C",
+"h c #364285",
+"i c #E6E6E7",
+"j c #82869C",
+"k c #3E426C",
+"l c #475695",
+"m c #202A6D",
+"n c #42528C",
+"o c #9A9EAC",
+"p c #383E71",
+"q c #EE8E0C",
+"r c #AA6A1C",
+"s c #F90204",
+"t c #232659",
+"u c #AE1224",
+"v c #5F1A3C",
+"w c #5662AB",
+"x c #424A94",
+"y c #2A3279",
+"z c #525A94",
+"A c #FC9A04",
+"B c #9A96A4",
+"C c #6E7AC0",
+"D c #323665",
+"E c #DEDEDD",
+"F c #2C3260",
+"G c #49527C",
+"H c #3E468B",
+"I c #4E569B",
+"J c #1D2664",
+"K c #BBBEC4",
+"L c #D18214",
+"M c #82562C",
+"N c #B37221",
+"O c #5E66AC",
+"P c #7B8294",
+"Q c #A21224",
+"R c #424A73",
+"S c #451E4C",
+"T c #3A426F",
+"U c #3E4E8B",
+"V c #969AA8",
+"W c #E58E0C",
+"X c #6A4634",
+"Y c #464E94",
+"Z c #636EB4",
+"` c #CECED4",
+" . c #4A2A54",
+".. c #3A428C",
+"+. c #484660",
+"@. c #262E72",
+"#. c #363E83",
+"$. c #70523C",
+"%. c #8E6234",
+"&. c #F69E04",
+"*. c #262A5C",
+"=. c #E3060C",
+"-. c #EF0A0C",
+";. c #464E77",
+">. c #323A84",
+",. c #DA8A0C",
+"'. c #FA0A0C",
+"). c #661A3C",
+"!. c #525E99",
+"~. c #2B326C",
+"{. c #7A7E94",
+"]. c #4E264C",
+"^. c #2E3A74",
+"/. c #BABAC4",
+"(. c #CA8214",
+"_. c #F69604",
+":. c #3E4A94",
+"<. c #373A67",
+"[. c #9696AA",
+"}. c #58423C",
+"|. c #FEAA04",
+"1. c #D28A0C",
+"2. c #EEEEED",
+"3. c #3F4672",
+"4. c #222E71",
+"5. c #F69204",
+"6. c #FE0204",
+"7. c #5E1E3D",
+"8. c #5A62AC",
+"9. c #72768C",
+"0. c #BE1E2C",
+"a. c #EE2E34",
+"b. c #C60A14",
+"c. c #821634",
+"d. c #7E3E54",
+"e. c #5E4A4C",
+"f. c #9B662C",
+"g. c #323254",
+"h. c #D6C6CC",
+"i. c #32265C",
+"j. c #7E5E3C",
+"k. c #423E5C",
+"l. c #8E8EA0",
+"m. c #A6A6B4",
+"n. c #626684",
+"o. c #423244",
+"p. c #961E34",
+"q. c #6A76BC",
+"r. c #4A264C",
+"s. c #625254",
+"t. c #EA9A9C",
+"u. c #582244",
+"v. c #764E34",
+"w. c #3E2E5C",
+"x. c #745640",
+"y. c #4E4A5C",
+"z. c #5E463C",
+"A. c #A46A28",
+"B. c #8A5E34",
+"C. c #D70A14",
+"D. c #3E3A64",
+"E. c #DADADC",
+"F. c #F20204",
+"G. c #B26E1C",
+"H. c #B60E1C",
+"I. c #E2DEE4",
+"J. c #865A2C",
+"K. c #E68A0C",
+"L. c #FEA204",
+"M. c #A61224",
+"N. c #4A224C",
+"O. c #EA8E0C",
+"P. c #19225B",
+"Q. c #56464C",
+"R. c #4E567C",
+"S. c #424E8C",
+"T. c #4E5A9A",
+"U. c #424E78",
+"V. c #3A467C",
+"W. c #36326C",
+"X. c #46325C",
+"Y. c #767E94",
+"Z. c #B6BAC3",
+"`. c #222E64",
+" + c #2E3A7D",
+".+ c #364684",
+"++ c #EAEAEC",
+"@+ c #4A5A94",
+"#+ c #EF9207",
+"$+ c #AE6E1E",
+"%+ c #F6060C",
+"&+ c #5266A4",
+"*+ c #9A9AAB",
+"=+ c #7E5A34",
+"-+ c #B67624",
+";+ c #5F6AB4",
+">+ c #475299",
+",+ c #6672BC",
+"'+ c #6E4E34",
+")+ c #36467C",
+"!+ c #F09A04",
+"~+ c #9296A4",
+"{+ c #6E768C",
+"]+ c #4A4E6C",
+"^+ c #868A9C",
+"/+ c #9EA2AC",
+"(+ c #FE9E04",
+"_+ c #BEC2C4",
+":+ c #9E1624",
+"<+ c #46224C",
+"[+ c #E6920C",
+"}+ c #D1D2D4",
+"|+ c #CA7A14",
+"1+ c #2A265C",
+"2+ c #4E5274",
+"3+ c #96622C",
+"4+ c #A26624",
+"5+ c #561E44",
+"6+ c #46528B",
+"7+ c #323A69",
+"8+ c #3A4686",
+"9+ c #262E64",
+"0+ c #5E4E54",
+"a+ c #96162C",
+"b+ c #D68214",
+"c+ c #52669C",
+"d+ c #F69A04",
+"e+ c #FE0604",
+"f+ c #5A66AC",
+"g+ c #D6CACC",
+"h+ c #F20604",
+"i+ c #E2E2E4",
+"j+ c #FEA604",
+"k+ c #A61624",
+"l+ c #EA920C",
+"m+ c #2A3674",
+"n+ c #47568C",
+"o+ c #2A2E6C",
+"p+ c #323E84",
+"q+ c #1E266C",
+"r+ c #535EA4",
+"s+ c #363A74",
+"t+ c #3E3E6C",
+"u+ c #1A2264",
+"v+ c #26327C",
+"w+ c #525AA4",
+"x+ c #3A427C",
+"y+ c #424E94",
+"z+ c #4E5AA4",
+"A+ c #767A92",
+"B+ c #3E4A77",
+"C+ c #C67A1C",
+"D+ c #222A62",
+"E+ c #3E4A87",
+"F+ c #D6D6DA",
+"G+ c #2E2E64",
+" u+y y y y 9 @.4.m m m J ",
+" t _ m+2 #. + +0 v+@.v+@.@.4.J . . . . . ",
+" F x+8+H ..h p+ +0 0 0 v+v+4.m 4.m m q+q+u+. . . ",
+" F | l >+y+:.H h p+>. + +0 v+@.4.@.@.m 4.m m m m q+. . . . . ",
+" x !.w+I >+Y :.H ..h >.0 0 0 0 v+v+4.4.m m 4.m m m q+q+u+u+u+. . ",
+" ;.O O r+r+I >+x :.8+h p+p+>.0 y v+v+4.@.@.4.4.m m q+m m m m m q+. . . . ",
+" !.;+;+f+r+z+I >+y+:.8+..p+>.>.0 y y v+@.4.m m m m m q+m { q+q+m J q+u+u+. . ",
+" k ,+Z Z O 8.r+z+>+>+x H ..#.>.p+ +0 0 v+v+v+4.@.4.m m m m m q+{ { q+q+q+{ q+. . . . ",
+" k q.q.Z ;+8.r+w+z+>+y+:.8+.+.. + + +0 y 9 @.@.4.m 4.m m m q+m q+q+m { q+q+q+J J u+. . . ",
+" I C ,+Z Z ;+w r+z+>+Y y+:.H h p+p+0 0 y y @.v+4.4.4.m m m m m m m m q+q+q+q+q+q+q+m u+. . . ",
+" k ,+q.,+;+O f+w w+z+l y+:.8+....p+p+ +0 0 y @.@.@.4.4.4.4.m m q+m q+m { { q+q+J q+J q+J u+. . . ",
+" | C q.,+Z ;+f+w w+z+>+Y y+:.8+..p+p+>.0 0 v+v+v+@.4.m m m m m m { q+{ q+q+q+{ { { q+J q+q+q+u+. . . ",
+" O q.Z Z ;+f+w r+z+I >+Y x H .+..p+>. + +0 m+v+v+4.@.4.m m m m m m { m { { q+q+q+m { m q+q+J J u+. . ",
+" Z Z Z Z O f+8.r+w+I l >+x :.8+..p+>.>. +0 0 v+@.4.@.4.m 4.m m m m m m m m m m m m m m { { m q+q+m . . . ",
+" 3.;+;+;+;+8.w r+z+I >+y+y+:.H ....p+>.0 0 y y 9 @.4.m m m m 4.m m m m m m m 4.4.4.m m m 4.m 4.m m { q+J . . ",
+" ;+;+;+O 8.w r+z+z+l Y y+:.H 8+h p+p+ + +0 0 @.i.v ).).$ u+4.m 4.4.4.4.4.4.4.4.4.4.4.4.4.m 4.m 4.m m 4.q+. . ",
+" x 8.8.w r+r+T.I I >+>+y+:.8+....p+p+>.0 0 0 v+@.5+C.6 6 C., 4.4.4.4.4.v+4.v+4.4.4.v+v+4.v+4.9 4.4.4.m 4.4.m J . ",
+" p 8.r+r+w+w+I I I >+Y y+x H H ..p+p+>. + +0 v+y @.v 6 e+6.=.S 4.v+v+v+v+4.v+4.v+v+9 v+9 9 4.9 4.9 9 @.9 4.4.4.P.. . ",
+" E+!.!.z+z+@+I >+y+y+:.H H .+..h p+>. +0 0 0 m+v+@.v 6 e+e+=.S 4.v+9 v+m+v+m+v+v+9 9 v+m+m+v+m+9 9 9 @.9 @.4.9 4.D+J ",
+" I I I I l >+>+>+y+x :.H .+..h p+>.>.0 0 y y v+v+@.7.6 6.6.=.S @.v+m+m+v+m+v+m+m+0 m+m+m+v+m+v+y 9 m+m+9 9 9 @.@.J . ",
+" F Y >+>+Y y+y+:.:.:.H H ..#.p+>.p+>. +0 0 v+9 y v+@.7.-.6.6.=.<+9 y v+m+m+0 0 0 0 0 0 m+ +m+^.m+0 m+9 m+m+~.9 9 9 @.`.. ",
+" Y y+y+y+y+x :.:.:.H .+..h h p+p+ + +0 0 y y y 9 y y $ 6 e+e+=.S 9 + +m+ + + + + + + + +0 +0 + +m+ +m+m+m+m+m+~.9 D+. ",
+" P.H x :.:.:.H H ...+..h p+p+>.>.0 0 0 0 v+m+v+y m+y y v 6 6.6.=.<+y 0 +0 + + +^. + + +2 +2 +^. +0 ^.0 m+m+m+m+m+~.9 @.P. ",
+" >.:.8+8+..H .+....#.p+p+p+>.>.0 +0 y y 0 v+y 0 v+m+y 7.6 6.6.=.<+m+ + +2 + +2 p+2 2 2 +2 +2 +2 2 + + + +m+^.m+m+~.`.. ",
+" ~.........#...h h p+p+>.>. + +0 0 0 y v+y m+9 m+0 0 y v 6 s 6.=.r.m+ + + +2 +2 2 p+2 p+2 2 2 p+2 2 2 2 2 + + + +^.^.m+~.9+ ",
+" p+h p+h p+p+p+p+>.>.>. +0 0 0 y 0 v+9 y 9 v+y y m+m+9 7.F.6.6.=.<+ +2 p+p+p+! p+p+2 p+! p+! p+! 2 p+2 2 2 2 2 ^. + +m+m+9 P. ",
+"t 0 p+>.>.p+>.>. + +0 0 +0 0 0 v+y v+9 v+y 0 0 v+y 0 m+5+6 s 6.=.r. +2 2 2 p+p+! ! ! h h h h ! h ! h h 2 2 2 2 2 +2 ^.^.^.m+D+",
+"v+ +>.>. + + +0 +0 0 0 v+0 v+v+v+9 9 9 m+9 9 9 _ <+m+y 7.6 6.6.=.r.^.m+r.2 ! ! h h h .+.+h .+h h h h ! h h ! p+2 2 +2 +^.m+m+",
+"y 0 0 0 0 0 0 0 0 0 0 0 v+v+9 @.@.@.@.v+0 0 0 0 g u <+W.v F.s 6.=.].W.u.Q ^..+.+.+.+h .+.+.+.+.+.+.+h .+! h ! h ! ! 2 2 ^.>.^.m+",
+"0 0 0 0 0 0 0 v+y v+v+v+9 v+@.v+v+v+v+9 9 9 m+y g ^ ^ 5+c.6 6.s F.).d ^ b.p h ...+.+] 8+8+8+8+8+8+.+.+.+.+.+.+! h 2 2 2 2 2 2 ^.",
+"y v+v+v+v+v+y v+y @.v+@.@.v+4.4.@.@.@.v+0 y 0 m+g H.F.=.F.s 6.6.F.6 F.F.Q #..+.+:..+8+:.] ] ] ] E+E+8+8+.+.+.+h .+h ! ! 2 2 +^.",
+"v+y y v+v+v+9 9 9 y @.~.9 @.@.@.@.9 9 ~.9 m+m+~.m+w.1 '.6.6.6.6.6.s '.0./ ! 8+8+8+H ] 8+8+8+] 8+8+8+] V.8+V.! )+h )+h 2 ! 2 2 +",
+"4.v+@.@.@.4.t+^+V V ~+[.[.~+~+~+~+~+: ~+: ~+~+: ~+*+t.a.%+s 6.6.s -.3 7 B ~+: : ~+: ~+~+~+: ~+: : l.: : l.: {.3.h .+.+! ! ! ! 2 ",
+"4.4.4.4.@.m R.F+++2.2.2.2.2.++++++++++i ++i i i i i+h.d.Q F.s s 6 p.) g+I.E E E E.E.E.E.E.E.E.E.E.E.E.F+E.F+K U.V.8+.+h h 2 2 +",
+"m @.@.4.@.m 2+F+2.2.2.2.2.2.++++++++++++++i ++i ++i _+t+ .Q F.F.@ X.; a E E E E E E E E.E E E E E E.E E.E.E./.;.V.H ] )+8+! ! 2 ",
+"m 4.4.m m m p l.o o *+*+*+o o *+*+o *+*+*+o V *+*+*+P 2 ^.w.Q a+<.h 3.^+o o V o o V V o V V V V V V ~+~+V B j B+] ] 8+8+)+..! 2 ",
+"q+m 4.4.m m m *.G+_ _ _ *.*._ _ G+_ 9+F g.D 7+D <.D.<.7+7+2 7+<.p T T T k 3.3.3.3.3.B+R R R R 3.R R R 3.3.8 V.B+E+E+] 8+.+8+)+! ",
+"m m m m 4.m o.$+f 1.1.f 1.,.1.1.- z.> 4+f f f 1.f f f f (.J.k.f.L f f f f f f L f A.+.} - f L f L L L f L $+3.E+E+U E+] ] )+..2 ",
+" . m m m m J [ f &.|.j+|.|.j+|.c b+M }.L L.L.j+j+L.j+L.&.O.3+Q.- d+&.L.L.(+L.(+&.#+A.0+f.O.A (+(+(+A (+A 5.A.+.B+E+E+E+H )+V. ",
+" m m m m q+m t X !+j+|.|.j+j+j+j+!+C+= '+W L.j+L.j+L.L.L.&.< $.'+- _.(+(+(+(+(+(+&.W j.e 5 #+(+(+(+(+(+(+A O.B.+.E+U E+] ! F ",
+" . u+m m m q+J [ [+&.&.&.&.&.&.&.&.L v.}.f d+&.d+d+d+_._.~ K.=+e.$+_._.d+_._._._._.q %.$.} l+_.5._.5.5.~ 5.#+f.y.S.U U B+] ^. ",
+" u+m m m q+{ t M $+G.G.G.G.G.$+G.r = g.M $+G.G.G.G.N N N G.B.k x.A.N N N N N -+N N f.]+s.f.N N -+N N N G.N 4++.B+U U E+E+! 9+ ",
+" . q+{ q+J t *.*.*._ _ _ _ _ g.F F 9 % 7+7+<.p <.t+p T T T x+3.3.R R 8 ;.8 ;.;.G ;.n+G G G G G G G G U.U.U.U 6+S.S.U E+# ",
+" u+q+q+J 3.m./.K /././././.Z./.Z.K K /./.K K /.Z.Z./.Z.Z.& /.& /.& & Z.& Z./.Z.& & & Z.& & & & & & & & & o G S.6+n U # 9+ ",
+" . q+J ]+}+++2.2.2.2.2.2.2.++++++++++++++++i i i i i i i i i+i+i i+i+I.E I.i+i+E E i+i+E E i+E E E E.E K ' n n S.S.E+ ",
+" q+{ J 8 a E E.E.E.E.E.E.E.E E.E.E.E.E.F+F+E.F+E.F+F+F+}+( ( F+}+( ( ( ( ( }+}+}+}+` }+}+}+` ` ` ` }+` & 2+n n n V.% ",
+" . u+J F n.4 4 4 4 4 4 4 4 4 9.{+4 4 9.9.9.9.9.9.9.+ A+9.A+A+Y.A+A+A+A+A+Y.Y.Y.Y.P Y.P P P Y.{.Y.A+A++ 4 U.n 6+n U )+ ",
+" J J J J J J t J { { { D+`.9+9 % % m+^.^.2 2 2 ! ! ! V.H E+E+E+S.S.n n+6+n+n+@+@+z b b b b b z @+@+n+n+n 6+n S.7+ ",
+" . u+J J J J J J m 4.@.9 @.9 m+^.^.^. +2 ! ! ..8+] ] E+E+S.n n 6+>+l l T.T.b * b * c+c+* * b b b @+n+l 6+n S. ",
+" P.{ q+q+q+q+q+m { m 4.4.9 9 m+0 0 +2 2 2 ! h 8+8+8+] U U U n n n+l @+@+b @+b * !.* * * * * z @+l @+l n U.F ",
+" . J { { J J q+m m 4.@.9 9 9 m+^. + +2 p+! h .+8+8+E+U S.y+n n l l l l @+@+b b b b b b b b @+@+l l n+n n ",
+" J J J q+q+m { m D+9 9 9 m+0 m+ +2 2 2 ! h h .+8+8+E+E+S.n n n >+l @+@+@+@+b b b b b b b @+T.l 6+l T ",
+" . . q+J J q+{ m m 4.@.9 m+m+m+0 +2 p+! ! .+8+] ] ] U :.y+n n l l l @+@+@+@+b b @+@+@+@+@+@+n+n n ! ",
+" . J J q+q+q+m 4.4.@.9 9 m+0 ^. +2 2 2 h h .+8+8+E+] U S.y+n n n l l l @+@+@+@+@+@+@+@+n+n+l n % ",
+" . . J J { q+m 4.@.9 9 m+0 ^. + +2 2 2 h h 8+.+H E+U U S.n >+n >+l l l l l @+@+l n+l >+n 6+! ",
+" . q+q+q+m D+4.4.@.9 9 m+0 m+ + +2 h ! h .+8+] ] ] U U S.S.n n n n l l n+l n+n+l n+n+n % ",
+" . P.J m m D+4.@.9 9 m+m+^. + +2 2 ! h .+h 8+] H E+E+U S.n n >+n n l 6+>+n+n n n n V. ",
+" q+J { 4.4.4.@.9 9 m+0 ^.2 +2 2 ! ! .+.+8+] ] U U U S.S.n n 6+n n n n n 6+T ",
+" . u+{ 4.`.@.9 m+m+m+m+^. +2 2 p+! ! h )+8+8+8+E+E+U E+S.U S.n n S.n U ] ",
+" { m 4.9 9 9 9 m+m+ + + + +2 2 #.)+..8+.+] 8+] E+U E+S.U U U U p ",
+" . J 4.4.9 9 m+m+^.^.2 2 2 ! #.! ! V.8+8+8+] ] E+] E+E+E+E+V. ",
+" D+@.9 9 m+m+^.m+^.2 2 2 ! ! h ! V.8+V.8+] E+# % ",
+" . D+9 y ^. +^.^.2 +2 2 ! h )+h V.! 2 p ",
+" 9 m+m+0 ^.2 2 2 2 2 2 % "};
diff --git a/arts/builder/pics/Synth_DEBUG.xpm b/arts/builder/pics/Synth_DEBUG.xpm
new file mode 100644
index 00000000..4a0a09af
--- /dev/null
+++ b/arts/builder/pics/Synth_DEBUG.xpm
@@ -0,0 +1,319 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 248 2",
+/* colors */
+" c #8B94BA",
+" . c #525A8C",
+" X c #374482",
+" o c #8992B8",
+" O c #3B457C",
+" + c #354280",
+" @ c #444E92",
+" # c #323E7D",
+" $ c #6E77A4",
+" % c #3F4E8D",
+" & c #2C3877",
+" * c #444C7E",
+" = c #283473",
+" - c #253070",
+" ; c #525985",
+" : c #242E6F",
+" > c #333E81",
+" , c #5F6995",
+" < c #1F2A6A",
+" 1 c #1E2869",
+" 2 c #949DBF",
+" 3 c #2D387B",
+" 4 c #7E88B0",
+" 5 c #2F3973",
+" 6 c #2B3679",
+" 7 c #575F8D",
+" 8 c #555D8B",
+" 9 c #40487D",
+" 0 c #4D568D",
+" q c #4F5785",
+" w c #44538E",
+" e c #555FA2",
+" r c #1F2A6D",
+" t c #1E286C",
+" y c #8E97BC",
+" u c #283279",
+" i c #253076",
+" p c #364380",
+" a c #8289B0",
+" s c #2F3B79",
+" d c #404B8D",
+" f c #2E3978",
+" g c #4F599F",
+" h c #565F92",
+" j c #404C83",
+" k c #2F386F",
+" l c #1A2361",
+" z c #384585",
+" x c #364383",
+" c c #303D7D",
+" v c #2F3B7C",
+" b c #2E3B7B",
+" n c #1D2767",
+" m c #505E99",
+" M c #283375",
+" N c #384388",
+" B c #374187",
+" V c #4E598D",
+" C c #384174",
+" Z c #42508B",
+" A c #1E296B",
+" S c #1D276A",
+" D c #6C739D",
+" F c #2A357A",
+" G c #7983AD",
+" H c #3A4883",
+" J c #263176",
+" K c #676F98",
+" L c #28326E",
+" P c #242F74",
+" I c #9EA5C4",
+" U c #232D73",
+" Y c #42508E",
+" T c #41508D",
+" R c #3D4C89",
+" E c #2D3876",
+" W c #374483",
+" Q c #273270",
+" ! c #38417A",
+" ~ c #313E7D",
+" ^ c #5D6591",
+" / c #5C6390",
+" ( c #323B74",
+" ) c #2A3676",
+" _ c #354084",
+" ` c #232E6F",
+" ' c #757CA5",
+" ] c #1F2A6B",
+" [ c #323D77",
+" { c #1E286A",
+" } c #1C2668",
+" | c #9299BE",
+". c #293478",
+".. c #273276",
+".X c #3E467C",
+".o c #4C588D",
+".O c #222C71",
+".+ c #3A4278",
+".@ c #212C70",
+".# c #202A6F",
+".$ c #1F2A6E",
+".% c #1E286D",
+".& c #363E74",
+".* c #1D286C",
+".= c #353E73",
+".- c #3E4D89",
+".; c #3D4B88",
+".: c #7E85AA",
+".> c #2B3573",
+"., c #7C83A8",
+".< c #394784",
+".1 c #384583",
+".2 c #646C97",
+".3 c #3A447B",
+".4 c #636A96",
+".5 c #868FB5",
+".6 c #6872B2",
+".7 c #212B69",
+".8 c #3F498D",
+".9 c #7981A8",
+".0 c None",
+".q c #5B66A5",
+".w c #212B6C",
+".e c #1F296A",
+".r c #414E88",
+".t c #1D2768",
+".y c #2C377A",
+".u c #1C2567",
+".i c #3B458C",
+".p c #3D4A84",
+".a c #293577",
+".s c #3C4883",
+".d c #2C3670",
+".f c #4B5A95",
+".g c #646E9D",
+".h c #3A4681",
+".j c #394680",
+".k c #475691",
+".l c #172058",
+".z c #485292",
+".x c #323D83",
+".c c #5662A3",
+".v c #44528E",
+".b c #34407B",
+".n c #5D6696",
+".m c #303B81",
+".M c #1F296D",
+".N c #42508C",
+".B c #2E397F",
+".V c #414E8B",
+".C c #313C78",
+".Z c #1D276B",
+".A c #404E8A",
+".S c #3F4E89",
+".D c #596292",
+".F c #6D759F",
+".G c #2A357B",
+".H c #515F94",
+".J c #3D4A87",
+".K c #3B4885",
+".L c #485695",
+".P c #5F6A9B",
+".I c #35427F",
+".U c #242E6B",
+".Y c #707BA5",
+".T c #4C5485",
+".R c #232C6A",
+".E c #4A5283",
+".W c #303C7A",
+".Q c #202A67",
+".! c #343D74",
+".~ c #2D3877",
+".^ c #1D2664",
+"./ c #3C4A89",
+".( c #454E7E",
+".) c #2B3675",
+"._ c #68719D",
+".` c #293473",
+".' c #283272",
+".] c #485498",
+".[ c #39457C",
+".{ c #354282",
+".} c #334080",
+".| c #424E92",
+"X c #323C7F",
+"X. c #424F88",
+"XX c #6973A1",
+"Xo c #2A3477",
+"XO c #414A7D",
+"X+ c #4A5993",
+"X@ c #495792",
+"X# c #253072",
+"X$ c #43518C",
+"X% c #333F79",
+"X& c #6F78A0",
+"X* c #465085",
+"X= c #1C2669",
+"X- c #2C367C",
+"X; c #2F3975",
+"X: c #515E93",
+"X> c #2D3773",
+"X, c #5E69AD",
+"X< c #4F5C91",
+"X1 c #7882AC",
+"X2 c #29336F",
+"X3 c #232E73",
+"X4 c #888FB5",
+"X5 c #49548B",
+"X6 c #202A70",
+"X7 c #868DB3",
+"X8 c #333F7C",
+"X9 c #404F8C",
+"X0 c #3F4D8B",
+"Xq c #2F3B78",
+"Xw c #4D579C",
+"Xe c #3B4787",
+"Xr c #26316F",
+"Xt c #49568E",
+"Xy c #252F6E",
+"Xu c #344180",
+"Xi c #374279",
+"Xp c #57649F",
+"Xa c #4A5385",
+"Xs c #303D7C",
+"Xd c #828BB2",
+"Xf c #30397C",
+"Xg c #646EAF",
+"Xh c #2E397A",
+"Xj c #464F81",
+"Xk c #313A73",
+"Xl c #3C498B",
+"Xz c #343F83",
+"Xx c #6D77B1",
+"Xc c #222D6E",
+"Xv c #222B6E",
+"Xb c #1D2769",
+"Xn c #546195",
+"Xm c #263175",
+"XM c #757FA8",
+"XN c #455490",
+"XB c #202B6F",
+"XV c #43528E",
+"XC c #1F296E",
+"XZ c #323E7A",
+"XA c #1E296D",
+"XS c #505C9E",
+"XD c #3B4886",
+"XF c #2A3472",
+/* pixels */
+".0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0X#... u u i PX3.O.# A n.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.> # N B.x.m.B.G u u i P U.O.OX6X6.M l l.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0Xe @.|.i N B.x.m.B.G u u i P U.O.OX6.#.#XCXC t l.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 p g g.] @.|.i N B.x.m.B.G u u i P U.O.OX6.#.#XCXA.%.% tX= l.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.c.c e g.].|.8.i N _.x.BX-.G u.. i P U.O.OX6.#.$XCXA.% t t.*.Z }.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.0.0.0.0XwX,X,.c gXw.].|.8.i N _.x.BX-.G u J i P U.O.OX6.#XCXCXA.% t t.Z.Z.ZX= l.0.0.0.0.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.0.0.0.6.6X,X, e gXw.].|.8.i BXz.m.BX-.G u J i P U.O.@X6.#XCXCXA.% t t.Z.Z.Z S S.u.0.0.0.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.0X$.6.6XgX,.c e g.].].|.8.i B.x.m.BX- F u i iX3.O.O.@.#.#XC.M.% t t.*.Z.Z S S S S }.l.0.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0X<Xx.6.6X,X,.c gXw.].|.8.i N B.x.m.B.G u u i PX3.O.O.@.#.$XCXA.% t t.Z.Z.Z S S SXbX= }.l.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0X:Xx.6.6XgX,.q e g.].].|.8.i N _.x.BX-.G u.. i P U.O.OX6.#.$XCXA.% t t.Z.Z.Z S S SXbX=X= }.l.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0X<Xx.6.6XgX,.c eXw.f.z @.8.i N _X Xh.yXo. .. J i P U.O.@XB.#XC.MXA t t.Z.Z.Z S S SXbXbX=X= }.u.l.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0X$Xx.6.6XgX,.q eXS m.PXn.f d.i BXz v.C E.) M J i iX3.OX6.#.#.$XC.M.% t t t t.Z.Z S S SXbXbX= } }.u.l.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.6.6.6XgX,.q.cXp.PXXX1.P.f.8 B.I ! 9Xa *.3.>X#X#X3.OXv.w.7.e t.%.MXAXA.Z.Z.Z.Z t t t t { SXbXb } }.u.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.6.6.6XgX,.q.c.qXg.5 | I $ 0.J x 9 8._ a.F /.& -X#.OXc.R.U L.7.M.M.#.#.#.M.M.M.M.M r.w r.M A t { {Xb.t.u.0.0.0.0.0.0",
+".0.0.0.0.0Xw.6XgX,X,.q.c eXS.g.5 |.gX5X5Xa . ^ ,.2.4.4.XXFXF.>.&XO C.=.U.w.wXv.w.w.UX2 LXr.w.w.w.w ] ] 1.Q n n.t.t l.0.0.0.0.0",
+".0.0.0.0.0X,X,X,X,.q eXSXwXw.nX7X7Xd.n.V h.Y.F K 7.T.D._X*X;.3X*.2X7 ,.(X2XcXc :XrX2.&Xj 9 !X2XcXcXc.w.7.7.R.7.Q.Q 1 n.0.0.0.0.0",
+".0.0.0.0.cX,X,.c.c e g g.].z.n oX1XX.n 0.P G ^ * * *.T 8 9X; OX5.F 2 / CX2 -.' E !Xj 8 K 8XO.d :.U.U L k CXO C k.U.Q.Q 1.0.0.0.0",
+".0.0.0 p.c.c e e g gXwXw @ d h $ h hXnXXX7 qX;.!.3 9.(.+X;.X ..9 I 7 kX2X# E.s.D.9X7 |._XaXkXr L.d C ;.2.,.4 ; k.7.7.w.^.0.0.0",
+".0.0.0 g e g g gXwXw.].] dX5.nX4.gX5 h.g._.F *.).&Xj.X CX>.'.&.T.2.:.( L Q M E.[.D aX7 , 9X%X>.+.E ; ^.2.F K.4.+ L.R.R <.0.0.0",
+".0.0.0 g gXwXw.].].] @.|.r hXXXd.n.J hXM._ /.+.`.& 7.XX> QX#.dXO ; K C L.' M E.b 7X4X7X7 7 !.3.[ 7.:X& K.2.4 D.9.E k L.UXc.0.0.0",
+".0.0Xe.].].].].].|.|.8.8X..g.gXXX5 X VX1 D / * ( 9 7.+X2.' M k 8 ; q k.'.`. .) [ .X7.:XM ..3 j . K.: ^Xj.(.( 7X&.( k LXyXy.Q.0.0",
+".0.0 @ @.|.|.|.|.8.8.i NX5XM.g h.p #Xa.:.F.n VXj.T 8.&.'.' M C D ; C.d.a 6.y.)X;.TX7XM._.T.[ V.FXM.: q.!.!.=.E D * k LXr -Xy.0.0",
+".0.>.|.|.8.8.8.8.i.i N _.s .X*.sX8XfXj.YX&.F.4.D.T * 5 M.'X2.+X&.EXk.d 6.y 3X;.+ 7X7.F.D.T j.D.9X& K * 5.=.+.E ^.X.d L.'.' Q.Q.0",
+".0 #.i.i.i.i.i.i N N _ >.}.hX8Xf 3.y.X.g.Y a GXM 0X%.>Xo.' k.( '.(.d.) 3 3 b [Xj.4 o K.TX5X*.2X4.F 7.+X;.=.(.T ; C.dXF.).` =.Q.0",
+".0 N N N N N B B B _.x.mXfXf 3.y 6. X; 9Xj . qXa !X>Xo. .> C.( / CX> & v b bXi /.FXd.n jX*X5._ y D q.+Xq.+ ;.TXj.=X>.>.).).>.'.0",
+".0 B B B _ _Xz.x.x.x.m.B.BX-X-X- F.. MXFX>.! [.C.). . F 5 *.(.(.! f b cXs.WXOX&XM 4 h.h jX5.F I KXj.+.CXO.2 q 9 ( E E f &.).>.0",
+"X#.x.x.x.x.x.m.m.B 3 3.y.G.G F F u..Xm.' Q.'XF.)Xo. F.yX>.&.!.!X; b c > cXZXjX&XXXXX5.j.pXa._ I ' 7Xa j 8.F q.+ (Xq f f f &.)XF",
+"...m.m.m.B.B.B.B.y 6 6 &. u u u.. J.. J.... u. F.y.y 3.~X; f f vX >Xz #.bXa.F.P.D j p.hXj K I a $.g.n D.9 qXi [Xs.W.W s f.~.>",
+". .BX-X-X-.y 3 s ! 9 O !.)..Xm i PX#X#.' M.. u F.y 3 3 3XhXh sXsX >Xz _.}.I.hX5X*.r.h W.h j ^Xd 4 GXM $.F._XjXiX% #XsXs.W s f.)",
+" u.G.G F F.yX8 j.D '.nX5.CX# PX3X#.'.`.> = M. 6.y.y 3.B v c c >Xz _.{ x.{ + X.h.<.1.<.<.< j ..Y.: X4X7.F.D j.b.bXu.} #XZ.W s E",
+" u u u... 3.s h.F a.n jX>X# -XF (XO OXi.> MXo 6 &.~ fXq.WXs ~ > _ x x z W W W.<.<.<XeXeXD.K.r V 7 , ,.n VX*.h p + +Xu.} # ~.W f",
+" i u i..Xo sX5 'Xd | ^ !XF :.> 9 7 ' , q ( M.a 6 E.b ! O !X8 #Xz x x z zXeXeXeXeXl././Xl././.p.p jX*X*X* j.s.1.1 X X +.I.} #Xs s",
+" P i P iXm M *.Y.9.:.E.dXr :.! 8 DX7 ^ *Xk.`X>X%XO . 8.DXa.s.I.{ x z z z z.<XD././XlX0X0 RX0.;.J.p.p j.J.K.K.<.<.<.1 X p.I.}X8.W",
+"X3 P P P U :.+.F.F.F.3 : :Xy 9 $X7 I ^.+ 5.>Xi .._ 4X7 o D ..s.{ W z z H.K.p.J RXl % % % % %X9X0X0X0 R R R R./XDXD.<.1 X p.IX8Xs",
+".O U U UXcXy 9 '.4 .Xk.wXc.U O.F.,X7 q 5XkXk.E D.F $ GX7.F hX..<.K.pX..o.o VX..-X0 % % %.A.S.S.S.SX0.AX0X0X0 R.;.JXD.<.1 X +.I #",
+".#.O.O.O.w L.(.:.D.X L r.wXc.+ DX& 'XOX2 (XO ,X4 '.P.YXd.F.n.o.rX5X<.P.9XM.YX: Z.V Y Y Y.AX.X.X..A.V T T TX9X0 R.;.J.K.<.1 X.IX8",
+" A.O.OX6.U.& ; '.EX>.U.M.wXyXO ' K / CX2 C 7 ^.2 8X*.nXMXX.PXnXtXn.gXM 4XM.HX$ Z.NX.X5 V.D.D.D.o Z Z Y T TX9X0 R.;XD.K.<.1 p.b",
+" nX6.#.#X2 q ^X&.X.U ]XA.wX2Xa.: ^.(Xk LXO., ^.T 9.[ 0 $XX.g.PXn $Xd | I GXn.vX$ Z.o ,X&.5.5 o.2.oX$XV YXV.NX9X0 R.JXD.<.h p.b",
+".0X6.M ]Xk ^ / 7Xk < t t.U ! 8.: ;.= k.d.(., ;.3 O.j V $.g.nX:Xt.g a y IXdXXXn.kX< h.gXM 4 o y.Y.n.o w wXNXV.N.VX0 R.J.K.< X.0",
+".0.M A.7.+ D 8XO L t t tX2.T.4.,.(X2 k.= ;.,.E [ !.sX< $.PX:X5.r.D 4 I G.PXnX<.P GX4 2 | y 2 a $X:.kXNXNXNXV.N.A.-.JXD.<.j.0",
+".0 l.e.7 k.T.+.d.7.Z t.eXk / ,.4.+ L.=.( ^.: q.b 9X5.n $ hX$.r.J hXd o |.YXn.nXp.Y .5 a.YXXX1 4.YXn.kXN.kXN.vX$X9X0 R.J.K [.0",
+".0 l {.7 L.! L.w {.Z 1.7.+ D ^ ;XkXr C ,X&.: . !X*.n.gXX V.p.s.s 8X7.5 oXXX:.P $.5 IXd $.PXn._XdX1.YXnX@.k.k.kXNXV.N.A.-.J.KX%.0",
+".0.0XbXb.e.R.e 1 S t 1.7.! 7.( CX2Xy.= / D.9.D j 8XX.P.DX* H.p j ^ X7 4.g.H.g G o IX1.PXn.H.g oXMXXXnX+X@.L.kXN.vX$.V.-.J.s.0.0",
+".0.0 l.Z S S S.Z t t.t.w kXj.! LXyXy.! 7 K.9.4 ..2.9.nX5.p.<.pXa K 2Xd.Y.PXnXX.5 y 2 $Xn.H.H.g yXM.P.H.fX+.LX@.k wXV.V.- RXi.0.0",
+".0.0.0.Z.Z.Z.Z.*.Z.ZXb 1.RX2.U.UXy - k.( / '.F K.2 ,Xa.s.1.< j 7X& yX1.g.PXn $ y y ._.HXnXn $ y.Y.P.H.f.f.fX@.kXNXV.N.A R.0.0.0",
+".0.0.0X=.*.Z.Z.Z.Z.ZX=X= 1.e.wXc -X#XF C q.F.9 a.2.T.h p X.<X*.F G $.n.nXpXM 2 a.P.HXn.P.Y y $.n.H m.f.fX+.kXNXV.N.A.p.0.0.0",
+".0.0.0 l.Z.Z.Z.Z.Z.ZX=X=Xb A.wXcX#X# Q.d.+Xj.T 8Xj O ! p X.<X5 ' GXd.gX<.HXnXM I yXd.gXn.P $X1.5XXXp m m.f.fX+.kXN.v.N.A.j.0.0.0",
+".0.0.0.0 }.Z.Z S S S S S t rXc `X#X#.' =X> (X% !.bX8Xu x X.h V G G G.nXtX+X<.Y I |XdXXXpXXXd 4 4.gXn m m.f.fX+.kXNXV.N.J.0.0.0.0",
+".0.0.0.0.0X= S S S S S S t.wXc `X#X#.' =.>X>X;.CXZ #Xu x X.hX*.P.P.PX<.vXtX< $ I 2 oX1 $X1 o 4XM.P m m m.f.fX@.kXNXV.S.0.0.0.0.0",
+".0.0.0.0.0 l S S S SXb S t rXc `X#X# M.a ) &Xh s c.} + x X.h j.o V V.vX$XtX<XX 2 2 | y y GXXXp m m m.f.fX@.kXNXV.h.0.0.0.0.0",
+".0.0.0.0.0.0.u SXbXbXbXb {.M.wXcX#X# MXo ) 6 f b c.}Xu x X.1.s.rX. Z Z.N wX@.P 4 o | y o.5.Y.PXn m.f.f.fX+.kXN w.r.0.0.0.0.0.0",
+".0.0.0.0.0.0.0 }X=X=X=Xb S A.wXc -X# M M ) &Xh v c.}Xu.{ x W.<.K.J RX0X9XVXNXn $ 4 | y .5 4XXXp m.f.f.fX+X@.kXN Z.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.l }X=X=X=Xb t.wXc `X#.' = ) 6 f b c #.} + x W zXD./ RX0 T.NXVX@Xn.P $ $.YXXXXXp m.f.f.fX+X@.kXNX$.[.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.l } } }Xb {.w.w `X#X# M ) & fXhXs ~.}Xu x W.<XD./ RX0X9X9 Y wXtX<XnXnXpXnXn m.f.f.fX+X@.kXNX$.3.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.l.u } } { A.wXc -X# = M ) & f bXs #.} + W z.<XD./ RX0X9.NX$ w.kXtX+X<.f.fX+X@X@X@.k.kXNX$.+.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.l.u }Xb.e.wXc :X#.' = ) & f sXs #.}Xu x W.<XDXD.; RX0X9.NXV.vXNXNXN.k.k.k.k.k.kXNXNX$.3.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.0.l.u.t A ].w ` -X# = ).) & f bXs #.} + x.1.<XD.J.; RX0.V.N.NX$XVXVXNXNXNXNXNXN w Z.[.0.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.0.0.0.u 1 ].wXc :X#.'.`.) & f b.W ~ #Xu + X.1.<XD.J.; RX0.AX9.NX$XVXVXV.vXVXVXV.r.0.0.0.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.0.0.0.0 l 1.wXc ` - Q =.`.) & f sXs #.}Xu + X.1.<.KXD.J R.-X0.A.V.V.N.N.N.N.S.h.0.0.0.0.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 1.wXc :Xr.'.`.).) f f.WXs #.}.I p X.1.<.KXD.J.J R.-.-.-.A.A.A.J.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.^.7 ` - Q.'.`.) & f s.WXZ #.}.I p X.1.<.<.KXD.J.J.J R R.p.j.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.QXy Q =.>.) & f s.W ~ #.}.I + X.1.h.<.<.K.K.sXi.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.Q.Q.'.>.).~ f s.WXsX8X8.I.I p p X.j [X%.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",
+".0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0XF.>.) E f s.WXs #X8.b.b.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0"
+};
diff --git a/arts/builder/pics/Synth_DIV.xpm b/arts/builder/pics/Synth_DIV.xpm
new file mode 100644
index 00000000..c424ce7a
--- /dev/null
+++ b/arts/builder/pics/Synth_DIV.xpm
@@ -0,0 +1,1350 @@
+/* XPM */
+static char * Synth_DIV_xpm[] = {
+"64 64 1283 2",
+" c None",
+". c #253073",
+"+ c #273276",
+"@ c #293378",
+"# c #283278",
+"$ c #263077",
+"% c #252F75",
+"& c #232E74",
+"* c #212B71",
+"= c #202A6E",
+"- c #1E296A",
+"; c #1C2667",
+"> c #2B3671",
+", c #313D7B",
+"' c #384288",
+") c #353F87",
+"! c #323D83",
+"~ c #2F3A80",
+"{ c #2D377D",
+"] c #2A357B",
+"^ c #29347A",
+"/ c #273177",
+"( c #253076",
+"_ c #232D72",
+": c #222C72",
+"< c #212C71",
+"[ c #202B70",
+"} c #202A70",
+"| c #1F296E",
+"1 c #1B2463",
+"2 c #3C4988",
+"3 c #434D95",
+"4 c #414C93",
+"5 c #3D488D",
+"6 c #202A6F",
+"7 c #1F2A6F",
+"8 c #1E286C",
+"9 c #37437E",
+"0 c #4F59A0",
+"a c #485399",
+"b c #3B458D",
+"c c #283379",
+"d c #242E74",
+"e c #1E296D",
+"f c #1E286D",
+"g c #1C2669",
+"h c #5862A8",
+"i c #555FA6",
+"j c #3F4B90",
+"k c #1F2A6E",
+"l c #1D276B",
+"m c #1C2668",
+"n c #4B5A97",
+"o c #616CB3",
+"p c #5C67AF",
+"q c #4B579B",
+"r c #2E397F",
+"s c #263177",
+"t c #253075",
+"u c #6872B4",
+"v c #343F84",
+"w c #222C71",
+"x c #212B70",
+"y c #1B2666",
+"z c #1B2366",
+"A c #45538B",
+"B c #445194",
+"C c #2B367B",
+"D c #263076",
+"E c #232E73",
+"F c #1D266B",
+"G c #1E266C",
+"H c #1A2264",
+"I c #1D276A",
+"J c #171F57",
+"K c #4A5996",
+"L c #273277",
+"M c #242F74",
+"N c #1A2664",
+"O c #1E296C",
+"P c #1D296B",
+"Q c #1E2A6C",
+"R c #354186",
+"S c #2C377B",
+"T c #202B6F",
+"U c #6672BC",
+"V c #666EB4",
+"W c #5E6AB4",
+"X c #5A66AC",
+"Y c #565EA4",
+"Z c #525EA4",
+"` c #4E5AA2",
+" . c #4A569C",
+".. c #465296",
+"+. c #424E94",
+"@. c #3E4A8E",
+"#. c #3E468C",
+"$. c #36428C",
+"%. c #363E84",
+"&. c #626EB4",
+"*. c #5E66AC",
+"=. c #5662AB",
+"-. c #525AA4",
+";. c #424A94",
+">. c #3A4A8C",
+",. c #3A468C",
+"'. c #323E84",
+"). c #273278",
+"!. c #4A529C",
+"~. c #464E93",
+"{. c #3A428C",
+"]. c #313983",
+"^. c #2D387E",
+"/. c #2A3479",
+"(. c #263176",
+"_. c #303A7B",
+":. c #353D7B",
+"<. c #303A7A",
+"[. c #252F74",
+"}. c #212A6F",
+"|. c #1F2B6F",
+"1. c #212A6E",
+"2. c #1E286A",
+"3. c #1D2769",
+"4. c #303B81",
+"5. c #2C367E",
+"6. c #293479",
+"7. c #232E72",
+"8. c #313C7C",
+"9. c #475088",
+"0. c #606998",
+"a. c #69709D",
+"b. c #606898",
+"c. c #485189",
+"d. c #303979",
+"e. c #212D72",
+"f. c #222E74",
+"g. c #222A6F",
+"h. c #1E2868",
+"i. c #1A235E",
+"j. c #5A62AC",
+"k. c #35418B",
+"l. c #2F3B80",
+"m. c #485088",
+"n. c #797FAA",
+"o. c #A3A7C3",
+"p. c #B3B6CD",
+"q. c #A3A8C3",
+"r. c #797EA8",
+"s. c #273176",
+"t. c #222B70",
+"u. c #212B6C",
+"v. c #20296C",
+"w. c #4E569C",
+"x. c #323A80",
+"y. c #29357A",
+"z. c #283178",
+"A. c #263075",
+"B. c #263171",
+"C. c #323E7A",
+"D. c #60699A",
+"E. c #A4A9C3",
+"F. c #D3D5E1",
+"G. c #E0E2EA",
+"H. c #D2D5E2",
+"I. c #A5A9C3",
+"J. c #626997",
+"K. c #313D7E",
+"L. c #242E73",
+"M. c #262E73",
+"N. c #262F73",
+"O. c #263273",
+"P. c #222E6C",
+"Q. c #223264",
+"R. c #222D6E",
+"S. c #4E5AA4",
+"T. c #4A5A9C",
+"U. c #303C81",
+"V. c #2D397E",
+"W. c #2C357D",
+"X. c #273378",
+"Y. c #263276",
+"Z. c #252F76",
+"`. c #373F7D",
+" + c #6C729E",
+".+ c #B4B7CE",
+"++ c #E0E2EB",
+"@+ c #EBECF2",
+"#+ c #B4B8CE",
+"$+ c #6C73A2",
+"%+ c #394278",
+"&+ c #243073",
+"*+ c #263277",
+"=+ c #263078",
+"-+ c #26327C",
+";+ c #252D72",
+">+ c #253071",
+",+ c #242F6E",
+"'+ c #232E6E",
+")+ c #46529C",
+"!+ c #425294",
+"~+ c #354182",
+"{+ c #2B357D",
+"]+ c #273178",
+"^+ c #263175",
+"/+ c #242F73",
+"(+ c #333E7D",
+"_+ c #636A9B",
+":+ c #A5A9C2",
+"<+ c #D3D5E2",
+"[+ c #646B9A",
+"}+ c #364181",
+"|+ c #26336C",
+"1+ c #283273",
+"2+ c #2A3674",
+"3+ c #26366C",
+"4+ c #2A3274",
+"5+ c #232E6C",
+"6+ c #212B69",
+"7+ c #464E94",
+"8+ c #2F3B81",
+"9+ c #2D3679",
+"0+ c #2B357C",
+"a+ c #273272",
+"b+ c #273274",
+"c+ c #273076",
+"d+ c #243074",
+"e+ c #253070",
+"f+ c #2D3779",
+"g+ c #4A538C",
+"h+ c #7C82AB",
+"i+ c #A5AAC5",
+"j+ c #B5B9CE",
+"k+ c #A5ABC5",
+"l+ c #7E84AC",
+"m+ c #4E568C",
+"n+ c #2E3A7A",
+"o+ c #2B3779",
+"p+ c #28337A",
+"q+ c #293574",
+"r+ c #2B377D",
+"s+ c #2A367C",
+"t+ c #2A327C",
+"u+ c #293474",
+"v+ c #273273",
+"w+ c #273271",
+"x+ c #3E4A94",
+"y+ c #323A84",
+"z+ c #2E3A7F",
+"A+ c #2A3679",
+"B+ c #2A3579",
+"C+ c #263470",
+"D+ c #263274",
+"E+ c #273377",
+"F+ c #273371",
+"G+ c #27346F",
+"H+ c #293475",
+"I+ c #394382",
+"J+ c #4F588C",
+"K+ c #666F9B",
+"L+ c #7279A3",
+"M+ c #686F9F",
+"N+ c #50598E",
+"O+ c #3C4681",
+"P+ c #2D3777",
+"Q+ c #2D3976",
+"R+ c #2E397B",
+"S+ c #2D3775",
+"T+ c #2B3873",
+"U+ c #2F3B77",
+"V+ c #30397E",
+"W+ c #2F3775",
+"X+ c #2A386E",
+"Y+ c #2E3A7D",
+"Z+ c #293579",
+"`+ c #293575",
+" @ c #293473",
+".@ c #263170",
+"+@ c #2A357C",
+"@@ c #2A3379",
+"#@ c #293278",
+"$@ c #273279",
+"%@ c #2A3378",
+"&@ c #283377",
+"*@ c #283378",
+"=@ c #2C3779",
+"-@ c #303B7E",
+";@ c #3A4482",
+">@ c #3D4781",
+",@ c #3D4683",
+"'@ c #323E80",
+")@ c #2D397A",
+"!@ c #2E3B7A",
+"~@ c #2E387D",
+"{@ c #2F3B7D",
+"]@ c #2E3C7A",
+"^@ c #2F387D",
+"/@ c #2F3B7F",
+"(@ c #313D7F",
+"_@ c #303E7E",
+":@ c #2F387C",
+"<@ c #2E367C",
+"[@ c #2C3877",
+"}@ c #2C3878",
+"|@ c #2C3777",
+"1@ c #2A3676",
+"2@ c #2B3571",
+"3@ c #2B3478",
+"4@ c #283477",
+"5@ c #2A3375",
+"6@ c #2A3474",
+"7@ c #2A3576",
+"8@ c #2B3676",
+"9@ c #2C3778",
+"0@ c #2C387A",
+"a@ c #2C397B",
+"b@ c #2E387B",
+"c@ c #2E3A7C",
+"d@ c #2E3B7B",
+"e@ c #2F3C7C",
+"f@ c #2F3D7C",
+"g@ c #303D7D",
+"h@ c #303D7E",
+"i@ c #313F7E",
+"j@ c #313E80",
+"k@ c #313D7D",
+"l@ c #313E7F",
+"m@ c #324081",
+"n@ c #323E81",
+"o@ c #2E3E7C",
+"p@ c #2D3A79",
+"q@ c #2D3978",
+"r@ c #283677",
+"s@ c #2A347C",
+"t@ c #263372",
+"u@ c #283479",
+"v@ c #283578",
+"w@ c #2B377B",
+"x@ c #2F3C7D",
+"y@ c #2F3C7E",
+"z@ c #303C7D",
+"A@ c #313E7E",
+"B@ c #323E7E",
+"C@ c #333F7F",
+"D@ c #323F7E",
+"E@ c #333F80",
+"F@ c #344081",
+"G@ c #333F7E",
+"H@ c #33417F",
+"I@ c #354183",
+"J@ c #34407E",
+"K@ c #2F3B7E",
+"L@ c #303980",
+"M@ c #2F3C7A",
+"N@ c #2A3279",
+"O@ c #293478",
+"P@ c #2B357A",
+"Q@ c #2B3579",
+"R@ c #2D397B",
+"S@ c #2E397C",
+"T@ c #2E3B7D",
+"U@ c #2F3B7B",
+"V@ c #2F3D7F",
+"W@ c #303D7F",
+"X@ c #313E7D",
+"Y@ c #313F81",
+"Z@ c #334082",
+"`@ c #334080",
+" # c #344183",
+".# c #354284",
+"+# c #35417E",
+"@# c #344284",
+"## c #364386",
+"$# c #364385",
+"%# c #364282",
+"&# c #354383",
+"*# c #344180",
+"=# c #2B3776",
+"-# c #2B3675",
+";# c #283370",
+"># c #29337C",
+",# c #273375",
+"'# c #293477",
+")# c #283474",
+"!# c #2C377C",
+"~# c #2C3875",
+"{# c #2E3A7E",
+"]# c #303C7F",
+"^# c #303D7C",
+"/# c #344181",
+"(# c #344281",
+"_# c #354280",
+":# c #344282",
+"<# c #34427F",
+"[# c #374280",
+"}# c #364482",
+"|# c #374487",
+"1# c #374582",
+"2# c #374586",
+"3# c #384485",
+"4# c #344080",
+"5# c #2D3876",
+"6# c #26327B",
+"7# c #273477",
+"8# c #2A3475",
+"9# c #2A3775",
+"0# c #2C3879",
+"a# c #2E3A78",
+"b# c #2F3B7C",
+"c# c #303C7B",
+"d# c #323E7F",
+"e# c #323F80",
+"f# c #333F81",
+"g# c #334180",
+"h# c #364283",
+"i# c #364382",
+"j# c #374385",
+"k# c #384584",
+"l# c #354482",
+"m# c #384588",
+"n# c #384587",
+"o# c #394585",
+"p# c #394587",
+"q# c #394686",
+"r# c #394687",
+"s# c #374483",
+"t# c #354382",
+"u# c #354282",
+"v# c #2B3775",
+"w# c #2A337C",
+"x# c #283570",
+"y# c #2D377C",
+"z# c #2B3679",
+"A# c #2D3A7C",
+"B# c #323F81",
+"C# c #344182",
+"D# c #334181",
+"E# c #344382",
+"F# c #354281",
+"G# c #364484",
+"H# c #364583",
+"I# c #374482",
+"J# c #384585",
+"K# c #374684",
+"L# c #374685",
+"M# c #374480",
+"N# c #3A4686",
+"O# c #394885",
+"P# c #3A4988",
+"Q# c #3A4A8A",
+"R# c #3A4989",
+"S# c #3A4786",
+"T# c #2F3B78",
+"U# c #2B3674",
+"V# c #343F80",
+"W# c #3B4384",
+"X# c #424D89",
+"Y# c #454F8A",
+"Z# c #454E89",
+"`# c #47518A",
+" $ c #47508A",
+".$ c #475190",
+"+$ c #495387",
+"@$ c #4B5691",
+"#$ c #4C5791",
+"$$ c #4B568C",
+"%$ c #4E5990",
+"&$ c #515B93",
+"*$ c #505B92",
+"=$ c #525D91",
+"-$ c #535E95",
+";$ c #535E94",
+">$ c #556094",
+",$ c #556095",
+"'$ c #556096",
+")$ c #566194",
+"!$ c #576296",
+"~$ c #566297",
+"{$ c #566294",
+"]$ c #586397",
+"^$ c #576496",
+"/$ c #576499",
+"($ c #576497",
+"_$ c #5A6497",
+":$ c #5A6599",
+"<$ c #5A659B",
+"[$ c #5A6598",
+"}$ c #586599",
+"|$ c #586498",
+"1$ c #576297",
+"2$ c #535E92",
+"3$ c #525D92",
+"4$ c #4F5992",
+"5$ c #44528C",
+"6$ c #3F4C85",
+"7$ c #384282",
+"8$ c #4D568F",
+"9$ c #656C9D",
+"0$ c #767DA9",
+"a$ c #7F85AE",
+"b$ c #8087AF",
+"c$ c #8086AF",
+"d$ c #8489B0",
+"e$ c #848AB0",
+"f$ c #848BB0",
+"g$ c #848BAE",
+"h$ c #858BB3",
+"i$ c #868DAF",
+"j$ c #888EB0",
+"k$ c #8B91B2",
+"l$ c #8B91B0",
+"m$ c #8B91B3",
+"n$ c #8D94B6",
+"o$ c #8B92B6",
+"p$ c #8C93B8",
+"q$ c #8B93B6",
+"r$ c #8D95B8",
+"s$ c #8D95B9",
+"t$ c #8D96B7",
+"u$ c #8D95B7",
+"v$ c #8F97BB",
+"w$ c #8D95B6",
+"x$ c #8E96BA",
+"y$ c #8D96B6",
+"z$ c #9197BC",
+"A$ c #9198B8",
+"B$ c #9097BA",
+"C$ c #9199BE",
+"D$ c #9198BE",
+"E$ c #9097BB",
+"F$ c #8F97BA",
+"G$ c #8E97B9",
+"H$ c #8B94B8",
+"I$ c #8991B7",
+"J$ c #8088B0",
+"K$ c #7079A5",
+"L$ c #596497",
+"M$ c #434D87",
+"N$ c #33407D",
+"O$ c #6972A1",
+"P$ c #9398BB",
+"Q$ c #ABAFC9",
+"R$ c #B7BAD0",
+"S$ c #B9BDD2",
+"T$ c #BBBED3",
+"U$ c #BBBED4",
+"V$ c #BBBFD3",
+"W$ c #BCBFD4",
+"X$ c #BDBFD6",
+"Y$ c #BCBFD5",
+"Z$ c #BEC1D5",
+"`$ c #BEC2D6",
+" % c #BEC2D5",
+".% c #BFC3D6",
+"+% c #BFC3D7",
+"@% c #C0C3D8",
+"#% c #C0C4D7",
+"$% c #C1C5D8",
+"%% c #C1C5D9",
+"&% c #C2C6D9",
+"*% c #C1C6D9",
+"=% c #C2C6D8",
+"-% c #C1C6D8",
+";% c #C3C7D9",
+">% c #C2C7D9",
+",% c #C1C7D9",
+"'% c #C2C7D8",
+")% c #C3C7DB",
+"!% c #C3C7DA",
+"~% c #BFC5D8",
+"{% c #BDC1D7",
+"]% c #B2B8D0",
+"^% c #9DA3C2",
+"/% c #757EA8",
+"(% c #3A4882",
+"_% c #2B357B",
+":% c #4B538C",
+"<% c #787FA8",
+"[% c #A6ABC7",
+"}% c #C0C3D6",
+"|% c #CBCEDE",
+"1% c #CED0DF",
+"2% c #CDD0DF",
+"3% c #CFD2E0",
+"4% c #D0D2E0",
+"5% c #D0D2E1",
+"6% c #D0D3E1",
+"7% c #D0D3E0",
+"8% c #D2D3E0",
+"9% c #D2D4E1",
+"0% c #D2D5E3",
+"a% c #D3D5E3",
+"b% c #D3D6E4",
+"c% c #D3D6E3",
+"d% c #D3D7E4",
+"e% c #D4D7E5",
+"f% c #D3D7E3",
+"g% c #D4D8E4",
+"h% c #D5D8E5",
+"i% c #D5D8E4",
+"j% c #D5D8E6",
+"k% c #D0D4E2",
+"l% c #C6CADC",
+"m% c #B0B5CD",
+"n% c #848CB3",
+"o% c #596599",
+"p% c #3D4A83",
+"q% c #35427E",
+"r% c #2A347A",
+"s% c #424B86",
+"t% c #696F9E",
+"u% c #9397BA",
+"v% c #AAAEC8",
+"w% c #B6B9CF",
+"x% c #B9BCD1",
+"y% c #BBBED2",
+"z% c #BBBFD2",
+"A% c #BCBFD6",
+"B% c #BDBFD5",
+"C% c #BDC0D6",
+"D% c #BDC1D5",
+"E% c #BFC2D8",
+"F% c #BFC3D8",
+"G% c #C0C4D8",
+"H% c #C2C7DB",
+"I% c #C3C8DB",
+"J% c #C3C9DB",
+"K% c #C2C5DA",
+"L% c #B4B9D0",
+"M% c #9EA4C3",
+"N% c #7680AC",
+"O% c #546195",
+"P% c #3D4B85",
+"Q% c #384583",
+"R% c #323F7C",
+"S% c #323D7D",
+"T% c #495189",
+"U% c #616999",
+"V% c #747AA4",
+"W% c #7C82AA",
+"X% c #7E85AC",
+"Y% c #7F85AC",
+"Z% c #8488AF",
+"`% c #848AAE",
+" & c #848BAD",
+".& c #858BAE",
+"+& c #858DB4",
+"@& c #868DB0",
+"#& c #868DB2",
+"$& c #8990B2",
+"%& c #8991B4",
+"&& c #8B92B8",
+"*& c #8D93B6",
+"=& c #8D94B7",
+"-& c #8D92B9",
+";& c #8D96BA",
+">& c #8F96B8",
+",& c #8D96B8",
+"'& c #9197BE",
+")& c #9197BB",
+"!& c #9199BB",
+"~& c #929ABD",
+"{& c #929CBE",
+"]& c #939DBE",
+"^& c #929ABC",
+"/& c #929BBE",
+"(& c #949DBE",
+"_& c #929ABE",
+":& c #8C95B8",
+"<& c #858EB5",
+"[& c #737EAA",
+"}& c #5D699D",
+"|& c #48538D",
+"1& c #3A4886",
+"2& c #394786",
+"3& c #2C3677",
+"4& c #363D7B",
+"5& c #3B4580",
+"6& c #3F4984",
+"7& c #3F4884",
+"8& c #414A84",
+"9& c #454E86",
+"0& c #455087",
+"a& c #49508B",
+"b& c #495190",
+"c& c #49538B",
+"d& c #495390",
+"e& c #4B558C",
+"f& c #505A92",
+"g& c #515A96",
+"h& c #515C8F",
+"i& c #525D96",
+"j& c #536096",
+"k& c #576095",
+"l& c #57649A",
+"m& c #59659A",
+"n& c #5A659C",
+"o& c #5B6799",
+"p& c #5C689D",
+"q& c #5B679D",
+"r& c #5B689A",
+"s& c #5E699F",
+"t& c #5F6A9F",
+"u& c #5F6C9F",
+"v& c #606E9D",
+"w& c #606D9D",
+"x& c #616CA3",
+"y& c #606C9D",
+"z& c #606CA4",
+"A& c #606DA0",
+"B& c #5F6B9E",
+"C& c #5E6A9D",
+"D& c #5A689D",
+"E& c #59669B",
+"F& c #556198",
+"G& c #4E5C94",
+"H& c #485690",
+"I& c #3E4B89",
+"J& c #3B4885",
+"K& c #384685",
+"L& c #2A3477",
+"M& c #2A3677",
+"N& c #283670",
+"O& c #303E80",
+"P& c #303C80",
+"Q& c #353F81",
+"R& c #374383",
+"S& c #384384",
+"T& c #3A4788",
+"U& c #3A4A89",
+"V& c #3C4A88",
+"W& c #3D4C8C",
+"X& c #3F4D8C",
+"Y& c #404F8E",
+"Z& c #42508D",
+"`& c #41508D",
+" * c #435190",
+".* c #425290",
+"+* c #43528C",
+"@* c #43548F",
+"#* c #445494",
+"$* c #44548C",
+"%* c #445293",
+"&* c #445391",
+"** c #435090",
+"=* c #42518E",
+"-* c #41508E",
+";* c #404E8C",
+">* c #3F4D8A",
+",* c #3A4885",
+"'* c #374581",
+")* c #232C71",
+"!* c #242F76",
+"~* c #252F73",
+"{* c #253176",
+"]* c #293673",
+"^* c #2A3678",
+"/* c #2E3C7C",
+"(* c #313E79",
+"_* c #313C81",
+":* c #324084",
+"<* c #344082",
+"[* c #374382",
+"}* c #374786",
+"|* c #3B478C",
+"1* c #3C4B8C",
+"2* c #3F4C8C",
+"3* c #3E4E8E",
+"4* c #404F90",
+"5* c #414F8C",
+"6* c #425090",
+"7* c #455391",
+"8* c #475694",
+"9* c #445493",
+"0* c #455394",
+"a* c #424F8C",
+"b* c #465494",
+"c* c #46588F",
+"d* c #45568F",
+"e* c #455491",
+"f* c #445390",
+"g* c #43528E",
+"h* c #35417C",
+"i* c #212D71",
+"j* c #222D71",
+"k* c #242E71",
+"l* c #253173",
+"m* c #283179",
+"n* c #273476",
+"o* c #2D397C",
+"p* c #303C77",
+"q* c #34407F",
+"r* c #374484",
+"s* c #384489",
+"t* c #3A478B",
+"u* c #3A4684",
+"v* c #3B4B8C",
+"w* c #404E90",
+"x* c #435290",
+"y* c #42538D",
+"z* c #455494",
+"A* c #455593",
+"B* c #44558D",
+"C* c #465690",
+"D* c #475793",
+"E* c #485495",
+"F* c #475594",
+"G* c #465592",
+"H* c #41508C",
+"I* c #3C4A89",
+"J* c #202C71",
+"K* c #222E72",
+"L* c #2D3979",
+"M* c #364082",
+"N* c #344484",
+"O* c #364483",
+"P* c #384688",
+"Q* c #3D498D",
+"R* c #3E4E8C",
+"S* c #435191",
+"T* c #435391",
+"U* c #465491",
+"V* c #485795",
+"W* c #475496",
+"X* c #485894",
+"Y* c #46568B",
+"Z* c #495A92",
+"`* c #495996",
+" = c #495992",
+".= c #414F8A",
+"+= c #3E4C88",
+"@= c #1F2B6E",
+"#= c #222C70",
+"$= c #252E73",
+"%= c #263279",
+"&= c #2B3777",
+"*= c #2D3879",
+"== c #2F3C78",
+"-= c #324080",
+";= c #364287",
+">= c #384481",
+",= c #3E4D8C",
+"'= c #3E4B8D",
+")= c #424F8F",
+"!= c #425292",
+"~= c #435291",
+"{= c #45528D",
+"]= c #465594",
+"^= c #43548C",
+"/= c #475991",
+"(= c #4A5A99",
+"_= c #485791",
+":= c #485593",
+"<= c #4B5B9A",
+"[= c #4C5B98",
+"}= c #4A5A95",
+"|= c #495894",
+"1= c #404E8A",
+"2= c #3E4D89",
+"3= c #394680",
+"4= c #1F2A6D",
+"5= c #1F286D",
+"6= c #232E70",
+"7= c #232D71",
+"8= c #253072",
+"9= c #263172",
+"0= c #293675",
+"a= c #2B3879",
+"b= c #313F83",
+"c= c #384888",
+"d= c #3B498C",
+"e= c #404E8D",
+"f= c #42508E",
+"g= c #435292",
+"h= c #455492",
+"i= c #465695",
+"j= c #475691",
+"k= c #48568F",
+"l= c #47578F",
+"m= c #495993",
+"n= c #48568C",
+"o= c #4C5C9C",
+"p= c #4C5D9C",
+"q= c #4D5E98",
+"r= c #333E78",
+"s= c #1E296E",
+"t= c #1E2A6D",
+"u= c #222D70",
+"v= c #253171",
+"w= c #283276",
+"x= c #283476",
+"y= c #2A3773",
+"z= c #323F7F",
+"A= c #384285",
+"B= c #384684",
+"C= c #3F4B87",
+"D= c #46518C",
+"E= c #4D598E",
+"F= c #495493",
+"G= c #43538C",
+"H= c #414E92",
+"I= c #405090",
+"J= c #44528F",
+"K= c #45558F",
+"L= c #4A5898",
+"M= c #485A92",
+"N= c #4A599C",
+"O= c #4A5891",
+"P= c #4B5A95",
+"Q= c #4B5B96",
+"R= c #4D5D97",
+"S= c #4E5F98",
+"T= c #505E99",
+"U= c #4F5E9D",
+"V= c #4C5D98",
+"W= c #485893",
+"X= c #455390",
+"Y= c #212B6F",
+"Z= c #232E6D",
+"`= c #253074",
+" - c #293674",
+".- c #2D387A",
+"+- c #344280",
+"@- c #46528D",
+"#- c #5B669F",
+"$- c #737DAC",
+"%- c #7B86B1",
+"&- c #747DAD",
+"*- c #495791",
+"=- c #414E8C",
+"-- c #445291",
+";- c #465593",
+">- c #46568E",
+",- c #485A91",
+"'- c #485897",
+")- c #4A578D",
+"!- c #4B5C95",
+"~- c #4B5A93",
+"{- c #4E5E99",
+"]- c #4E5E97",
+"^- c #4D5D98",
+"/- c #4F5F9C",
+"(- c #4C5C97",
+"_- c #475692",
+":- c #3A4883",
+"<- c #1E276C",
+"[- c #202B6E",
+"}- c #1F2B70",
+"|- c #242E70",
+"1- c #273370",
+"2- c #293573",
+"3- c #2C387C",
+"4- c #2C397A",
+"5- c #2D3A7A",
+"6- c #3C4886",
+"7- c #596597",
+"8- c #8990B4",
+"9- c #ADB3CE",
+"0- c #BDC1D6",
+"a- c #AEB4CE",
+"b- c #8A92B8",
+"c- c #606C9F",
+"d- c #46548F",
+"e- c #465694",
+"f- c #465691",
+"g- c #475697",
+"h- c #4A5895",
+"i- c #4A5B94",
+"j- c #4C5B97",
+"k- c #4C5A92",
+"l- c #4F5F9D",
+"m- c #4F609A",
+"n- c #52639E",
+"o- c #4D5E9C",
+"p- c #4A5991",
+"q- c #4F5A94",
+"r- c #1D286C",
+"s- c #1D276C",
+"t- c #212B6D",
+"u- c #212E6E",
+"v- c #232F73",
+"w- c #283470",
+"x- c #2A3575",
+"y- c #2C377A",
+"z- c #2B3876",
+"A- c #2E3B76",
+"B- c #434D8D",
+"C- c #707BA9",
+"D- c #ADB3CC",
+"E- c #D8DAE6",
+"F- c #E3E6EE",
+"G- c #D8DAE7",
+"H- c #B0B5CE",
+"I- c #7580AB",
+"J- c #445492",
+"K- c #465791",
+"L- c #495899",
+"M- c #47578E",
+"N- c #4B5995",
+"O- c #4C588F",
+"P- c #4B5A92",
+"Q- c #4F5E93",
+"R- c #50619D",
+"S- c #51629D",
+"T- c #4B5A8D",
+"U- c #4A5A9A",
+"V- c #4E5E94",
+"W- c #4A5994",
+"X- c #495693",
+"Y- c #455490",
+"Z- c #1C276A",
+"`- c #1F296D",
+" ; c #202B6B",
+".; c #242F72",
+"+; c #25326D",
+"@; c #2C3976",
+"#; c #434F89",
+"$; c #7982AC",
+"%; c #BCC0D6",
+"&; c #EDEFF3",
+"*; c #7D87B1",
+"=; c #4F5D97",
+"-; c #445491",
+";; c #475492",
+">; c #475695",
+",; c #495995",
+"'; c #485895",
+"); c #4F5F9B",
+"!; c #4F6098",
+"~; c #506099",
+"{; c #4C598E",
+"]; c #4B5C97",
+"^; c #4A5A9B",
+"/; c #4A5A94",
+"(; c #3E4B85",
+"_; c #1D2768",
+":; c #1F296C",
+"<; c #232F72",
+"[; c #25306D",
+"}; c #293576",
+"|; c #2A3774",
+"1; c #2D3977",
+"2; c #303B80",
+"3; c #424A85",
+"4; c #6F78A5",
+"5; c #ADB2CC",
+"6; c #ADB3CD",
+"7; c #757EAB",
+"8; c #4A5892",
+"9; c #43518F",
+"0; c #46558D",
+"a; c #4A5993",
+"b; c #4A5B95",
+"c; c #4D5A90",
+"d; c #4E5E9B",
+"e; c #4E5F9B",
+"f; c #4F5F9A",
+"g; c #4E5B8F",
+"h; c #4F609C",
+"i; c #1C2769",
+"j; c #20296D",
+"k; c #212C6F",
+"l; c #222C6D",
+"m; c #23306F",
+"n; c #263275",
+"o; c #293578",
+"p; c #384580",
+"q; c #586398",
+"r; c #8790B4",
+"s; c #8991B6",
+"t; c #5E6B9F",
+"u; c #44528A",
+"v; c #40508D",
+"w; c #43508F",
+"x; c #43528F",
+"y; c #475495",
+"z; c #4A5793",
+"A; c #4B5991",
+"B; c #495891",
+"C; c #4C5B95",
+"D; c #4D5B90",
+"E; c #4D5A8F",
+"F; c #4F5E9A",
+"G; c #4D5E96",
+"H; c #49588A",
+"I; c #4A5A8D",
+"J; c #46528C",
+"K; c #1D266A",
+"L; c #1B2667",
+"M; c #212C6D",
+"N; c #212C6C",
+"O; c #263174",
+"P; c #283374",
+"Q; c #293671",
+"R; c #33407F",
+"S; c #424C86",
+"T; c #737CA9",
+"U; c #7D87AF",
+"V; c #747EAB",
+"W; c #5D6A9D",
+"X; c #4A558E",
+"Y; c #3F4E8C",
+"Z; c #41518F",
+"`; c #43538F",
+" > c #475792",
+".> c #475791",
+"+> c #495998",
+"@> c #4B5998",
+"#> c #4C5C95",
+"$> c #4C5A93",
+"%> c #4D5D99",
+"&> c #4A568A",
+"*> c #45548F",
+"=> c #1D286B",
+"-> c #1E2968",
+";> c #202A6D",
+">> c #283371",
+",> c #27336F",
+"'> c #2F3C7B",
+")> c #323E7D",
+"!> c #334081",
+"~> c #4B5993",
+"{> c #495690",
+"]> c #414F86",
+"^> c #3F4C89",
+"/> c #404D8C",
+"(> c #425091",
+"_> c #44528D",
+":> c #45548D",
+"<> c #475690",
+"[> c #48578F",
+"}> c #495588",
+"|> c #4C5A98",
+"1> c #4A568B",
+"2> c #4C5A96",
+"3> c #1C2768",
+"4> c #1B2767",
+"5> c #1B2665",
+"6> c #1F2B6D",
+"7> c #222D6F",
+"8> c #232F6E",
+"9> c #273373",
+"0> c #2E3A7B",
+"a> c #3A4888",
+"b> c #3E4C8B",
+"c> c #3B4B87",
+"d> c #3B4A8A",
+"e> c #3D4B88",
+"f> c #3F4E8B",
+"g> c #404E8B",
+"h> c #42518C",
+"i> c #455493",
+"j> c #475795",
+"k> c #485793",
+"l> c #48558B",
+"m> c #4A5992",
+"n> c #485794",
+"o> c #4A5694",
+"p> c #1E266B",
+"q> c #1D2668",
+"r> c #1E2869",
+"s> c #1C2867",
+"t> c #1E2A69",
+"u> c #222E6D",
+"v> c #263173",
+"w> c #2D3A77",
+"x> c #394684",
+"y> c #3A4A84",
+"z> c #3E4A8C",
+"A> c #3B4B88",
+"B> c #3D4987",
+"C> c #3C4B89",
+"D> c #3D4C8B",
+"E> c #40508C",
+"F> c #44548E",
+"G> c #44538F",
+"H> c #485592",
+"I> c #485792",
+"J> c #46568C",
+"K> c #42528C",
+"L> c #1A2665",
+"M> c #1E276B",
+"N> c #222C6F",
+"O> c #263271",
+"P> c #2A3574",
+"Q> c #364684",
+"R> c #3C4884",
+"S> c #3B4987",
+"T> c #3D4A87",
+"U> c #3D4A89",
+"V> c #3E4D8B",
+"W> c #42508C",
+"X> c #44528B",
+"Y> c #44538E",
+"Z> c #46548E",
+"`> c #465493",
+" , c #475593",
+"., c #475490",
+"+, c #4A5794",
+"@, c #424E8C",
+"#, c #3C477A",
+"$, c #1A2467",
+"%, c #1D2969",
+"&, c #1C2868",
+"*, c #202C6C",
+"=, c #232F6F",
+"-, c #243075",
+";, c #2E3B7C",
+">, c #2F3A7E",
+",, c #333F7C",
+"', c #3E4A84",
+"), c #3B4A88",
+"!, c #3F4D88",
+"~, c #404F8C",
+"{, c #42508F",
+"], c #44518C",
+"^, c #445490",
+"/, c #485693",
+"(, c #465284",
+"_, c #1B2464",
+":, c #1C266A",
+"<, c #1E276D",
+"[, c #202A6C",
+"}, c #1F2B6A",
+"|, c #25316F",
+"1, c #2C367D",
+"2, c #2E3A74",
+"3, c #2F3B7A",
+"4, c #303F7C",
+"5, c #324283",
+"6, c #3B4889",
+"7, c #3D4A88",
+"8, c #404F8A",
+"9, c #44528E",
+"0, c #475794",
+"a, c #465294",
+"b, c #3A4475",
+"c, c #182059",
+"d, c #1A2462",
+"e, c #1D2869",
+"f, c #1F296A",
+"g, c #212A6D",
+"h, c #252F6F",
+"i, c #263272",
+"j, c #283275",
+"k, c #2A3675",
+"l, c #2E3A77",
+"m, c #3B4887",
+"n, c #3C4A87",
+"o, c #3E4C89",
+"p, c #3F4C88",
+"q, c #42528F",
+"r, c #45558C",
+"s, c #1B2565",
+"t, c #25306F",
+"u, c #283373",
+"v, c #2D3A78",
+"w, c #3C4987",
+"x, c #3E4B88",
+"y, c #3E4C8A",
+"z, c #3E4E89",
+"A, c #3F4E8A",
+"B, c #414E89",
+"C, c #42518D",
+"D, c #414F8B",
+"E, c #445190",
+"F, c #42528D",
+"G, c #42518B",
+"H, c #3C467F",
+"I, c #1C2664",
+"J, c #1F2A6B",
+"K, c #242F6F",
+"L, c #3F4D89",
+"M, c #3F4F8A",
+"N, c #40508B",
+"O, c #1D2765",
+"P, c #3B4988",
+"Q, c #3C4A86",
+"R, c #3C4B87",
+"S, c #404F8B",
+"T, c #3D4B87",
+"U, c #3D4C88",
+"V, c #3F4C87",
+" . + @ @ # $ % & * = - ; ",
+" > , ' ) ! ~ { ] ^ / ( % _ : < [ } | 1 1 ",
+" 2 3 4 5 ' ) ! ~ { ] ^ / ( % _ : < [ 6 7 | | 8 1 ",
+" 9 0 0 a 3 4 b ' ) ! ~ { ] c / ( d _ : < [ 6 7 | e f f 8 g 1 ",
+" h h i 0 a 3 j b ' ) ! ~ { ] c / ( d _ : * [ 6 k | e f 8 8 8 l m ",
+" n o p i 0 q a 3 j b ' ) ! r { ] c s t d _ : * [ 6 | | e f 8 8 l l l g 1 ",
+" u o p h i 0 q a 4 5 b ' v ! r { ] # s % d _ w x } 6 | | e f 8 8 l l y z m m ",
+" A u u o p h i 0 a B 4 5 b ' ! ~ r C ^ # D % E _ < x 6 7 | | f 8 8 8 l F G G H I m J ",
+" K u u o o p i 0 q a 3 j b ' ) ! ~ { ] ^ L D M E _ < x 6 k | e f 8 8 l y G G N G H g m J ",
+" n u u u o p h i 0 q a 3 j b ' v ! ~ { ] c / ( d _ : * [ 6 k | e f 8 O P Q G Q Q G Q H g m J ",
+" K u u u o p h i 0 0 a 3 4 5 b R v ~ r S ^ # s % d _ w x T 6 | | e 8 8 G G Q N G Q N G N H m ; J ",
+" A u u U V W X Y Z ` ...+.@.#.$.%.! ~ { C ^ L D % E _ < x 6 k | | f G O Q G G G N G G Q G G H m ; J ",
+" u u u &.*.X =.Z -. ...+.;.>.,.$.'.! r { ^ ).D M E w * < [ 6 k | e O G G Q Q Q Q G Q G N G N N m m ; ",
+" u u o &.W X =.Y ` .!.~.+.@.{.$.%.].^./.(.% E L _.:.<.[.}.|.6 k 1.Q Q Q Q Q Q Q Q Q Q Q Q Q G G 2.3.3.1 ",
+" n o o o *.X Y Z -. .!.+.;.#.#.{.$.4.5.6.(.d 7.8.9.0.a.b.c.d.e.< f.g.f.f.f.f.Q g.g.f.g.f.f.g.f.Q Q - - - h.i. ",
+" o p p p j.Y Z ` .!.!.+.;.>.,.k.l.^.6.L % d # m.n.o.p.q.r.c.s.f.t.f.f.f.f.f.f.f.f.f.f.g.g.f.g.f.g.u.u.v.- h. ",
+" h p h h i Z -.` w. .+.+.;.,.,.{.x.{ y.z.A.% B.C.D.E.F.G.H.I.J.K.L.M.N.f.M.M.O.O.O.M.O.O.O.P.Q.M.f.P.R.R.u.u.u.h. ",
+" 9 h i i i 0 S.T. .!.+.+.;.>.,.$.U.V.W.X.Y.( Z.d `. +.+++@+G.#+$+%+&+*+=+O.O.-+M.O.O.O.O.O.M.-+M.O.O.;+>+,+'+R.R.u.1 ",
+" 0 i 0 0 0 q !.)+!++.;.@.#.{.{.~+V.5.{+]+^+( Z./+(+_+:+<+++<+:+[+}+|+1+).-+O.2+-+-+3+-+O.3+4+3+O.O.O.>+B.>+>+,+'+5+6+ ",
+" 0 0 q q a a )+7++.;.@.,.{.$.%.8+9+0++ a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+o+r+-+2+s+t+2+2+t+s+4+t+4+3+u+v+w+B.>+>+,+'+ ",
+" 2 a a a a B 3 +.x+;.,.{.,.$.'.y+z+A+B+*+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+R+S+T+U+V+W+X+s+s+X+s+Y+2+2+Z+q+`+`+u+ @w+w+.@,+h. ",
+" 3 3 3 3 4 4 j j 5 b ' {.%.%.'.'.A++@@@#@*+$@%@&@*@6.=@-@;@>@,@'@)@!@~@{@]@^@/@(@_@:@Y+Y+<@Y+2+[@}@|@|@|@|@1@`+u+ @w+B.,+ ",
+" 2@4 4 j j 5 5 b b b ' ' ) '.'.y+<@3@A+4@5@6@`+7@8@9@0@a@b@c@d@{@e@f@g@h@_@i@j@k@l@m@n@{@o@Y+o@Y+p@q@p@q@q@q@|@1@1@`+ @w+w+6+ ",
+" , 5 b b b b b ' ' R ) v ! '.y+<@Y+r@$@s@t@u@y.v@A+w@a@0@{@x@y@z@A@A@B@C@D@E@F@D@G@H@I@J@K@o@L@]@M@M@K@M@!@p@q@q@|@1@`+u+ @6+ ",
+" ' ' ' ' ' ' ' ) v v ! ! ~ <@Y+<@s+s@N@@@O@P@Q@o+R@S@T@U@V@W@(@X@Y@Z@`@`@ #.#+#@###$#%#&#*#, X@X@X@X@X@X@, M@M@p@q@|@=#-#`+;# ",
+" ) ) ) ) ) v ! ! ! ~ ~ r { Y+s+t+s+>#,#'#)#A+!#~#R@{#]#^#j@j@C@H@/#/#(#_#:#.#<#[#}#|#1#2#3#4#D@*#*#D@D@D@X@, , M@!@p@q@5#-#`+ ",
+". ! ! ! ! ! ! ~ ~ ~ r { { C ] s+4+O.6#7#8#P@9#0#a#b#/@c#d#e#f#4#g#.#h#i#$#j#k#l#m#n#o#p#q#r#s#t#u#_#*#*#*#D@D@X@, M@M@p@q@5#v#;#",
+"+ ~ ~ ~ ~ r r r { { S C ] ^ @ -+-+-+4+w#x#r+y#z#A#W@]#g@B#C#D#E#F#G#H#I#J#K#L#M#N#O#P#Q#R#S#r#k#s#s#t#u#_#*#*#D@D@X@, M@T#q@5#U#",
+"@ { { { { { { C ] V#W#X#Y#Z#Z#`# $ $`#.$+$@$#$$$%$&$*$=$-$;$>$,$'$)$!$~${$]$^$/$($]$_$:$<$[$}$|$1$1$2$3$4$5$6$*#*#D@X@, M@T#q@v#",
+"@ ] ] ] ] ] ] ^ 7$8$9$0$a$b$c$d$d$e$f$g$h$i$j$k$l$m$n$o$p$q$r$r$s$t$u$v$w$x$y$z$A$B$C$C$D$D$z$E$F$G$H$I$J$K$L$M$_#*#N$D@, M@T#5#",
+"# ^ ^ c c c # { Z#O$P$Q$R$S$S$T$T$U$V$W$X$Y$Z$`$ %.%+%+%@%#%$%%%$%&%*%=%-%;%;%>%,%'%)%)%;%)%!%;%>%&%~%{%]%^%/%2$(%_#*#N$D@X@M@q@",
+"$ / / / / s s _%:%<%[%}%|%1%2%3%4%5%4%6%7%8%9%9%0%a%b%a%c%b%b%b%c%d%e%f%e%e%g%h%i%j%h%j%j%j%h%h%h%h%d%k%l%m%n%o%p%s#_#q%N$D@, T#",
+"% ( ( ( ( t % r%s%t%u%v%w%x%x%T$y%z%W$A%B%C%D%`$`$+%@%E%.%F%G%G%%%*%H%>%;%>%>%)%;%I%J%J%J%J%I%)%!%!%K%+%L%M%N%O%P%Q%s#_#q%N$R%M@",
+"& % % d d d d E S%T%U%V%W%X%Y%Z%`%e$ &.&+&@&#&$&%&&&*&&&=&-&;&>&,&'&)&D$D$!&~&{&]&^&/&(&]&(&{&{&/&_&v$:&<&[&}&|&1&2&Q%s#_#q%N$, ",
+"* _ _ _ _ _ _ _ _ 3&4&5&6&7&8&9&0&a&b&c&d&e&e&f&&$g&h&i&j&>$k&l&m&n&o&p&q&r&s&t&u&v&w&x&y&z&A&B&C&C&D&E&F&G&H&I&2 J&K&Q%s#_#q%R%",
+"= : : : : : w < < * x x [ }.e.L.O.O.4@L&2+M&N&O&d#P&d#Q&G#R&S&T&U&V&W&X&Y&Y&Z&`& *.*+*@*#*$*%*&*****=*-*-*;*>*I&I&2 ,*K&Q%'*q%R%",
+"- < < < * * x x x [ T 6 6 }.e.)*!*~*{*q+]*^*/*P&(*_*:*<*[*}*L#|*1*2*3*4*5*6*`&7*8*9*0*a*b*c*d*e*f*f*f*g*=*-*;*>*I&I&2 ,*Q%Q%_#h*",
+"; [ [ [ [ [ } 6 6 6 6 k T < i*j*k*~*l*m*n*M&o*c@c@p*q*:#r*s*t*K#u*v*X&w* *x* *y*z*A*B*C*D*E*F*G*G*G*e*f*x***Z&H*>*I&I*J&,*Q%'*h*",
+" } 6 6 6 6 6 7 k k | g.T = J*t.K*. O.v+u@1@L*c@O&O&M*N*O*P*|*>.Q*V&R*R*;*Z&S*T*U*V*W*X*Y*Z*`* =8*8*8*G*e*f*g*Z&.=>*+=2 J&Q%'* ",
+" | 7 7 k | | | Q G }.k @=6 6 #=7.$=%=v+4@&=&=*===-=N*;=P*>=u*u*>.,='=)=!=~={=]=^=/=(=_=X*:=<=[=}=|=|=8*G*e*f*g*H*1=2=+=J&,*3= ",
+" 1 | | | | | | e e 4=5=6 6 T j*6=7=7=8=9=^ 0=a=_.b=M*O*P*c=d=,.@.R*R*e=f=g=z*h=i=j=k=l=m=n=o=p=q=}=K |=8*G*e*f*=*H*>*+=2 J&r= ",
+" 1 | e e e e f f s=f t=e }.T = < u=7.v=O.w=x=y=c@z=N*A=B=C=D=E=F=G=H=I=6*J=]=K=L=M=N=O=P=Q=R=S=T=U=V=K W=8*G*X=g*H*1=I&2 J&r= ",
+" 8 f f f f 8 8 f Q G = e k = Y=j*Z=`=L ,# -&=.-b#+-O*@-#-$-%-&-u&*-=-.*--f*;->-,-'-)-!-~-{-S=]-^-/-(-K W=_-e*f*=*.=2=+=:- ",
+" 1 f 8 8 8 8 f f <-O 8 O f [-}-u=|-8=D+1-2-3-4-5-A@6-7-8-9-0-a-b-c-d- *--e-f-g-h-h-i-j-k-l-m-n-q=o-p-q-|=W=G*f*g*.=2=+=h* ",
+" 8 8 8 8 8 r-s-8 5=<-8 t=k t-u-v-t O.w-x-y-z-A-d#B-C-D-E-F-G-H-I-p-f=--J-K-L-M-N-O-P-q=Q-R-S-S-T-U-V-W-X-_-Y-g*H*1=+= ",
+" g 8 l l l s-l 8 Z-s-8 5=`- ;u=.;>++;4@A+0#@;n+(@#;$;%;F-&;F-0-*;=;=*x*-;;;>;,;';N-o=]-);!;~;{;!;];^;/;/;_-Y-g*H*1=(; ",
+" 1 l l l l l l <-s-l 8 _;:;= #=<;[;B.};M&|;1;2;l@3;4;5;E-F-G-6;7;8;f=9;z*0;j=*-a;b;c;d;e;f;g;{-h;P-^;/;/;_-Y-g*H*1=3= ",
+" m l l I l l m g i;8 8 j;k;l;'+m;n;o;2+2+n+e@X@p;q;r;D-0-a-s;t;u;v;w;x;9*y;_-z;A;B;C;D;E;F;G;H;}=I;e-J;_-Y-g*H*(; ",
+" g I I I I K;F l L;g - M;N;Z=O;P;)#Q;0#{#U@k@R;S;o%T;U;V;W;X;Y;Y&Z;`;f* >>;.>+>@>#>$>%>%>&>#>/;^;/;/;_-*>g*1= ",
+" 1 I I I I I m I l =>e ->;>6=8=>>,>};=@R@'>)>!>/#P%@-~>{>]>I*^>/>Y&(>_>:>:><>[>}>~>|>(-1>2>n W-/;/;e-G*X=g*3= ",
+" L;I 3.3.I K;3>4>5>8 6>7>j*8>8=9>'#L*1;0>z@z=F#K&a>I*b>c>d>e>f>g>h>S*--i>y;j=j>k>_=l>h-m>n>}=/;o>e-Y-g*.= ",
+" N N p>m q>K;I K;r>s>t>u>,+v>w=`+^*w>n+d#B@:#x>u*y>z>A>B>C>D>Y;E>H*F>G>F>G*H>I>k=';_-X*X*W-/;/;J>J>K> ",
+" J H G 5>L>M>L;3.<-:;6 N>7>>+O>P>7@)@n+b#z=F@Q>u*y>>.R>S>T>U>V>X&5*f=W>&*X>Y>Z>`>j= ,.,X-+,e-e-!+@,#, ",
+" J ; 5>$,F m i;%,&,*,7>=,d+-,u+1@M&;,>,,,~+u*,.y>',D>),V&e>e>!,/>~,H*{,],^,J-`;-;-;/,8* =J>J>(,#, ",
+" J ; _,L;; :,l <,[,},N>|,+ q+M&1,2,3,4,5,Q>{.u*u*',6,),C>7,e>+=g>8,E>H*W>h>x;f*9,0,J-o>a,K>b, ",
+" c,; d,; 3>e,f,[,g,7>h,i,j,k,=@l,e@D@*#t#Q%K&1&2 7,m,n,o,o,o,V>p,g>g>v;`&q,J=f*G=r,J>K>#, ",
+" J s,1 3>3.2. ;R.'+t,9=u,k,&=v,c#D@*#_#t#Q%K&1&2 w,1&n,x,y,>*z,A,B,C,C,D,x;C,E,F,G,H, ",
+" 1 I,3>2.J,u.R.K,9=9>P>&=!@M@X@D@*#_#s#Q%2&J&2 w,S>n,T>o,L,A,A,M,M,D,N,C,g*.= ",
+" i.O,f, ; ;R.K,w+9>x-|@p@M@, X@N$*#_#s#Q%K&,*2 P,Q,R,n,T>x,x,L,A,1=S,1=3= ",
+" h.u.5+,+.@w+ @`+=#q@p@M@, D@N$q%_#s#Q%K&,*J&2 T,n,7,U,U,+=+=V,(; ",
+" 1 6+'+,+B.w+u+-#5#q@T#M@, D@N$q%_#s#Q%Q%,*J&J&2 2 +=+=+=(;3= ",
+" h.,+w+ @`+-#5#q@T#M@X@D@N$q%_#'*Q%Q%Q%,*J&J&:-h* ",
+" 6+6+;#`+v#5#q@T#M@, R%N$q%q%_#'*'*3=r=r= ",
+" ;#U#v#5#q@T#M@, R%R%h*h* "};
diff --git a/arts/builder/pics/Synth_EMPTY.xpm b/arts/builder/pics/Synth_EMPTY.xpm
new file mode 100644
index 00000000..0fc95945
--- /dev/null
+++ b/arts/builder/pics/Synth_EMPTY.xpm
@@ -0,0 +1,1119 @@
+/* XPM */
+static char * Synth_EMPTY_xpm[] = {
+"64 64 1052 2",
+" c None",
+". c #253073",
+"+ c #273276",
+"@ c #293378",
+"# c #283278",
+"$ c #263077",
+"% c #252F75",
+"& c #232E74",
+"* c #212B71",
+"= c #202A6E",
+"- c #1E296A",
+"; c #1C2667",
+"> c #2B3671",
+", c #313D7B",
+"' c #384288",
+") c #353F87",
+"! c #323D83",
+"~ c #2F3A80",
+"{ c #2D377D",
+"] c #2A357B",
+"^ c #29347A",
+"/ c #273177",
+"( c #253076",
+"_ c #232D72",
+": c #222C72",
+"< c #212C71",
+"[ c #202B70",
+"} c #202A70",
+"| c #1F296E",
+"1 c #1B2463",
+"2 c #3C4988",
+"3 c #434D95",
+"4 c #414C93",
+"5 c #3D488D",
+"6 c #202A6F",
+"7 c #1F2A6F",
+"8 c #1E286C",
+"9 c #37437E",
+"0 c #4F59A0",
+"a c #485399",
+"b c #3B458D",
+"c c #283379",
+"d c #242E74",
+"e c #1E296D",
+"f c #1E286D",
+"g c #1C2669",
+"h c #5862A8",
+"i c #555FA6",
+"j c #3F4B90",
+"k c #1F2A6E",
+"l c #1D276B",
+"m c #1C2668",
+"n c #4B5A97",
+"o c #616CB3",
+"p c #5C67AF",
+"q c #4B579B",
+"r c #2E397F",
+"s c #263177",
+"t c #253075",
+"u c #6872B4",
+"v c #343F84",
+"w c #222C71",
+"x c #212B70",
+"y c #1B2666",
+"z c #1B2366",
+"A c #45538B",
+"B c #445194",
+"C c #2B367B",
+"D c #263076",
+"E c #232E73",
+"F c #1D266B",
+"G c #1E266C",
+"H c #1A2264",
+"I c #1D276A",
+"J c #171F57",
+"K c #4A5996",
+"L c #273277",
+"M c #242F74",
+"N c #1A2664",
+"O c #1E296C",
+"P c #1D296B",
+"Q c #1E2A6C",
+"R c #354186",
+"S c #2C377B",
+"T c #202B6F",
+"U c #6672BC",
+"V c #666EB4",
+"W c #5E6AB4",
+"X c #5A66AC",
+"Y c #565EA4",
+"Z c #525EA4",
+"` c #4E5AA2",
+" . c #4A569C",
+".. c #465296",
+"+. c #424E94",
+"@. c #3E4A8E",
+"#. c #3E468C",
+"$. c #36428C",
+"%. c #363E84",
+"&. c #626EB4",
+"*. c #5E66AC",
+"=. c #5662AB",
+"-. c #525AA4",
+";. c #424A94",
+">. c #3A4A8C",
+",. c #3A468C",
+"'. c #323E84",
+"). c #273278",
+"!. c #4A529C",
+"~. c #464E93",
+"{. c #3A428C",
+"]. c #313983",
+"^. c #2D387E",
+"/. c #2A3479",
+"(. c #263176",
+"_. c #222D72",
+":. c #212A6F",
+"<. c #1F2B6F",
+"[. c #212A6E",
+"}. c #1E286A",
+"|. c #1D2769",
+"1. c #303B81",
+"2. c #2C367E",
+"3. c #293479",
+"4. c #232E72",
+"5. c #222D71",
+"6. c #212D72",
+"7. c #222E74",
+"8. c #222A6F",
+"9. c #1E2868",
+"0. c #1A235E",
+"a. c #5A62AC",
+"b. c #35418B",
+"c. c #2F3B80",
+"d. c #232D73",
+"e. c #222D73",
+"f. c #222B70",
+"g. c #212B6C",
+"h. c #20296C",
+"i. c #4E569C",
+"j. c #323A80",
+"k. c #29357A",
+"l. c #283178",
+"m. c #263075",
+"n. c #263171",
+"o. c #232F70",
+"p. c #222E73",
+"q. c #233070",
+"r. c #24306D",
+"s. c #232E70",
+"t. c #242F70",
+"u. c #252E6F",
+"v. c #242E73",
+"w. c #262E73",
+"x. c #262F73",
+"y. c #263273",
+"z. c #222E6C",
+"A. c #223264",
+"B. c #222D6E",
+"C. c #4E5AA4",
+"D. c #4A5A9C",
+"E. c #303C81",
+"F. c #2D397E",
+"G. c #2C357D",
+"H. c #273378",
+"I. c #263276",
+"J. c #252F76",
+"K. c #253070",
+"L. c #242F73",
+"M. c #243071",
+"N. c #24306F",
+"O. c #243073",
+"P. c #253177",
+"Q. c #26326E",
+"R. c #263277",
+"S. c #263078",
+"T. c #26327C",
+"U. c #252D72",
+"V. c #253071",
+"W. c #242F6E",
+"X. c #232E6E",
+"Y. c #46529C",
+"Z. c #425294",
+"`. c #354182",
+" + c #2B357D",
+".+ c #273178",
+"++ c #263175",
+"@+ c #262F74",
+"#+ c #273073",
+"$+ c #263272",
+"%+ c #25306E",
+"&+ c #273173",
+"*+ c #26336C",
+"=+ c #283273",
+"-+ c #2A3674",
+";+ c #26366C",
+">+ c #2A3274",
+",+ c #232E6C",
+"'+ c #212B69",
+")+ c #464E94",
+"!+ c #2F3B81",
+"~+ c #2D3679",
+"{+ c #2B357C",
+"]+ c #273272",
+"^+ c #273274",
+"/+ c #273076",
+"(+ c #243074",
+"_+ c #283274",
+":+ c #263174",
+"<+ c #283374",
+"[+ c #293373",
+"}+ c #283575",
+"|+ c #293577",
+"1+ c #293376",
+"2+ c #293575",
+"3+ c #2B3779",
+"4+ c #28337A",
+"5+ c #293574",
+"6+ c #2B377D",
+"7+ c #2A367C",
+"8+ c #2A327C",
+"9+ c #293474",
+"0+ c #273273",
+"a+ c #273271",
+"b+ c #3E4A94",
+"c+ c #323A84",
+"d+ c #2E3A7F",
+"e+ c #2A3679",
+"f+ c #2A3579",
+"g+ c #263470",
+"h+ c #263274",
+"i+ c #273377",
+"j+ c #273371",
+"k+ c #27346F",
+"l+ c #293475",
+"m+ c #2A357A",
+"n+ c #2A3675",
+"o+ c #2C3878",
+"p+ c #2D3978",
+"q+ c #2D3777",
+"r+ c #2D3976",
+"s+ c #2E397B",
+"t+ c #2D3775",
+"u+ c #2B3873",
+"v+ c #2F3B77",
+"w+ c #30397E",
+"x+ c #2F3775",
+"y+ c #2A386E",
+"z+ c #2E3A7D",
+"A+ c #293579",
+"B+ c #293473",
+"C+ c #263170",
+"D+ c #2A357C",
+"E+ c #2A3379",
+"F+ c #293278",
+"G+ c #273279",
+"H+ c #2A3378",
+"I+ c #283377",
+"J+ c #283378",
+"K+ c #2C3779",
+"L+ c #2B3679",
+"M+ c #2B3877",
+"N+ c #2E397C",
+"O+ c #2D397C",
+"P+ c #2D397A",
+"Q+ c #2E3B7A",
+"R+ c #2E387D",
+"S+ c #2F3B7D",
+"T+ c #2E3C7A",
+"U+ c #2F387D",
+"V+ c #2F3B7F",
+"W+ c #313D7F",
+"X+ c #303E7E",
+"Y+ c #2F387C",
+"Z+ c #2E367C",
+"`+ c #2C3877",
+" @ c #2C3777",
+".@ c #2A3676",
+"+@ c #2B3571",
+"@@ c #2B3478",
+"#@ c #283477",
+"$@ c #2A3375",
+"%@ c #2A3474",
+"&@ c #2A3576",
+"*@ c #2B3676",
+"=@ c #2C3778",
+"-@ c #2C387A",
+";@ c #2C397B",
+">@ c #2E387B",
+",@ c #2E3A7C",
+"'@ c #2E3B7B",
+")@ c #2F3C7C",
+"!@ c #2F3D7C",
+"~@ c #303D7D",
+"{@ c #303D7E",
+"]@ c #313F7E",
+"^@ c #313E80",
+"/@ c #313D7D",
+"(@ c #313E7F",
+"_@ c #324081",
+":@ c #323E81",
+"<@ c #2E3E7C",
+"[@ c #2D3A79",
+"}@ c #283677",
+"|@ c #2A347C",
+"1@ c #263372",
+"2@ c #283479",
+"3@ c #283578",
+"4@ c #2B377B",
+"5@ c #2F3C7D",
+"6@ c #2F3C7E",
+"7@ c #303C7D",
+"8@ c #313E7E",
+"9@ c #323E7E",
+"0@ c #333F7F",
+"a@ c #323F7E",
+"b@ c #333F80",
+"c@ c #344081",
+"d@ c #333F7E",
+"e@ c #33417F",
+"f@ c #354183",
+"g@ c #34407E",
+"h@ c #2F3B7E",
+"i@ c #303980",
+"j@ c #2F3C7A",
+"k@ c #2A3279",
+"l@ c #293478",
+"m@ c #2B357A",
+"n@ c #2B3579",
+"o@ c #2D397B",
+"p@ c #2E3B7D",
+"q@ c #2F3B7B",
+"r@ c #2F3D7F",
+"s@ c #303D7F",
+"t@ c #313E7D",
+"u@ c #313F81",
+"v@ c #334082",
+"w@ c #334080",
+"x@ c #344183",
+"y@ c #354284",
+"z@ c #35417E",
+"A@ c #344284",
+"B@ c #364386",
+"C@ c #364385",
+"D@ c #364282",
+"E@ c #354383",
+"F@ c #344180",
+"G@ c #2B3776",
+"H@ c #2B3675",
+"I@ c #283370",
+"J@ c #29337C",
+"K@ c #273375",
+"L@ c #293477",
+"M@ c #283474",
+"N@ c #2C377C",
+"O@ c #2C3875",
+"P@ c #2E3A7E",
+"Q@ c #303C7F",
+"R@ c #303D7C",
+"S@ c #344181",
+"T@ c #344281",
+"U@ c #354280",
+"V@ c #344282",
+"W@ c #34427F",
+"X@ c #374280",
+"Y@ c #364482",
+"Z@ c #374487",
+"`@ c #374582",
+" # c #374586",
+".# c #384485",
+"+# c #344080",
+"@# c #2D3876",
+"## c #26327B",
+"$# c #273477",
+"%# c #2A3475",
+"&# c #2A3775",
+"*# c #2C3879",
+"=# c #2E3A78",
+"-# c #2F3B7C",
+";# c #303C7B",
+"># c #323E7F",
+",# c #323F80",
+"'# c #333F81",
+")# c #334180",
+"!# c #364283",
+"~# c #364382",
+"{# c #374385",
+"]# c #384584",
+"^# c #354482",
+"/# c #384588",
+"(# c #384587",
+"_# c #394585",
+":# c #394587",
+"<# c #394686",
+"[# c #394687",
+"}# c #374483",
+"|# c #354382",
+"1# c #354282",
+"2# c #2B3775",
+"3# c #2A337C",
+"4# c #283570",
+"5# c #2D377C",
+"6# c #2D3A7C",
+"7# c #323F81",
+"8# c #344182",
+"9# c #334181",
+"0# c #344382",
+"a# c #354281",
+"b# c #364484",
+"c# c #364583",
+"d# c #374482",
+"e# c #384585",
+"f# c #374684",
+"g# c #374685",
+"h# c #374480",
+"i# c #3A4686",
+"j# c #394885",
+"k# c #3A4988",
+"l# c #3A4A8A",
+"m# c #3A4989",
+"n# c #3A4786",
+"o# c #2F3B78",
+"p# c #2B3674",
+"q# c #283473",
+"r# c #2C387D",
+"s# c #2A3778",
+"t# c #2E3B7C",
+"u# c #313D80",
+"v# c #33407E",
+"w# c #364483",
+"x# c #394684",
+"y# c #374686",
+"z# c #374682",
+"A# c #3A4785",
+"B# c #394884",
+"C# c #394888",
+"D# c #3C4886",
+"E# c #3C4A8B",
+"F# c #3C4A87",
+"G# c #3A4887",
+"H# c #394685",
+"I# c #384685",
+"J# c #384583",
+"K# c #2A337B",
+"L# c #2E3976",
+"M# c #333D79",
+"N# c #313D77",
+"O# c #333E7B",
+"P# c #374380",
+"Q# c #364485",
+"R# c #374683",
+"S# c #374583",
+"T# c #3A4889",
+"U# c #364582",
+"V# c #384682",
+"W# c #3C498A",
+"X# c #3C4B85",
+"Y# c #3B4A87",
+"Z# c #3D4C8C",
+"`# c #3E4B8C",
+" $ c #3D4B8C",
+".$ c #3B4988",
+"+$ c #394786",
+"@$ c #33407D",
+"#$ c #27347B",
+"$$ c #2D3A7F",
+"%$ c #2F3A7B",
+"&$ c #364383",
+"*$ c #384684",
+"=$ c #3B4887",
+"-$ c #3A4885",
+";$ c #384883",
+">$ c #3D4A88",
+",$ c #3D4C8A",
+"'$ c #3C4B88",
+")$ c #394986",
+"!$ c #3C4A84",
+"~$ c #3F4C8C",
+"{$ c #3F4E8E",
+"]$ c #3E4E8A",
+"^$ c #3E4E8D",
+"/$ c #3E4D8B",
+"($ c #3D4B8A",
+"_$ c #3A4888",
+":$ c #3A4787",
+"<$ c #263279",
+"[$ c #283276",
+"}$ c #283478",
+"|$ c #2A3771",
+"1$ c #33407F",
+"2$ c #344385",
+"3$ c #344084",
+"4$ c #374585",
+"5$ c #384488",
+"6$ c #374587",
+"7$ c #394788",
+"8$ c #3B488C",
+"9$ c #394784",
+"0$ c #3B488A",
+"a$ c #3B498A",
+"b$ c #3B4B88",
+"c$ c #3F4D89",
+"d$ c #3E4D88",
+"e$ c #3F4F89",
+"f$ c #414E91",
+"g$ c #404F8E",
+"h$ c #404E8D",
+"i$ c #404D8C",
+"j$ c #3E4C8B",
+"k$ c #3C4A89",
+"l$ c #3A4886",
+"m$ c #35427E",
+"n$ c #283277",
+"o$ c #27327C",
+"p$ c #2C387B",
+"q$ c #364083",
+"r$ c #333C83",
+"s$ c #34407F",
+"t$ c #354385",
+"u$ c #394789",
+"v$ c #3C4A8C",
+"w$ c #3B4986",
+"x$ c #3E4B8A",
+"y$ c #3C4B89",
+"z$ c #3F4C88",
+"A$ c #404F8D",
+"B$ c #41518D",
+"C$ c #42518C",
+"D$ c #42508F",
+"E$ c #41518E",
+"F$ c #404F90",
+"G$ c #3F4E8C",
+"H$ c #323F7C",
+"I$ c #26346F",
+"J$ c #2F3B79",
+"K$ c #334084",
+"L$ c #384186",
+"M$ c #374687",
+"N$ c #3A4685",
+"O$ c #3C498C",
+"P$ c #3E4C88",
+"Q$ c #3F4E8B",
+"R$ c #41508E",
+"S$ c #425190",
+"T$ c #414E8A",
+"U$ c #43538D",
+"V$ c #42528E",
+"W$ c #435190",
+"X$ c #41508C",
+"Y$ c #404E8C",
+"Z$ c #3E4D8C",
+"`$ c #232D71",
+" % c #242E71",
+".% c #283077",
+"+% c #28327C",
+"@% c #28347C",
+"#% c #2A3678",
+"$% c #323E80",
+"%% c #323C84",
+"&% c #323F7B",
+"*% c #344384",
+"=% c #384483",
+"-% c #384889",
+";% c #3F4D8E",
+">% c #3E4C8D",
+",% c #3E4D8A",
+"'% c #414E90",
+")% c #425090",
+"!% c #425290",
+"~% c #44548E",
+"{% c #44538E",
+"]% c #455294",
+"^% c #43528E",
+"/% c #445295",
+"(% c #435391",
+"_% c #42518F",
+":% c #3F4D8A",
+"<% c #3E4B89",
+"[% c #3B4885",
+"}% c #2A3477",
+"|% c #2A3677",
+"1% c #283670",
+"2% c #303E80",
+"3% c #303C80",
+"4% c #353F81",
+"5% c #374383",
+"6% c #384384",
+"7% c #3A4788",
+"8% c #3A4A89",
+"9% c #3C4A88",
+"0% c #3F4D8C",
+"a% c #42508D",
+"b% c #41508D",
+"c% c #43528C",
+"d% c #43548F",
+"e% c #445494",
+"f% c #44548C",
+"g% c #445293",
+"h% c #445391",
+"i% c #435090",
+"j% c #42518E",
+"k% c #374581",
+"l% c #232C71",
+"m% c #242F76",
+"n% c #252F73",
+"o% c #253176",
+"p% c #293673",
+"q% c #2E3C7C",
+"r% c #313E79",
+"s% c #313C81",
+"t% c #324084",
+"u% c #344082",
+"v% c #374382",
+"w% c #374786",
+"x% c #3B478C",
+"y% c #3C4B8C",
+"z% c #3E4E8E",
+"A% c #414F8C",
+"B% c #455391",
+"C% c #475694",
+"D% c #445493",
+"E% c #455394",
+"F% c #424F8C",
+"G% c #465494",
+"H% c #46588F",
+"I% c #45568F",
+"J% c #455491",
+"K% c #445390",
+"L% c #35417C",
+"M% c #212D71",
+"N% c #253173",
+"O% c #283179",
+"P% c #273476",
+"Q% c #303C77",
+"R% c #374484",
+"S% c #384489",
+"T% c #3A478B",
+"U% c #3A4684",
+"V% c #3B4B8C",
+"W% c #404E90",
+"X% c #435290",
+"Y% c #42538D",
+"Z% c #455494",
+"`% c #455593",
+" & c #44558D",
+".& c #465690",
+"+& c #475793",
+"@& c #485495",
+"#& c #475594",
+"$& c #465592",
+"%& c #202C71",
+"&& c #222E72",
+"*& c #2D3979",
+"=& c #364082",
+"-& c #344484",
+";& c #384688",
+">& c #3D498D",
+",& c #3E4E8C",
+"'& c #435191",
+")& c #465491",
+"!& c #485795",
+"~& c #475496",
+"{& c #485894",
+"]& c #46568B",
+"^& c #495A92",
+"/& c #495996",
+"(& c #495992",
+"_& c #414F8A",
+":& c #1F2B6E",
+"<& c #222C70",
+"[& c #252E73",
+"}& c #2B3777",
+"|& c #2D3879",
+"1& c #2F3C78",
+"2& c #324080",
+"3& c #364287",
+"4& c #384481",
+"5& c #3E4B8D",
+"6& c #424F8F",
+"7& c #425292",
+"8& c #435291",
+"9& c #45528D",
+"0& c #465594",
+"a& c #43548C",
+"b& c #475991",
+"c& c #4A5A99",
+"d& c #485791",
+"e& c #485593",
+"f& c #4B5B9A",
+"g& c #4C5B98",
+"h& c #4A5A95",
+"i& c #495894",
+"j& c #404E8A",
+"k& c #3E4D89",
+"l& c #394680",
+"m& c #1F2A6D",
+"n& c #1F286D",
+"o& c #253072",
+"p& c #263172",
+"q& c #293675",
+"r& c #2B3879",
+"s& c #303A7B",
+"t& c #313F83",
+"u& c #384888",
+"v& c #3B498C",
+"w& c #42508E",
+"x& c #435292",
+"y& c #455492",
+"z& c #465695",
+"A& c #475691",
+"B& c #48568F",
+"C& c #47578F",
+"D& c #495993",
+"E& c #48568C",
+"F& c #4C5C9C",
+"G& c #4C5D9C",
+"H& c #4D5E98",
+"I& c #333E78",
+"J& c #1E296E",
+"K& c #1E2A6D",
+"L& c #222D70",
+"M& c #253171",
+"N& c #283476",
+"O& c #2A3773",
+"P& c #323F7F",
+"Q& c #384285",
+"R& c #3A4687",
+"S& c #3E4A84",
+"T& c #414E92",
+"U& c #405090",
+"V& c #44528F",
+"W& c #45558F",
+"X& c #4A5898",
+"Y& c #485A92",
+"Z& c #4A599C",
+"`& c #4A5891",
+" * c #4B5A95",
+".* c #4B5B96",
+"+* c #4D5D97",
+"@* c #4E5F98",
+"#* c #505E99",
+"$* c #4F5E9D",
+"%* c #4C5D98",
+"&* c #485893",
+"** c #455390",
+"=* c #212B6F",
+"-* c #232E6D",
+";* c #253074",
+">* c #293674",
+",* c #2D387A",
+"'* c #344280",
+")* c #3A478C",
+"!* c #3B4A8D",
+"~* c #414E8C",
+"{* c #445291",
+"]* c #465593",
+"^* c #46568E",
+"/* c #485A91",
+"(* c #485897",
+"_* c #4A578D",
+":* c #4B5C95",
+"<* c #4B5A93",
+"[* c #4E5E99",
+"}* c #4E5E97",
+"|* c #4D5D98",
+"1* c #4F5F9C",
+"2* c #4C5C97",
+"3* c #475692",
+"4* c #3A4883",
+"5* c #1E276C",
+"6* c #202B6E",
+"7* c #1F2B70",
+"8* c #242E70",
+"9* c #273370",
+"0* c #293573",
+"a* c #2C387C",
+"b* c #2C397A",
+"c* c #2D3A7A",
+"d* c #374386",
+"e* c #3C4885",
+"f* c #3C4A8A",
+"g* c #404F8C",
+"h* c #414F8F",
+"i* c #465694",
+"j* c #465691",
+"k* c #475697",
+"l* c #4A5895",
+"m* c #4A5B94",
+"n* c #4C5B97",
+"o* c #4C5A92",
+"p* c #4F5F9D",
+"q* c #4F609A",
+"r* c #52639E",
+"s* c #4D5E9C",
+"t* c #4A5991",
+"u* c #4F5A94",
+"v* c #1D286C",
+"w* c #1D276C",
+"x* c #212B6D",
+"y* c #212E6E",
+"z* c #232F73",
+"A* c #283470",
+"B* c #2A3575",
+"C* c #2C377A",
+"D* c #2B3876",
+"E* c #2E3B76",
+"F* c #354388",
+"G* c #384787",
+"H* c #404D8B",
+"I* c #445492",
+"J* c #465791",
+"K* c #495899",
+"L* c #47578E",
+"M* c #4B5995",
+"N* c #4C588F",
+"O* c #4B5A92",
+"P* c #4F5E93",
+"Q* c #50619D",
+"R* c #51629D",
+"S* c #4B5A8D",
+"T* c #4A5A9A",
+"U* c #4E5E94",
+"V* c #4A5994",
+"W* c #495693",
+"X* c #455490",
+"Y* c #1C276A",
+"Z* c #1F296D",
+"`* c #202B6B",
+" = c #242F72",
+".= c #25326D",
+"+= c #2C3976",
+"@= c #2E3A7A",
+"#= c #3E4C8C",
+"$= c #445491",
+"%= c #475492",
+"&= c #475695",
+"*= c #495995",
+"== c #485895",
+"-= c #4F5F9B",
+";= c #4F6098",
+">= c #506099",
+",= c #4C598E",
+"'= c #4B5C97",
+")= c #4A5A9B",
+"!= c #4A5A94",
+"~= c #3E4B85",
+"{= c #1D2768",
+"]= c #1F296C",
+"^= c #232F72",
+"/= c #25306D",
+"(= c #293576",
+"_= c #2A3774",
+":= c #2D3977",
+"<= c #303B80",
+"[= c #3D4B89",
+"}= c #43518F",
+"|= c #46558D",
+"1= c #495791",
+"2= c #4A5993",
+"3= c #4A5B95",
+"4= c #4D5A90",
+"5= c #4E5E9B",
+"6= c #4E5F9B",
+"7= c #4F5F9A",
+"8= c #4E5B8F",
+"9= c #4F609C",
+"0= c #1C2769",
+"a= c #20296D",
+"b= c #212C6F",
+"c= c #222C6D",
+"d= c #23306F",
+"e= c #263275",
+"f= c #293578",
+"g= c #364384",
+"h= c #40508D",
+"i= c #43508F",
+"j= c #43528F",
+"k= c #475495",
+"l= c #4A5793",
+"m= c #4B5991",
+"n= c #495891",
+"o= c #4C5B95",
+"p= c #4D5B90",
+"q= c #4D5A8F",
+"r= c #4F5E9A",
+"s= c #4D5E96",
+"t= c #49588A",
+"u= c #4A5A8D",
+"v= c #46528C",
+"w= c #1D266A",
+"x= c #1B2667",
+"y= c #212C6D",
+"z= c #212C6C",
+"A= c #293671",
+"B= c #3F4B89",
+"C= c #41518F",
+"D= c #43538F",
+"E= c #475792",
+"F= c #475791",
+"G= c #495998",
+"H= c #4B5998",
+"I= c #4C5C95",
+"J= c #4C5A93",
+"K= c #4D5D99",
+"L= c #4A568A",
+"M= c #45548F",
+"N= c #1D286B",
+"O= c #1E2968",
+"P= c #202A6D",
+"Q= c #283371",
+"R= c #27336F",
+"S= c #2F3C7B",
+"T= c #323E7D",
+"U= c #334081",
+"V= c #3C4A86",
+"W= c #3F4C89",
+"X= c #425091",
+"Y= c #44528D",
+"Z= c #45548D",
+"`= c #475690",
+" - c #48578F",
+".- c #495588",
+"+- c #4B5993",
+"@- c #4C5A98",
+"#- c #4A568B",
+"$- c #4C5A96",
+"%- c #1C2768",
+"&- c #1B2767",
+"*- c #1B2665",
+"=- c #1F2B6D",
+"-- c #222D6F",
+";- c #232F6E",
+">- c #273373",
+",- c #2E3A7B",
+"'- c #3B4B87",
+")- c #3B4A8A",
+"!- c #3D4B88",
+"~- c #404E8B",
+"{- c #455493",
+"]- c #475795",
+"^- c #485793",
+"/- c #48558B",
+"(- c #4A5992",
+"_- c #485794",
+":- c #4A5694",
+"<- c #1E266B",
+"[- c #1D2668",
+"}- c #1E2869",
+"|- c #1C2867",
+"1- c #1E2A69",
+"2- c #222E6D",
+"3- c #263173",
+"4- c #2D3A77",
+"5- c #3A4A84",
+"6- c #3E4A8C",
+"7- c #3D4987",
+"8- c #3D4C8B",
+"9- c #40508C",
+"0- c #44538F",
+"a- c #485592",
+"b- c #485792",
+"c- c #46568C",
+"d- c #42528C",
+"e- c #1A2665",
+"f- c #1E276B",
+"g- c #222C6F",
+"h- c #263271",
+"i- c #2A3574",
+"j- c #364684",
+"k- c #3C4884",
+"l- c #3B4987",
+"m- c #3D4A87",
+"n- c #3D4A89",
+"o- c #42508C",
+"p- c #44528B",
+"q- c #46548E",
+"r- c #465493",
+"s- c #475593",
+"t- c #475490",
+"u- c #4A5794",
+"v- c #424E8C",
+"w- c #3C477A",
+"x- c #1A2467",
+"y- c #1D2969",
+"z- c #1C2868",
+"A- c #202C6C",
+"B- c #232F6F",
+"C- c #243075",
+"D- c #2F3A7E",
+"E- c #333F7C",
+"F- c #3B4A88",
+"G- c #3F4D88",
+"H- c #44518C",
+"I- c #445490",
+"J- c #485693",
+"K- c #465284",
+"L- c #1B2464",
+"M- c #1C266A",
+"N- c #1E276D",
+"O- c #202A6C",
+"P- c #1F2B6A",
+"Q- c #25316F",
+"R- c #2C367D",
+"S- c #2E3A74",
+"T- c #2F3B7A",
+"U- c #303F7C",
+"V- c #324283",
+"W- c #3B4889",
+"X- c #404F8A",
+"Y- c #44528E",
+"Z- c #475794",
+"`- c #465294",
+" ; c #3A4475",
+".; c #182059",
+"+; c #1A2462",
+"@; c #1D2869",
+"#; c #1F296A",
+"$; c #212A6D",
+"%; c #252F6F",
+"&; c #283275",
+"*; c #2E3A77",
+"=; c #3E4C89",
+"-; c #42528F",
+";; c #43538C",
+">; c #45558C",
+",; c #1B2565",
+"'; c #25306F",
+"); c #283373",
+"!; c #2D3A78",
+"~; c #3C4987",
+"{; c #3E4B88",
+"]; c #3E4C8A",
+"^; c #3E4E89",
+"/; c #3F4E8A",
+"(; c #414E89",
+"_; c #42518D",
+":; c #414F8B",
+"<; c #445190",
+"[; c #42528D",
+"}; c #42518B",
+"|; c #3C467F",
+"1; c #1C2664",
+"2; c #1F2A6B",
+"3; c #242F6F",
+"4; c #3F4F8A",
+"5; c #40508B",
+"6; c #1D2765",
+"7; c #3C4B87",
+"8; c #404F8B",
+"9; c #3D4B87",
+"0; c #3D4C88",
+"a; c #3F4C87",
+" . + @ @ # $ % & * = - ; ",
+" > , ' ) ! ~ { ] ^ / ( % _ : < [ } | 1 1 ",
+" 2 3 4 5 ' ) ! ~ { ] ^ / ( % _ : < [ 6 7 | | 8 1 ",
+" 9 0 0 a 3 4 b ' ) ! ~ { ] c / ( d _ : < [ 6 7 | e f f 8 g 1 ",
+" h h i 0 a 3 j b ' ) ! ~ { ] c / ( d _ : * [ 6 k | e f 8 8 8 l m ",
+" n o p i 0 q a 3 j b ' ) ! r { ] c s t d _ : * [ 6 | | e f 8 8 l l l g 1 ",
+" u o p h i 0 q a 4 5 b ' v ! r { ] # s % d _ w x } 6 | | e f 8 8 l l y z m m ",
+" A u u o p h i 0 a B 4 5 b ' ! ~ r C ^ # D % E _ < x 6 7 | | f 8 8 8 l F G G H I m J ",
+" K u u o o p i 0 q a 3 j b ' ) ! ~ { ] ^ L D M E _ < x 6 k | e f 8 8 l y G G N G H g m J ",
+" n u u u o p h i 0 q a 3 j b ' v ! ~ { ] c / ( d _ : * [ 6 k | e f 8 O P Q G Q Q G Q H g m J ",
+" K u u u o p h i 0 0 a 3 4 5 b R v ~ r S ^ # s % d _ w x T 6 | | e 8 8 G G Q N G Q N G N H m ; J ",
+" A u u U V W X Y Z ` ...+.@.#.$.%.! ~ { C ^ L D % E _ < x 6 k | | f G O Q G G G N G G Q G G H m ; J ",
+" u u u &.*.X =.Z -. ...+.;.>.,.$.'.! r { ^ ).D M E w * < [ 6 k | e O G G Q Q Q Q G Q G N G N N m m ; ",
+" u u o &.W X =.Y ` .!.~.+.@.{.$.%.].^./.(.% E _.* < x 6 :.<.6 k [.Q Q Q Q Q Q Q Q Q Q Q Q Q G G }.|.|.1 ",
+" n o o o *.X Y Z -. .!.+.;.#.#.{.$.1.2.3.(.d 4._.< 5.:.< _.:.6.< 7.8.7.7.7.7.Q 8.8.7.8.7.7.8.7.Q Q - - - 9.0. ",
+" o p p p a.Y Z ` .!.!.+.;.>.,.b.c.^.3.L % d d.w e.f.w w w _.w 7.f.7.7.7.7.7.7.7.7.7.7.8.8.7.8.7.8.g.g.h.- 9. ",
+" h p h h i Z -.` i. .+.+.;.,.,.{.j.{ k.l.m.% n.o.p.q.r.s.p.t.u.7.v.w.x.7.w.w.y.y.y.w.y.y.y.z.A.w.7.z.B.B.g.g.g.9. ",
+" 9 h i i i 0 C.D. .!.+.+.;.>.,.$.E.F.G.H.I.( J.d E K.& L.M.N.O.P.Q.O.R.S.y.y.T.w.y.y.y.y.y.w.T.w.y.y.U.V.W.X.B.B.g.1 ",
+" 0 i 0 0 0 q !.Y.Z.+.;.@.#.{.{.`.F.2. +.+++( J.L.L.@+N.v.#+$+%+&+).*+=+).T.y.-+T.T.;+T.y.;+>+;+y.y.y.V.n.V.V.W.X.,+'+ ",
+" 0 0 q q a a Y.)++.;.@.,.{.$.%.!+~+{++ ]+^+/+(+K._+t :+<+[+}+|+1+2+3+4+5+3+6+T.-+7+8+-+-+8+7+>+8+>+;+9+0+a+n.V.V.W.X. ",
+" 2 a a a a B 3 +.b+;.,.{.,.$.'.c+d+e+f+R.g+h+i+j+k+l+m+n+-+o+S o+p+q+r+s+t+u+v+w+x+y+7+7+y+7+z+-+-+A+5+2+2+9+B+a+a+C+W.9. ",
+" 3 3 3 3 4 4 j j 5 b ' {.%.%.'.'.e+D+E+F+R.G+H+I+J+3.K+L+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+z+z+Z+z+-+`+o+ @ @ @ @.@2+9+B+a+n.W. ",
+" +@4 4 j j 5 5 b b b ' ' ) '.'.c+Z+@@e+#@$@%@2+&@*@=@-@;@>@,@'@S+)@!@~@{@X+]@^@/@(@_@:@S+<@z+<@z+[@p+[@p+p+p+ @.@.@2+B+a+a+'+ ",
+" , 5 b b b b b ' ' R ) v ! '.c+Z+z+}@G+|@1@2@k.3@e+4@;@-@S+5@6@7@8@8@9@0@a@b@c@a@d@e@f@g@h@<@i@T+j@j@h@j@Q+[@p+p+ @.@2+9+B+'+ ",
+" ' ' ' ' ' ' ' ) v v ! ! ~ Z+z+Z+7+|@k@E+l@m@n@3+o@N+p@q@r@s@W+t@u@v@w@w@x@y@z@A@B@C@D@E@F@, t@t@t@t@t@t@, j@j@[@p+ @G@H@2+I@ ",
+" ) ) ) ) ) v ! ! ! ~ ~ r { z+7+8+7+J@K@L@M@e+N@O@o@P@Q@R@^@^@0@e@S@S@T@U@V@y@W@X@Y@Z@`@ #.#+#a@F@F@a@a@a@t@, , j@Q+[@p+@#H@2+ ",
+". ! ! ! ! ! ! ~ ~ ~ r { { C ] 7+>+y.##$#%#m@&#*#=#-#V+;#>#,#'#+#)#y@!#~#C@{#]#^#/#(#_#:#<#[#}#|#1#U@F@F@F@a@a@t@, j@j@[@p+@#2#I@",
+"+ ~ ~ ~ ~ r r r { { S C ] ^ @ T.T.T.>+3#4#6+5#L+6#s@Q@~@7#8#9#0#a#b#c#d#e#f#g#h#i#j#k#l#m#n#[#]#}#}#|#1#U@F@F@a@a@t@, j@o#p+@#p#",
+"@ { { { { { { C ] ] ^ ^ c # L (.D D (.T.q#6+r#s#t#u#s@v#x@8#~#w#b#`@x#y#z#A#B#C#j#n#D#2 E#F#k#G#H#I#J#}#}#|#U@F@F@a@t@, j@o#p+2#",
+"@ ] ] ] ] ] ] ^ ^ c # L / (.D % % t (.y.K#p#L#M#N#O#P#9#y@V@Q#b# #R#S#T#U#[#V#W#X#Y#Z#Z#`# $W#.$G#+$+$I#J#J#}#|#U@F@@$a@, j@o#@#",
+"# ^ ^ c c c # # L / s D t % M d d % :+K@3##$p+$$%$a@8#8#&$Y@I#+$*$=$C#-$;$>$,$'$)$!$~${$]$^$/$($2 _$_$:$+$I#J#J#|#U@F@@$a@t@j@p+",
+"$ / / / / s s D D ( % % M v.E 7.w.<$[$}$|$L#[@o#Q@1$2$3$~#4$5$6$*$7$8$9$0$a$b$c$d${$e$f$g$h$i$j$($k$k$2 2 l$+$I#J#}#U@m$@$a@, o#",
+"% ( ( ( ( t % % M d d E _ _ _ 7.x.y.n$o$n@6+p$z+V+8#q$r$s$t$b#}#u$C#v$w$x$y$y$Z#z$A$B$C$D$E$F$G$/$j$j$($k$2 _$l$I#J#}#U@m$@$H$j@",
+"& % % d d d d E E _ _ _ : w _ d O.$ I$q#7+2#3+J$)@K$D@3$&$L$M$N$I#O$2 $ $P$Q$R$S$T$g$U$V$W$X$R$A$Y$Z$j$j$($k$2 l$+$J#}#U@m$@$, ",
+"* _ _ _ _ _ _ _ _ : w < < * `$ %O..%+%#@@%#%#%Q@$%%%&%K$*%~#=%-%a$O$P$;%>%,%'%)%!%~%{%]%^%/%(%_%R$R$R$Y$Z$:%j$<%2 [%I#J#}#U@m$H$",
+"= : : : : : w < < * x x [ :.6.v.y.y.#@}%-+|%1%2%>#3%>#4%b#5%6%7%8%9%Z#0%g$g$a%b%W$!%c%d%e%f%g%h%i%i%j%R$R$Y$:%<%<%2 -$I#J#k%m$H$",
+"- < < < * * x x x [ T 6 6 :.6.l%m%n%o%5+p%#%q%3%r%s%t%u%v%w%g#x%y%~$z%F$A%)%b%B%C%D%E%F%G%H%I%J%K%K%K%^%j%R$Y$:%<%<%2 -$J#J#U@L%",
+"; [ [ [ [ [ } 6 6 6 6 k T < M%5. %n%N%O%P%|%O+,@,@Q%s$V@R%S%T%f#U%V%0%W%W$X%W$Y%Z%`% &.&+&@&#&$&$&$&J%K%X%i%a%X$:%<%k$[%-$J#k%L%",
+" } 6 6 6 6 6 7 k k | 8.T = %&f.&&. y.0+2@.@*&,@2%2%=&-&w#;&x%>.>&9%,&,&Y$a%'&(%)&!&~&{&]&^&/&(&C%C%C%$&J%K%^%a%_&:%P$2 [%J#k% ",
+" | 7 7 k | | | Q G :.k :&6 6 <&4.[&<$0+#@}&}&|&1&2&-&3&;&4&U%U%>.Z$5&6&7&8&9&0&a&b&c&d&{&e&f&g&h&i&i&C%$&J%K%^%X$j&k&P$[%-$l& ",
+" 1 | | | | | | e e m&n&6 6 T 5.s.`$`$o&p&^ q&r&s&t&=&w#;&u&v&,.@.,&,&h$w&x&Z%y&z&A&B&C&D&E&F&G&H&h&K i&C%$&J%K%j%X$:%P$2 [%I& ",
+" 1 | e e e e f f J&f K&e :.T = < L&4.M&y.[$N&O&,@P&-&Q&*$R&:$S&@.,&T&U&)%V&0&W&X&Y&Z&`& *.*+*@*#*$*%*K &*C%$&**^%X$j&<%2 [%I& ",
+" 8 f f f f 8 8 f Q G = e k = =*5.-*;*L K@>*}&,*-#'*w#_$)*!*>.@.,&Z$~*!%{*K%]*^*/*(*_*:*<*[*@*}*|*1*2*K &*3*J%K%j%_&k&P$4* ",
+" 1 f 8 8 8 8 f f 5*O 8 O f 6*7*L&8*o&h+9*0*a*b*c*8@d*J#e*f*($j$/$g*h*W${*i*j*k*l*l*m*n*o*p*q*r*H&s*t*u*i&&*$&K%^%_&k&P$L% ",
+" 8 8 8 8 8 v*w*8 n&5*8 K&k x*y*z*t y.A*B*C*D*E*>#F*G*_$k$($Z$H*G$g*w&{*I*J*K*L*M*N*O*H&P*Q*R*R*S*T*U*V*W*3*X*^%X$j&P$ ",
+" g 8 l l l w*l 8 Y*w*8 n&Z*`*L& =V..=#@e+*#+=@=W+1$I#:$k$($Z$#=0%h$j%X%$=%=&=*===M*F&}*-=;=>=,=;='=)=!=!=3*X*^%X$j&~= ",
+" 1 l l l l l l 5*w*l 8 {=]== <&^=/=n.(=|%_=:=<=(@1$&$:$k$($Z$[=~$h$w&}=Z%|=A&1=2=3=4=5=6=7=8=[*9=O*)=!=!=3*X*^%X$j&l& ",
+" m l l I l l m g 0=8 8 a=b=c=X.d=e=f=-+-+@=)@t@v#g=+$2 ($j$y$Z#:%h=i=j=D%k=3*l=m=n=o=p=q=r=s=t=h&u=i*v=3*X*^%X$~= ",
+" g I I I I w=F l x=g - y=z=-*:+<+M@A=*#P@q@/@1$T@I#2 ($j$y$B=G$g$C=D=K%E=&=F=G=H=I=J=K=K=L=I=!=)=!=!=3*M=^%j& ",
+" 1 I I I I I m I l N=e O=P=s.o&Q=R=(=K+o@S=T=U=S@I#_$k$j$V=k$W=i$g$X=Y=Z=Z=`= -.-+-@-2*#-$-n V*!=!=i*$&**^%l& ",
+" x=I |.|.I w=%-&-*-8 =---5.;-o&>-L@*&:=,-7@P&a#I#_$k$j$'-)-!-Q$~-C$'&{*{-k=A&]-^-d&/-l*(-_-h&!=:-i*X*^%_& ",
+" N N <-m [-w=I w=}-|-1-2-W.3-[$2+#%4-@=>#9@V@x#U%5-6-b$7-y$8-G$9-X$~%0-~%$&a-b-B&==3*{&{&V*!=!=c-c-d- ",
+" J H G *-e-f-x=|.5*]=6 g---V.h-i-&@P+@=-#P&c@j-U%5->.k-l-m-n-/$0%A%w&o-h%p-{%q-r-A&s-t-W*u-i*i*Z.v-w- ",
+" J ; *-x-F m 0=y-z-A---B-(+C-9+.@|%t#D-E-`.U%,.5-S&8-F-9%!-!-G-i$g*X$D$H-I-I*D=$=$=J-C%(&c-c-K-w- ",
+" J ; L-x=; M-l N-O-P-g-Q-+ 5+|%R-S-T-U-V-j-{.U%U%S&W-F-y$>$!-P$~-X-9-X$o-C$j=K%Y-Z-I*:-`-d- ; ",
+" .;; +;; %-@;#;O-$;--%;$+&;n+K+*;)@a@F@|#J#I#l$2 >$=$F#=;=;=;/$z$~-~-h=b%-;V&K%;;>;c-d-w- ",
+" J ,;1 %-|.}.`*B.X.';p&);n+}&!;;#a@F@U@|#J#I#l$2 ~;l$F#{;];:%^;/;(;_;_;:;j=_;<;[;};|; ",
+" 1 1;%-}.2;g.B.3;p&>-i-}&Q+j@t@a@F@U@}#J#+$[%2 ~;l-F#m-=;c$/;/;4;4;:;5;_;^%_& ",
+" 0.6;#;`*`*B.3;a+>-B* @[@j@, t@@$F@U@}#J#I#-$2 .$V=7;F#m-{;{;c$/;j&8;j&l& ",
+" 9.g.,+W.C+a+B+2+G@p+[@j@, a@@$m$U@}#J#I#-$[%2 9;F#>$0;0;P$P$a;~= ",
+" 1 '+X.W.n.a+9+H@@#p+o#j@, a@@$m$U@}#J#J#-$[%[%2 2 P$P$P$~=l& ",
+" 9.W.a+B+2+H@@#p+o#j@t@a@@$m$U@k%J#J#J#-$[%[%4*L% ",
+" '+'+I@2+2#@#p+o#j@, H$@$m$m$U@k%k%l&I&I& ",
+" I@p#2#@#p+o#j@, H$H$L%L% "};
diff --git a/arts/builder/pics/Synth_ENVELOPE_ADSR.xpm b/arts/builder/pics/Synth_ENVELOPE_ADSR.xpm
new file mode 100644
index 00000000..4408f29d
--- /dev/null
+++ b/arts/builder/pics/Synth_ENVELOPE_ADSR.xpm
@@ -0,0 +1,318 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 247 2",
+/* colors */
+" c #54E523",
+" . c #364281",
+" X c #24306C",
+" o c #313E7C",
+" O c #303C7B",
+" + c #1E2A66",
+" @ c #2E3A79",
+" # c #505AA1",
+" $ c #1C2864",
+" % c #2C3877",
+" & c #4D589E",
+" * c #2A3675",
+" = c #293474",
+" - c #283473",
+" ; c #253070",
+" : c #334081",
+" > c #41607E",
+" , c #2E3A7C",
+" < c #1E2869",
+" 1 c #2B3679",
+" 2 c #2A3678",
+" 3 c #7C84AE",
+" 4 c #39448A",
+" 5 c #263074",
+" 6 c #232E71",
+" 7 c #303C81",
+" 8 c #202A6E",
+" 9 c #1E286C",
+" 0 c #414F8B",
+" q c #1D286B",
+" w c #2E387F",
+" e c #273278",
+" r c #1A235E",
+" t c #295252",
+" y c #384582",
+" u c #445391",
+" i c #313F7B",
+" p c #3E4D8B",
+" a c #3D4B8A",
+" s c #2D3977",
+" d c #3B4988",
+" f c #8C95BD",
+" g c #384585",
+" h c #55689E",
+" j c #858DB6",
+" k c #303D7D",
+" l c #1F2B69",
+" z c #2F3B7C",
+" x c #2B3778",
+" c c #45DA16",
+" v c #368640",
+" b c #295A44",
+" n c #333F83",
+" m c #313D81",
+" M c #43528C",
+" N c #1E296B",
+" B c #1D276A",
+" V c #3C9E35",
+" C c #2C3E72",
+" Z c #293379",
+" A c #2D6341",
+" S c #283378",
+" D c #263176",
+" F c #3A586F",
+" G c #252F75",
+" H c #242F74",
+" J c #41D015",
+" K c #232D73",
+" L c #3C4A88",
+" P c #4A5899",
+" I c #374483",
+" U c #354281",
+" Y c #33407F",
+" T c #409349",
+" R c #2E3A7A",
+" E c #1C2665",
+" W c #1B2464",
+" Q c #364285",
+" ! c #232E6F",
+" ~ c #323E81",
+" ^ c #434E95",
+" / c #212A6D",
+" ( c #303C7F",
+" ) c #3CBE16",
+" _ c #3E4A90",
+" ` c #2C387B",
+" ' c #1C2668",
+" ] c #1B2667",
+" [ c #293478",
+" { c #273276",
+" } c #394981",
+" | c #253074",
+". c #384580",
+".. c #263E61",
+".X c #37724D",
+".o c #37417F",
+".O c #222C71",
+".+ c #212C70",
+".@ c #202A6F",
+".# c #1F2A6E",
+".$ c #42518D",
+".% c #2E3A80",
+".& c #1E286D",
+".* c #1D286C",
+".= c #3E4D89",
+".- c #4E5D9C",
+".; c #3D4B88",
+".: c #3B4986",
+".> c #3A4785",
+"., c #384583",
+".< c #465594",
+".1 c #445192",
+".2 c #425190",
+".3 c #323F7D",
+".4 c #323D7D",
+".5 c #212B69",
+".6 c #2F3B7A",
+".7 c #4CD125",
+".8 c #3A4788",
+".9 c #4C5893",
+".0 c #273372",
+".q c None",
+".w c #263171",
+".e c #253666",
+".r c #222D6D",
+".t c #6E78A7",
+".y c #414D92",
+".u c #2F3B7D",
+".i c #1F296A",
+".p c #3F4B90",
+".a c #405287",
+".s c #2B3779",
+".d c #3B458C",
+".f c #283376",
+".g c #273375",
+".h c #374388",
+".j c #394680",
+".k c #364187",
+".l c #242F72",
+".z c #343F85",
+".x c #222B70",
+".c c #34427B",
+".v c #6670B6",
+".b c #1E296C",
+".n c #41508B",
+".m c #1D276B",
+".M c #404E8A",
+".N c #326747",
+".B c #3CAE22",
+".V c #3E4C88",
+".C c #2A357B",
+".Z c #3C4A86",
+".A c #44D219",
+".S c #465693",
+".D c #455492",
+".F c #33407D",
+".G c #42508F",
+".H c #404E8D",
+".J c #2B3A75",
+".K c #3C4889",
+".L c #2B3675",
+".P c #3A4887",
+".I c #384685",
+".U c #495699",
+".Y c #354282",
+".T c #25306F",
+".R c #36625B",
+".E c #43A739",
+".W c #5560A8",
+".Q c #344777",
+".! c #3DC215",
+".~ c #2D387A",
+".^ c #3B923B",
+"./ c #518F5E",
+".( c #384288",
+".) c #385274",
+"._ c #47529A",
+".` c #73A386",
+".' c #253072",
+".] c #475790",
+".[ c #232E70",
+".{ c #171F57",
+".} c #1F2A6C",
+".| c #6C75A7",
+"X c #424F8B",
+"X. c #2D387D",
+"XX c #1C2669",
+"Xo c #2C367C",
+"XO c #2B367B",
+"X+ c #283478",
+"X@ c #253075",
+"X# c #485794",
+"X$ c #45C023",
+"X% c #242E74",
+"X& c #232E73",
+"X* c #212C71",
+"X= c #34417D",
+"X- c #577192",
+"X; c #202A70",
+"X: c #1F2A6F",
+"X> c #3EB81C",
+"X, c #273370",
+"X< c #364582",
+"X1 c #364382",
+"X2 c #41CB18",
+"X3 c #5763A9",
+"X4 c #344180",
+"X5 c #303D7C",
+"X6 c #213260",
+"X7 c #2D3979",
+"X8 c #3D498C",
+"X9 c #3D478C",
+"X0 c #4D6295",
+"Xq c #2B3777",
+"Xw c #2A4962",
+"Xe c #293575",
+"Xr c #263172",
+"Xt c #42C71C",
+"Xy c #344183",
+"Xu c #737DA3",
+"Xi c #44548C",
+"Xp c #212B6D",
+"Xa c #4FDC22",
+"Xs c #1F296B",
+"Xd c #1E296A",
+"Xf c #2D397C",
+"Xg c #1D2769",
+"Xh c #1B2567",
+"Xj c #293578",
+"Xk c #4B5C96",
+"Xl c #4A5A95",
+"Xz c #273176",
+"Xx c #263175",
+"Xc c #465691",
+"Xv c #36427E",
+"Xb c #222D71",
+"Xn c #455490",
+"Xm c #212B70",
+"XM c #44528F",
+"XN c #33407B",
+"XB c #1F296E",
+"XV c #1E296D",
+"XC c #415782",
+"XZ c #2C377E",
+"XA c #4F5E9D",
+"XS c #5BF220",
+"XD c #3A8D3F",
+/* pixels */
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.qXr { [ Z e D HX&.O 8 N '.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.L.4.(.k n.%XZ.C Z eX@ H K.OX*X;X;XB W r.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.K ^.pX9 4.k n.%XZ.C Z eX@ H K.OX*X;.@X:XBXB 9 r.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.o # &._ ^.p.d 4.z m.%XZ.C S eX@X% K.OX*X;.@X:XBXV.&.& 9XX r.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.WX3 # &._ ^.p.d.(.z m.%XZ.C SXzX@X% K.OXmX;.@.#XBXV.& 9 9.*.m '.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q P.vX3.W # &._ ^ _.d.h.z m.%XZ.C S DX@X% K.OXmX;.@XBXBXV.& 9 9 q.m.mXX r.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.v.v.vX3.W # &._ ^ _.d.k.z 7 wXo.C e D GX% K.OXmX;.@XBXBXV.& 9 9.m.m.m B BXh.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.qX .v.v.vX3X3.W #._ ^.y _ 4.k n 7 wXo Z e D GX&XbX*Xm.@X:XBXB.& 9 9.*.m.m B B B B '.{.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.9.v.v.v.vX3.W # &._ ^.p.d 4.k ~.%X..C Z e D HX&XbX*Xm.@.#XBXV.& 9 9 q.m.m B B BXgXX '.{.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.9.v.v.v.vX3X3.W #.U._ ^ _.d.h.z m.%XZ.C SXzX@X% K.OXmX;.@.#XBXV.& 9 9 q.m.m B B BXgXXXX '.{.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.9.v.v.v.v.vX3.W # &._ ^.pX9 4.k n 7 wXo.C e D GX% K.OXm.@.@XBXBXV 9 9 q.m.m B B BXgXgXXXX ' E.{.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.qX .v.v.v.v.vX3.W # #.U._ ^ _.d.(.z ~.%X.Xo Z e D GX&XbX*Xm.@.#XBXB.& 9 9 9 9.m.m B B BXgXgXX ' ' E.{.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.v.v.v.v.vX3X3.W # &._ ^.p.d Q.z n 7 wXZ.C SXzX@ H K.OX*X;.@.#XBXBXVXV 9.b.b.b 9 9 9 9 < BXgXg ' ' E.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.v.v.v f fX3X3.W # &._ ^.pX8.8.o ~ m.%X.Xo Z e D GX& K.OXmX;.@.@ 8 8 8 8 8 8 8 8 8 8.}.}.bXs 9 < <XgXg W.q.q.q.q.q.q",
+".q.q.q.q.q P.v.v.v f f.W.W # &._ ^ ^X8.;.).R.Q z.~XZ.C Z { D HX& K.O.+.+.+.+.+.+.+.+.+.+.x.x.+XpXpXpXpXp.}.}Xs.iXd < r.q.q.q.q.q",
+".q.q.q.q.q.v.vX3X3X3.W # # &._._ ^.p dXC./.E.R C xXo Z e D GX%X& K KXbXbXbXbXb 6 6 6 6 6 6 6.[.[.[ ! !.r.rXpXpXp.}.} <.q.q.q.q.q",
+".q.q.q.q.WX3X3X3.W.W # # &._ ^ ^.pX9.>XC./.E.R C = Z ZXz D HX%X&X&X& H H H H H H H H.'.'.'.'.'.'.l.l.l.[.[ !.r.rXpXp.} <.q.q.q.q",
+".q.q.q.oX3.W.WX8 # f f.U._ ^ ^.pX9.d yXC./.7.X..X, SXz DX@X@ H H | | | | | 5 5 5 5 5 5 5XxXxXxXrXrXrXr.' ; ;.[ ! !.r.rXp $.q.q.q",
+".q.q.q # # # #.8 & f f._ ^.y _X9.d.( } F./.7 T.N...0 5Xz D DXxXxXxXxXx { { { {.f.f.f.f.f.f.fXe.g.g -.g.g.0XrXr ; ; ! !.r l.q.q.q",
+".q.q.q & & & &.(._ f j ^.p _.d 4.h Q.) F T .7.E bX,.w { { { { { { { S SX+ [ [XjXjXj 2 2 2 2XjXjXeXeXeXe - -.0.0Xr.w ; ! !.q.q.q",
+".q.q.K._._._._ n ^ j j _X9.d 4.kXy.j.R T.EXSXaX$.N.e.T { S S S SX+ [Xj 2 2 2 2 1.s.s.s.s.s.s.s x x xXq 2XeXeXe - -.0.w.w.T +.q.q",
+".q.q ^ ^ ^ ^ ^.y.p _X9.d 4.(.k.z.3.)./.7 XS .7 AX6 X { { [ [Xj 2 2 2.s.s.~ ` ` `XfXfXfXfXf.~.~.~X7.~ % xXqXqXeXe = -.0.w.T.q.q",
+".q.L.p.p.p _ _ _.d.d 4.(.k.z n m o.)./ XSXSXS V b...0.g 2 2.CXO.s ` `XfXfXf , , , z z z z z z R R R.~X7.~ % %.L *Xe -.0X,.5.q",
+".q.4X9.d.d.d.d.~ 4 3 3.z.z ~ 7.% @.) T XSXSXSXS.7.B bX, -XO.s ` ` `XfXf ,.u.u.u ( ( ( k k k k k kX5 z z z R @X7 % %.LXe = -.5.q",
+".q.( 4 4.(.h.k 1.k 3 3 ~ 7 7 wX. C.) T XSXSXSXS.7X$ A.e -XO `XfXf ,.u.u.u ( ( ( ~ ~ ~ ~ ~ ~ ~ ~ ~.3.3.4 kX5 z.6 @X7 %Xq.LXeX,.q",
+".q.k.k.z.z.z.z.f ~ 3 3.% wX.Xo `.QXw T Xa.7 A.eX,.s ` , ,.u ( ( ( ~ ~ ~ : : : : : : : : : : Y Y.3 o oX5 z R @X7 %.LXe.q",
+"Xr n n m m m 7.g.% 3 3X.XZXo 2 C.R v.E X$.^.^.^.BXa.^ b.. %X7.u.u ( m ~ ~ : : :XyXy.Y.Y.Y.Y.Y.Y.Y UX4X4 : Y.3.3 o O.6 @X7 %.L -",
+" {.%.%.%.%.% w wX.XZXoXo.C Z - C.X.7Xa XDXwXwXw.^XaX$.B b C s ( m ~ ~ : :Xy.Y Q Q Q Q I I I I IX1X1X1.Y UX4X4 Y.3 o o O.6 @ % *",
+" [XZXZXZXZXZXoXo.C.C.C Z S eX, C TXaXa TXwXwXw TXaXtX> A C C @.6 O i iXN.3XNX=X=XvXvXvXvXvX1 I g g., IX1X1 UX4 Y.3.3 o O.6 @.L",
+" Z.C.C.C.C.C.C.[ ZXuXu eXz DX,Xw T TXwXw.Q T.7XtX2 A.. C C C C C.Q.Q.Q.Q.Q.Q.Q.Q.Q.Q.Q. .I.I.>.I.I.,., IX1 UX4 Y.3 o O.6 %",
+" e Z Z S S S e.x eXuXu DX@ H.eXwXD .7X$.X C C C.R v.B.A V A A A A A.N.N.N.N.N.N.N.N.N.N.N.N F }.> d.P.8.>.I.,.,X1 .X4 Y.3 o O @",
+" D e e eXz D DXp DXuXu G H ;..XwXDXaX$.B bX, CX7.QXwXD c.AX2.!.!.!.!.!.! ) ) ) ) ) ) ) )X>.B vXC.Z L L d d.P.>.I., I .X4 Y.3 o.6",
+" HX@X@X@X@X@ G / HXuXuX&.[.e.R v.EXa.^ b.. - * ` CXwXD.A.A.A J J JX2X2X2X2X2X2X2X2X2X2X2XtXt T >XC a a a L d.P.>.I., I .Xv Y.3 O",
+"X& H HX%X%X%X%X&X& K KXb X.. v.7.7.A AX6 XXj 2 `.J.Q vX$.A c c c c c c c c c c c c c c c c.AXD F >.M p p a a L d.P.>., I .X4X= o",
+".O K K K K K KXbXb.O.OX*.r.. vXa.AXt A.eX,Xj `Xf @ i.R T T T T T T T T T T T T T T T TXD.B.A.E T.RXC.M.H p p a.; d.:.>., I .X= o",
+" 8.O.O.O.O.O.OXdX*.t.tXm l.. vXa.AXt A.eX,.s `Xf , k.Q.).) F F F F > > > > > > > > > > F T.AXtX$ T >.a.G.H.H p.=.; d.>.> yX1Xv.3",
+" NX*X*X*XmXmXm <Xm.t.t 8.eXwXD cXtX> b.eX,.sXf ,.u (.3.c.c.c. } } } }.Z.Z.a.a.a.a.aXC >.XX>XtXt T >XC.$.$.$.H p.=.; d.>., y .X=",
+" 'X;X;X;X;X;X;Xg.@.t.t.}.. t V cX>.B b X -.~Xf.u ( ~ :Xy Q g g.8.K aX8 p.H.G.G.1 u u.n.a.R.BX>.A T > >Xn.2XM.$ 0 p.=.;.:.> y. X=",
+".qX;.@.@.@.@.@Xg.#.t.t.e.R.^.B.A.^ b..X,Xe `Xf.u ( ~ :.Y Q g.8.8.K a p.H.H.G.1 u.D.<XM M F.N.^X2.E T./.]Xi u.$.$ 0.M.V.Z.>.,. .q",
+".qXBX:X:.#XBXBXBXBXB l.. vXtXtX2 AX6 XXe 2 ` ,.u ( ~ : Q Q g.8 dX8 p.H.H.G.1 u.D.<.<.<X#.a.).N )XtX$ T >Xi.D u.$X .M.=.;.Z.>. .q",
+".q WXBXBXBXBXBXBXVXV l.. v.AX2.! AX6 XX+.s ` , ( ~ :Xy Q g.I.8.K a p.H.G.2 u.D.<.<X#XlXlXiXC.N.BX>Xt T >XC.D.DXM.$ 0.M.V.Z.>XN.q",
+".q rXBXVXVXVXV '.&.tXu..XD c J.! b.e.TXj.sXf , ( ~ :Xy Q g.8.8 aX8.H.H.G u u.<.<X#XlXlXk.]Xi.R.BX>.A T > >XcXnXnXMX .M.=.;.:.c.q",
+".q.q 9.&.&.&.& ' 9.|Xu.. v c J.! b.e.T 2.sXf z ( ~ :.Y Q g.8.K a p.H.G.2 u.D.<X#XlXlXk.-Xl.9 F.N.^.!.E T./.]Xn.DXM.$ 0.=.;.>.q.q",
+".q.q r.& 9 9 9 ' 9.tXu.. v c J.! b.e.T 2.sXf z k ~ :.Y I g.8 d a p.H.G.2 u.<.<X#XlXk.-.-.-.-XiXC.X )XtX$./ >XiXcXM.$ 0.=.V.c.q.q",
+".q.q.q 9 9 9 9 ' +Xu./ v.B c.!.B b.e.T 2.sXf z k ~ :.Y I g.8 d a p.H.G u.D.<X#Xl PXk.-.-XAXA.9XC.X.BX>Xt T >XCXcXnXMX .M.V.q.q.q",
+".q.q.qXX.* q.m.m +.. vXt c c.!.B b.eX, 2.sXf z k ~ :.Y I.I.8 d a p.H.G u.D.<X#Xl PXk.-XAXAXAX0.].R VX>X2 T > >.]XnXMX .M.Z.q.q.q",
+".q.q.q r.m.m.m.m +.. v J J J.^ bX6 XX,Xj.s.~ z k ~ :.Y I g.8 d a p.H.GXM.D.<X#Xl P.-.-XAXA hXAX0 F.X.^.!.E T./.]XiXMX .M.j.q.q.q",
+".q.q.q.q '.m.m E $X-./ c J.! AX6.5.w.gXj x.~ z k ~ :.Y I g.8 d a p.H.GXM.D.<X#Xl PXk.-XAXA h h h.]XC.X )X>X$ T >XiXMX .V.q.q.q.q",
+".q.q.q.q.qXX B E $X-./ )X>.B bX6.5.'.gXe x.~ R k ~ :.YX1 g.> d a p.H.G.2 u.<X#XlXlXk.-XAXAXA h hXlXC.X.B.B.B T >.a M.M.q.q.q.q.q",
+".q.q.q.q.q r B B $X-./X$.B.B bX-.|XuXuXe x 3 3 3 3 : U 3 3 j j L p j j j j.S.< f f f f.-XA f f f j.].R.E.EX$.` >.a M }.q.q.q.q.q",
+".q.q.q.q.q.qXh B E.|X-././ bX6.|.tXuXuXeXq 3 3 3 3 YX4 3 3 j j L a j j j j.D.S f f f f.-.- f f f f.9 F./././.`XC.a.M.q.q.q.q.q.q",
+".q.q.q.q.q.q.q 'Xh ] $ r r $ +Xp !.'.gXe 2 %.~ z.4 YX4.Y I.I.8 d a p.H.GXM u.S.<X#XlXlXk.-.-.-.-XkXk.].aXCXC.aXi.n.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.{ 'XhXh r r E.i <.i.5.r -Xe.T.TX,.0.3 :.L % % @ d L O o.3.FXM.DXv .X< yXlXk.>.>.> }Xl.].c.c M MX .j.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.{ ' ' 'Xg <.}Xp ! ;Xr -XeXq.~ RX5 o YX4X1.,.I.P d a p.H.$XM u.D.S.SX#X#XlXlXlXlXlXlX#X#XcXn M.Q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.{ E ' ' <XsXp.r.[Xr.0XeXq % @ z o.3X4 U I.,.>.P L a p.H.$.$ u.DXc.SX#X#X#X#X#X#X#.SXcXn M.Q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.{ E 'Xg.iXp.r ! ;.0 -Xe %X7.6X5.3 YX4X1.,.I.> d.;.= p 0.$.$XMXn.DXc.S.S.S.SXcXcXnXn M.Q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.{ EXgXd.}Xp ! ;Xr -Xe.L % @ z o.3 Y UX1.,.I.P d.;.= p 0X .$XMXMXMXnXnXnXnXnXMXM.n.j.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q W <.}Xp.r !.w.0 = * %X7 R O o.3X4 . I.,.>.: d.;.=.M.M 0X .$.$XMXMXMXM M M.M.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q r <.}.r ! ;.w -Xe.L % @.6 o.3 YX4 . I.,.>.> d.;.V.=.M.M 0 0X X X X .M }.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q <Xp.r !.w.0 -XeXqX7 @ O o.3 YX4 . I.,.>.>.:.Z.;.V.=.=.=.M.M.M.V.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q $ l !.T.w.0 =.L %X7.6 O o.3 YXv . I y.,.>.>.Z.Z.;.;.V.V.Z.j.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q +.TX, -Xe.L % @.6 O o.3 YX4 .X1 y y.,.>.>.:.>.c.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.5.5X,Xe.L % @.6 O o.3X=X=Xv .. . . XN.c.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q",
+".q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q - *.L % @.6 O o o.3X=X=.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q.q"
+};
diff --git a/arts/builder/pics/Synth_FILEPLAY.xpm b/arts/builder/pics/Synth_FILEPLAY.xpm
new file mode 100644
index 00000000..76730eb0
--- /dev/null
+++ b/arts/builder/pics/Synth_FILEPLAY.xpm
@@ -0,0 +1,312 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 241 2",
+/* colors */
+" c #394684",
+" . c #FEFE82",
+" X c #FCF8EA",
+" o c #354280",
+" O c #664E4D",
+" + c #3C3352",
+" @ c #303C7B",
+" # c #2F3C7A",
+" $ c #2E3A79",
+" % c #282A5C",
+" & c #484C82",
+" * c #FFFFFA",
+" = c #2C3877",
+" - c #4D589E",
+" ; c #2A3675",
+" : c #FCFBF7",
+" > c #975F27",
+" , c #FFFEF0",
+" < c #384486",
+" 1 c #697095",
+" 2 c #222C6D",
+" 3 c #212C6C",
+" 4 c #303C7E",
+" 5 c #5A6390",
+" 6 c #FFE8B1",
+" 7 c #1C2667",
+" 8 c #EB9616",
+" 9 c #293477",
+" 0 c #FFFBE9",
+" q c #354086",
+" w c #475591",
+" e c #FEA50E",
+" r c #5363A0",
+" t c #1F2A6D",
+" y c #42518C",
+" u c #2F3A80",
+" i c #1E286C",
+" p c #F5DC68",
+" a c #50619D",
+" s c #2D387E",
+" d c #FFCD68",
+" f c #2B367C",
+" g c #1F2763",
+" h c #FFFEF6",
+" j c #283279",
+" k c #FEF2CA",
+" l c #FCBF3A",
+" z c #1A235E",
+" x c #384582",
+" c c #4C588F",
+" v c #232E74",
+" b c #DFE0E7",
+" n c #333F7D",
+" m c #F7E563",
+" M c #626DB5",
+" N c #3E4D8B",
+" B c #5C67AF",
+" V c #2A3574",
+" C c #FFF9C4",
+" Z c #273171",
+" A c #FFE799",
+" S c #354182",
+" D c #545FA7",
+" F c #FEDE8E",
+" G c #414E87",
+" H c #1D2767",
+" J c #3A458A",
+" K c #3A4680",
+" L c #323D82",
+" P c #E7CE8B",
+" I c #212B6E",
+" U c #1D276A",
+" Y c #FB9E0A",
+" T c #2C377C",
+" R c #353971",
+" E c #4C5C98",
+" W c #293379",
+" Q c #495895",
+" ! c #475693",
+" ~ c #232D73",
+" ^ c #222D72",
+" / c #FFA811",
+" ( c #455491",
+" ) c #212B71",
+" _ c #202B70",
+" ` c #43528F",
+" ' c #323E7B",
+" ] c #FEC548",
+" [ c #1D2663",
+" { c #2C3875",
+" } c #3A4886",
+" | c #FEFDB8",
+". c #374483",
+".. c #202A69",
+".X c #2F3A7B",
+".o c #1B2464",
+".O c #FDAD1F",
+".+ c #384287",
+".@ c #263072",
+".# c #FFFDE7",
+".$ c #253071",
+".% c #434E95",
+".& c #1E286A",
+".* c #9A8570",
+".= c #1C2668",
+".- c #4E5D99",
+".; c #485793",
+".: c #FCF487",
+".> c #202A6F",
+"., c #1F2A6E",
+".< c #C3822B",
+".1 c #1E286D",
+".2 c #1D286C",
+".3 c #2E3976",
+".4 c #3B4986",
+".5 c #FEF461",
+".6 c #FFCD55",
+".7 c #DC8715",
+".8 c #323F7D",
+".9 c #313D7C",
+".0 c #D89632",
+".q c #FEFD6E",
+".w c #FFFEFA",
+".e c #283373",
+".r c #273372",
+".t c None",
+".y c #39447D",
+".u c #FED678",
+".i c #242F6F",
+".p c #47548E",
+".a c #333F81",
+".s c #232D6E",
+".d c #414D92",
+".f c #FFD16F",
+".g c #1F296A",
+".h c #1E2769",
+".j c #2D397B",
+".k c #3E4A85",
+".l c #495893",
+".z c #563D40",
+".x c #242F72",
+".c c #61689A",
+".v c #232D71",
+".b c #FEB92F",
+".n c #212B6F",
+".m c #303B81",
+".M c #42508C",
+".N c #2E397F",
+".B c #1D276B",
+".V c #3E4C88",
+".C c #2A357B",
+".Z c #3D4A87",
+".A c #2C3673",
+".S c #263177",
+".D c #242F75",
+".F c #374481",
+".G c #787EA3",
+".H c #6872BB",
+".J c #B26E23",
+".K c #FFEFB7",
+".L c #232C6A",
+".P c #313C7B",
+".I c #FEFAD7",
+".U c #333973",
+".Y c #F69809",
+".T c #384685",
+".R c #564C67",
+".E c #5964AC",
+".W c #FFCC43",
+".Q c #404A90",
+".! c #FFFFFC",
+".~ c #FEB321",
+".^ c #3C468C",
+"./ c #D0B16E",
+".( c #283475",
+".) c #3B4781",
+"._ c #263273",
+".` c #2B336E",
+".' c #171F57",
+".] c #333E83",
+".[ c #45538E",
+".{ c #1E286B",
+".} c #1D286A",
+".| c #FFFFFF",
+"X c #1C2669",
+"X. c #4F5F9B",
+"XX c #4C5B98",
+"Xo c #3C4985",
+"XO c #C2791E",
+"X+ c #273277",
+"X@ c #483B52",
+"X# c #263076",
+"X$ c #253075",
+"X% c #465592",
+"X& c #7C5339",
+"X* c #222C72",
+"X= c #F3F3F3",
+"X- c #34417D",
+"X; c #343F7D",
+"X: c #202A70",
+"X> c #42518E",
+"X, c #404F8C",
+"X< c #3C4988",
+"X1 c #C8C7C2",
+"X2 c #364382",
+"X3 c #9E6D39",
+"X4 c #5761A9",
+"X5 c #252F6E",
+"X6 c #344180",
+"X7 c #3E4B8D",
+"X8 c #3C3C6A",
+"X9 c #2B3777",
+"X0 c #4A559C",
+"Xq c #FFD64F",
+"Xw c #475399",
+"Xe c #A8A9B6",
+"Xr c #FFDE66",
+"Xt c #FFFF73",
+"Xy c #1F296B",
+"Xu c #FDA20B",
+"Xi c #3E4990",
+"Xp c #1D2769",
+"Xa c #3F4C87",
+"Xs c #525F93",
+"Xd c #4B5A96",
+"Xf c #38438A",
+"Xg c #4A5A95",
+"Xh c #364188",
+"Xj c #FFE869",
+"Xk c #475692",
+"Xl c #44528F",
+"Xz c #34407C",
+"Xx c #292F64",
+"Xc c #FDB52F",
+"Xv c #43528E",
+"Xb c #1F296E",
+"Xn c #1E296D",
+"Xm c #999593",
+"XM c #404E8B",
+"XN c #2A357C",
+"XB c #7B6865",
+/* pixels */
+".t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.@X+ 9 W j.S.D v ).>.{ H.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.A.PXf q.] u s f W.SX$.D ~X* ) _X:Xb.o z.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.tX<.%.d.^Xf q.] u s f W.SX$.D ~X* ) _.>.>XbXb.{ z.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t o - -Xw.%.Q.^Xf q L u sXN j.SX$ v ~X* ) _.>.>XbXn.1.1 iX z.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.tX4X4 D -Xw.%.Q.^Xf q L u s.C j.SX$ v ~X* ) _.>.,XbXn.1 i i.2.B.=.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.t.t.t.tXX M BX4 D -Xw.%Xi.^Xh q L.N T.C j.SX$ v ~X* ) _.>XbXbXn.1 i i.B.B.BX z.t.t.t.t.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.t.t.t.H M B.E D -X0Xw.dXi JXh.].m.N f.C j.SX$ v ~X* )X:.>XbXbXn.1 i i.B.B.B U U 7.t.t.t.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.t.M.H.H M BX4 D -X0.%.dXi JXh.].m.N f W jX#X$ ~ ^ ) ).>.>XbXb.1 i i.2.B.B U U U U.=.'.t.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t c.H.H M B.E D D -Xw.%.Q.^Xf q L u s f WX+X#.D ~ ^ ) ).>.,XbXn.1 i i.B.B.B U U UXpX 7.'.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.tXs.H.H.H M BX4 D -X0Xw.%Xi J.+.] L u T.C j.SX$ v ~X* ) _.>.,XbXn.1 i i.B.B.B U U UXpX X 7.'.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t c.H.H.H M B.E D D -Xw.%.Q.^ J. .].m.N f.C j.SX$ v ~X* ).>.>XbXbXn i i.B.B.B U U UXpXpX X .= 7.'.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.M.H.H.H M B.EX4 D -X0XwX7.).RXBXBXBXBXB &.yXz.U.3.A V Z.i.s I.>Xb.1 i i i.{.B.B U U UXpXpX .=.= 7.'.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.H.H.H M B BX4 D -X0Xw.%Xo.y O.<.<.<.*XmXm.G.G.c 5Xs.p.k.y.P V.@.s IXn i i i i.{.{.{.{.& UXpXp.=.= 7.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.H.H M M B.EX4 D - -Xw.%.d.yX@ O.J.<.<./X1X1X1X1XeXeXeXeXe.G.G.G.G 1 1.c.c & R.`XxXx %XxXx...hXp.&XpXp.o.t.t.t.t.t.t",
+".t.t.t.t.tXX M M B B.EX4 D - -X0.%.dXiX8 OX&X3.<.0./.I X :X=X=X=X=X=X= b b bX1X1X1XeXeXe.G 1.R.RX@X@X@Xx...gXy.g.&.& z.t.t.t.t.t",
+".t.t.t.t.t M B B.EX4 D D - -X0Xw.%Xi JX@X& >.7.0.0 P 0 ,.! : : : : :X=X=X=X= b b b b bX1X1Xm.*X3X&X&X&X@.L.. I 3XyXy.h.t.t.t.t.t",
+".t.t.t.tX4 B.EX4 D D D -X0Xw.%.%.Q.^ <X@.JXO.Y.O l F h.w.|.|.|.|.|.|.|.|.|.|.|.|.|.|.| h , FXc.0XOXOXO.zXx.L.s.s 3 3 3.h.t.t.t.t",
+".t.t.t oX4X4 D D D - -X0Xw.%.%.Q.^.+X;.zXO.7.YXc d 6.w.!.|.|.|.|.|.|.|.|.|.|.|.|.|.|.| ,.# P.0.<.J.J.J.zXx.L.i.i.s.s 2 3 [.t.t.t",
+".t.t.t - D D - - -X0XwXw.%.dXi.^ JX; RX& 8.Y Y ] F k.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.| 0.I.f 8.<X3X3.JX@X5.i.@.$.i.i.s.s...t.t.t",
+".t.t.t - - -X0X0XwXw.%.%.dXi.^ JXh RX@X&.Y.YXu.6 6.I.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.I.K d 8.7.<.J > +.r.r.e.r.@.$.$.i.s.t.t.t",
+".t.tX<XwXwXwXw.%.%.%.dXi.^.^XfXh.]X8.z > Y YXu d k 0.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.| k 6.6 e Y.Y.JX& +.( V.(.(.e.r Z Z.i g.t.t",
+".t.t.%.%.%.%.d.d.QXi.^.^ JXfXh.].m +X&.J Y e.O.u.# ,.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.! * k F ] e Y.Y >.zXxX9X9X9 ; V V.e.r ZX5.t.t",
+".t.A.d.Q.QXiXiXi.^.^ JXfXh q.].m.NX@ >XO Y.O.b F h.w.|.|.|.|.|.|.|.|.|.|.|.|.|.|.| * h 6.f l / e YX&X@.` $ = = =X9 ; V.e.e Z...t",
+".t.P.^.^.^.^ J JXfXhXh q.] L.m.j.A.zXO.7 YXc.6 6 h.w.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.w h A.6.b / e 8X&X8.`.X $ $ $ = =X9 V V.e.L.t",
+".tXfXfXfXfXhXhXh q q.] L.m.m.N V.`.z.7.Y Y l.u.K.!.!.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.w , A ].b / 8.7 O R.U.9 @.X # $ = =X9 ; V.r.t",
+".t q q q q q.].] L L.m u.N s T.` +X&.Y.YXu.6 A k.!.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.| ,.# F l.~.O 8.< O.U.P.8.8.9 @.X $ $ = = ; V.t",
+".@.].] L L L.m.m u u.N s T f.CXxX@ > Y Y e d k.#.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.| 0.I.u.b.~.~.0.<.RXz n.a.a.8.8.9 @ # $ = = ;.e",
+"X+ u u u u.N.N.N s T f f.C j j +X&.J Y e.O.u.I 0.!.!.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.# C.u.b.~.~.<X3.R oX6 oX6X6X6.8.8.P # $ $ = V",
+" 9 s s s s T f f f.C.C W j.SX$ + >XOXu /Xc F.# , *.!.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.I 6.f.b.b.~.<XB.R. . X2X2 oX6X6 n.8.9 # $ $ {",
+" W f fXN.C.C.C W W j jX+.S.$.s.z.J.7Xu /.O.6 A 6.K k k.I.# 0 , h.w.w.!.!.|.|.|.!.! k AXr.b.bXcX3 OX8.T.T.T. . X2 oX6 n.8 ' # $ =",
+" j W W j j j j jX+.S.SX#X$.sXx.z.7.YXu e /.b ].6.u F A.K C.I.# 0 h h h.!.|.|.|.! *.K.:Xq.b.b.bX3.R.y } } }.T.T. X2 oX6 n.8.9 # $",
+".S.S.S.S.S.S.SX#X#X$X$X$.D.L %X& 8.YXu e /.~ l l ].6 d.f.u F F A A 6.K C k.I.#.#.# 6XjXq l l lXB.R.yX<X<.4 }.T x.F o o n.8.P $",
+".DX$X$X$X$X$X$X$.D v v ~ ~ % + > Y Y e e /.O.~.~.~.~.~.~.b.b.W.WXqXr.u.: A.K C C.I AXrXq.W l lXB &.) N.VX<X< } }.T x.F o oX-.8 #",
+" v.D.D v v v v ~ ~ ~ ~ ^ ) %.z > YXu e /.~ ].f.f d d d.6.6.6XqXqXqXrXrXrXj.:.:.: AXjXqXq.W l.0XB GXa N N N.VX<.4 }.T x.F o oX-.P",
+" ) ~ ~ ~ ~ ~ ~ ^ ^X*X* _.> + >XOXu e e.O.b.u k.K 6 6 6 A F.uXrXrXqXqXqXqXqXqXqXq mXqXqXqXq ]./XB GXMX,X, N N N.VX< } x.F oX- '",
+".>X*X*X*X*X*X* ) ) ) )Xy..X@.J.7 e e /Xc ].u.K A F A.K.K k.K 6 6 6 A A A.:XjXj mXqXqXqXqXq./.*.R.M.MX>X>X,X, N.V.VX< } x.F o n",
+".{ ) ) ) ) ) ) ) ) _.>.& g.z.7 8 e / / l d F 6 F d A k.#.! h , , , 0.#.I C A.:XjXqXqXqXqXq./.* 5Xl (Xl `X>.MX, N.V.V.4 } x oXz",
+" H _ _ _ _ _X:.>.>.>.> g %X& 8.Y e / / ] F F F.f ] F k.#.! * h h h h ,.#.I |.:Xj.5.5.5 m m./XB &X%X% ( ( ` `.MX, N.V.Z.4 x.FX-",
+".tX:.>.>.>.>.>.>.,.,Xb % +X& YXu e /.O.6 A F.f.6 l.u k.#.|.|.|.|.|.|.| * h C.:Xt.5.5.5.5 m.* 1 &.; ! !X% (XlX>.MXM N.V.Z } x.t",
+".tXb.>.>.,XbXbXbXbXbXb %.z > YXu /.O.~ d 6 F.6.6.W F.# ,.|.|.|.|.|.|.| * , | ..q.5.5.5 m p.* 5.p Q Q Q !X% (XlX>.MXM.V.ZXo .F.t",
+".t.oXbXbXbXbXbXbXnXn.2 %.z > Y e /.O.b.u k F.W ].6 A ,.w.|.|.|.|.|.|.| * , |Xt.q.5.5.q m p.* 5 cXdXd Q Q !X% (Xl yX, N.V.Z } '.t",
+".t zXbXnXnXnXn.1.1.1 i % +X& 8 8 /Xc ].u k F.W.6.u.K h.w.|.|.|.|.|.|.| ,.# |XtXt.q.q.q p./.*XsXg EXXXdXg.; !X% (Xv.MXM.V.ZXoXz.t",
+".t.t.{.1.1.1.1 i i i i [ %.z.7 8 /Xc.6 F k F ]Xr A C h.!.|.|.|.|.|.|.| ,.I | .Xt.q.q.q p./ 1X. E.-.- EXdXg.;Xk (Xl yX,.V.Z.).t.t",
+".t.t z.1 i i i i i i.B 7 g +.zX& >X3.*./X1 P P 6.K.I :.w.|.|.|.|.|.|.|.# C |XtXtXtXtXt P./ 1X..-X.X..- EXd Q.;X%XlX>X,.V.VXz.t.t",
+".t.t.t i i i i.2.B.B.BXpXp g % +X@.RXBXmXeX1X1 bX=X= : :.|.|.|.|.|.|.|.I |.:XtXtXtXtXt./Xm 1 a a a a.-.-XXXg.;Xk (Xv.MXM.V.t.t.t",
+".t.t.tX .2.B.B.B.B.B.BX .} H..XxXxXxX8X8 & 5 1 1.GXeXeX1X1 b bX= : :.w.I |.:XtXtXtXtXt./Xm 5 r r r aX..- EXg QXk (Xv.MXM.k.t.t.t",
+".t.t.t z.B.B.B.B.B.B U.B.{ t.n.v.$._.e.(X9.3 '.y & 5 1.GXeX1 b bX=X= : C A .XtXt . . .Xm 1Xs r r r a a.- EXd QXk (Xl.MXM K.t.t.t",
+".t.t.t.t.=.B.B U U U U U.{ t I.v.x._.(.( ; {.3.3.U.y & c 5 1 1.GXmXeXeX1 P P P.:.:.:.:Xm 1Xs r r r a a.- EXd QXk (Xv.MXa.t.t.t.t",
+".t.t.t.t.tX U U U U U U.{ t I.v.x._.( 9X9.j.X 4.8.a SX2.T.).k G c.c.GXmXm././ P P P PXm.cXs r r r aX..- EXg.lXk.[XvXM.t.t.t.t.t",
+".t.t.t.t.t z U U U UXp U.{ t I.s.x._.e 9X9 =.X @.8.a o S. x .).k.pXs 5 5 1.GXmXmXmXm 1Xs.- a a a aX. EXXXg.;X%.[Xv.).t.t.t.t.t",
+".t.t.t.t.t.t 7 UXpXpXpXp.&Xy I.s.x.@._ 9X9 = $ @.8.aX6X2. .T }X< N NX,X>Xl w cXs 5 5 1 5.-.- a aX.X..- EXd QXk w.[ G.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.=X X X Xp UXy I.s.i.$._.(X9 =.j.X.9.8X6 S. .T }X<.V NX,X>X>Xl.p.p.p c cXg E.-.-.-.- E EXdXg.; w.[ y.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.' 7X X X Xp.{ t 2.v.$._.( ;X9 $.X.9.8.a oX2.T }.4X< N NX,X> ` (X% !.;XgXdXX E E E EXXXdXg.;Xk ( y.y.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.' 7.=.=Xp.& t 3.s.$.@.e VX9 = $ @.8.aX6X2. .T }X<.V NX,.M `Xl (X% !.; QXgXgXdXdXgXg Q.;Xk ( y.y.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.' 7.=.=.&Xy I.s.i.@.e.(X9 = $.X.9.8X6 o. .T.T }X< N NX,.MX>Xl (X%Xk.;.; Q Q Q.l.;Xk w ( y.y.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.' 7.=Xp.g 3.s.i.$.r.( ; = $ # @.8X6X6X2. }.4.V.V NX,.MX>Xl ( (X%XkXkXkXkXkX% w.[ y.y.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.t.' 7Xp.&Xy 3.s.i.@.e VX9 = $.X.9.8X6 oX2 x.T }X<.V.V NXM.M yXvXlXl ( ( ( (.[.[.[ y.y.t.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.t.t.t.o.&Xy 3.s.i.$.r V ; = = $ @.8 nX6 o.F x.T }X<.V.V NXMX,.M yX>XvXvXlXvXvXv G.t.t.t.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.t.t.t.t z.h 3 2.s.$ Z.e VX9 = $ #.P.8 nX6 o.F x }.4.Z.V.V NXMX,X,.M.M.M.MXM.).t.t.t.t.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.h 3.s.i Z.r.e VX9 = $ #.9.8 n o o.F x }.4.Z.Z.V.V.V.VXMXMXMXa.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t [...s.i Z.e V ; = = $ # '.8 n o o.F x }Xo.Z.Z.Z.V.V.k K.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t gX5 Z.e V ; = $ $ #.9.8X- o o.F x x }Xo.)Xz.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t...L.r V ; = $ $ #.P.8X-X- o o.F x.F 'Xz.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t",
+".t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.e V { = $ $ #.P ' nXzX-.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t.t"
+};
diff --git a/arts/builder/pics/Synth_MIDI_DEBUG.xpm b/arts/builder/pics/Synth_MIDI_DEBUG.xpm
new file mode 100644
index 00000000..14dcd697
--- /dev/null
+++ b/arts/builder/pics/Synth_MIDI_DEBUG.xpm
@@ -0,0 +1,323 @@
+/* XPM */
+static char * MIDI_DEBUG_xpm[] = {
+"64 64 256 2",
+" c None",
+". c #161E54",
+"+ c #5A6A9C",
+"@ c #364684",
+"# c #4A5A8C",
+"$ c #8692B4",
+"% c #727EA4",
+"& c #26326C",
+"* c #46527C",
+"= c #5A5E8C",
+"- c #6A769C",
+"; c #323E6C",
+"> c #42467C",
+", c #526294",
+"' c #666A94",
+") c #7E8AAC",
+"! c #9AA6C4",
+"~ c #525A84",
+"{ c #4A527C",
+"] c #2E3A6C",
+"^ c #3A3E74",
+"/ c #7E829C",
+"( c #5A6694",
+"_ c #1E2A64",
+": c #929EBC",
+"< c #6A76BC",
+"[ c #3E4E84",
+"} c #62729C",
+"| c #424E7C",
+"1 c #66729C",
+"2 c #4A5294",
+"3 c #3A468C",
+"4 c #7276A4",
+"5 c #323E84",
+"6 c #525AA4",
+"7 c #5E6AAC",
+"8 c #929ABC",
+"9 c #7A86AC",
+"0 c #2E366C",
+"a c #868AA4",
+"b c #262E64",
+"c c #3E4674",
+"d c #7A7E9C",
+"e c #363E6C",
+"f c #525E8C",
+"g c #4A5684",
+"h c #5A66AC",
+"i c #626A8C",
+"j c #4E5A9C",
+"k c #8E9ABC",
+"l c #2A366C",
+"m c #5A62A4",
+"n c #6676A4",
+"o c #5662A4",
+"p c #2A3A7C",
+"q c #424E8C",
+"r c #6A72AC",
+"s c #8E92B4",
+"t c #465294",
+"u c #AAB2CC",
+"v c #62668C",
+"w c #222E64",
+"x c #1A2664",
+"y c #5A6284",
+"z c #424A8C",
+"A c #566694",
+"B c #666EB4",
+"C c #A2A6C4",
+"D c #7E82AC",
+"E c #6E729C",
+"F c #868AB4",
+"G c #4E5E94",
+"H c #8A96B4",
+"I c #7682A4",
+"J c #26327C",
+"K c #666E94",
+"L c #3A4284",
+"M c #9AA2C4",
+"N c #4A5694",
+"O c #727A9C",
+"P c #6E76A4",
+"Q c #3A4A7C",
+"R c #4A5A94",
+"S c #46568C",
+"T c #32427C",
+"U c #424A74",
+"V c #52629C",
+"W c #828EB4",
+"X c #525A94",
+"Y c #4A528C",
+"Z c #5A669C",
+"` c #222A74",
+" . c #4A4E7C",
+".. c #6672A4",
+"+. c #3A4A8C",
+"@. c #324284",
+"#. c #525E9C",
+"$. c #626EB4",
+"%. c #3E4A7C",
+"&. c #364274",
+"*. c #525E94",
+"=. c #4A568C",
+"-. c #626E94",
+";. c #323A7C",
+">. c #5A6294",
+",. c #868EB4",
+"'. c #727AAC",
+"). c #162254",
+"!. c #5E6E9C",
+"~. c #8A92B4",
+"{. c #767EA4",
+"]. c #2A326C",
+"^. c #42528C",
+"/. c #2E3E7C",
+"(. c #828AAC",
+"_. c #9EAACC",
+":. c #565A84",
+"<. c #323A6C",
+"[. c #3A4274",
+"}. c #222A64",
+"|. c #96A2C4",
+"1. c #464E7C",
+"2. c #5E6AB4",
+"3. c #7A82A4",
+"4. c #464E8C",
+"5. c #7E86AD",
+"6. c #666EA4",
+"7. c #4E5699",
+"8. c #424A84",
+"9. c #6E7AC0",
+"0. c #8A8EAC",
+"a. c #A2AACC",
+"b. c #7E86A4",
+"c. c #4E5E9C",
+"d. c #8E96BC",
+"e. c #465694",
+"f. c #6E7AA5",
+"g. c #6672BC",
+"h. c #1A2264",
+"i. c #2E367C",
+"j. c #262E74",
+"k. c #3E4684",
+"l. c #363E7C",
+"m. c #626A9C",
+"n. c #2A367C",
+"o. c #62669C",
+"p. c #222E74",
+"q. c #5E6A9A",
+"r. c #3A4682",
+"s. c #4E5A8B",
+"t. c #6E769C",
+"u. c #566293",
+"v. c #9EA6C6",
+"w. c #4E5284",
+"x. c #5E6693",
+"y. c #969EC4",
+"z. c #6A729B",
+"A. c #626AA4",
+"B. c #969ABC",
+"C. c #565E8A",
+"D. c #4E5684",
+"E. c #6A76A5",
+"F. c #2E3A7D",
+"G. c #1E266B",
+"H. c #5E628C",
+"I. c #6A6E94",
+"J. c #9EA2BC",
+"K. c #767AA4",
+"L. c #464A7C",
+"M. c #3E4A8E",
+"N. c #364285",
+"O. c #565EA1",
+"P. c #8A8EB5",
+"Q. c #1A225C",
+"R. c #3E4274",
+"S. c #8286AC",
+"T. c #A6AAC4",
+"U. c #3E468C",
+"V. c #363E84",
+"W. c #5E66AC",
+"X. c #2A327C",
+"Y. c #4E5A94",
+"Z. c #56629C",
+"`. c #4E528C",
+" + c #5E669C",
+".+ c #6A72A4",
+"++ c #565E94",
+"@+ c #4E568C",
+"#+ c #5E6294",
+"$+ c #767AAC",
+"%+ c #46528C",
+"&+ c #323E7C",
+"*+ c #626AB4",
+"=+ c #8692BC",
+"-+ c #727EAC",
+";+ c #263274",
+">+ c #465284",
+",+ c #5A5E94",
+"'+ c #323E74",
+")+ c #666A9C",
+"!+ c #7E8AB4",
+"~+ c #525A8C",
+"{+ c #4A5284",
+"]+ c #2E3A74",
+"^+ c #7E82A4",
+"/+ c #1E2A6C",
+"(+ c #929EC4",
+"_+ c #3E4E8C",
+":+ c #6272A4",
+"<+ c #424E84",
+"[+ c #4A529C",
+"}+ c #929AC4",
+"|+ c #7A86B4",
+"1+ c #2E3674",
+"2+ c #262E6C",
+"3+ c #3E467C",
+"4+ c #7A7EA4",
+"5+ c #363E74",
+"6+ c #626A94",
+"7+ c #4E5AA4",
+"8+ c #2A3674",
+"9+ c #5A62AC",
+"0+ c #5662AC",
+"a+ c #424E94",
+"b+ c #46529C",
+"c+ c #626694",
+"d+ c #222E6C",
+"e+ c #5A628C",
+"f+ c #424A94",
+"g+ c #56669C",
+"h+ c #6E72A4",
+"i+ c #8A96BC",
+"j+ c #7682AC",
+"k+ c #666E9C",
+"l+ c #3A428C",
+"m+ c #4A569C",
+"n+ c #727AA4",
+"o+ c #3A4A84",
+"p+ c #424A7C",
+"q+ c #525EA4",
+"r+ c #3E4A84",
+"s+ c #36427C",
+"t+ c #626E9C",
+"u+ c #323A84",
+"v+ c #868EBC",
+"w+ c #8A92BC",
+"x+ c #767EAC",
+"y+ c #2A3274",
+"z+ c #828AB4",
+"A+ c #565A8C",
+"B+ c #323A74",
+"C+ c #3A427C",
+"D+ c #222A6C",
+"E+ c #464E84",
+"F+ c #7A82AC",
+"G+ c #464E94",
+" ;+y+y+X.X.;+j.p.` D+/+G. ",
+" }.B+N.N.u+F.F.n.J j.;+j.p.p.D+d+Q.. . . ",
+" 0 8.M.U.l+N.5 F.i.i.n.J ;+j.` p./+/+/+G.h.h.. . ",
+" B+j 7.m+G+f+3 N.V.u+F.F.n.J j.p.p.p.` p.p.` /+/+x h.. . . . ",
+" X O.O.7.b+a+M.3 N.@.u+i.n.n.n.X.;+j.p.` /+/+/+/+` /+/+G.G.h.. . ",
+" @+*+h 9+7+m+[+a+f+3 l+V.5 F.i.X.J ;+j.p.p.p.` ` ` G./+/+G./+G./+h.. . . ",
+" 6.$.2.0+O.6 m+G+f+U.3 l+5 u+F.i.X.J J j.j.` p./+/+` G./+` G./+G./+G.x h.. . ",
+" E+< g.*+W.9+q+7+m+b+f+M.l+V.u+/.F.n.n.y+;+;+p.d+` p.` /+/+G.G./+G./+G.G.G.G.h.. . . ",
+" R.E.g.g.2.h 0+7+m+b+a+M.3 3 @.u+u+p n.J J j.p.j.p.` p.` /+/+` G./+G.G.x G.G.G.G.h.. . . ",
+" @+9.g.g.2.h 0+6 7.[+a+a+f+3 l+V.5 i.i.X.y+j.;+j.p.D+` /+/+/+/+/+/+G./+/+/+x /+/+G./+h.. . . ",
+" R.r < B $.2.0+q+j m+2 a+M.3 N.@.F.F.i.n.n.;+j.j.p.p.d+` p./+/+` G./+G.x G./+G.G./+x G.x h.. . . ",
+" <+9.< g.B W.9+O.#.O. +Z.X M.3 N.V.5 B+F.1+;+J ;+;+j.p./+/+/+` G.G./+G./+/+G.x G.x G.G./+G.G.h.. . . ",
+" B g.B *+2.h m m +.+4+o.7.z l+V.^ r+{+p+C+1+j.p.p.D+` D+D+/+/+/+` /+G.G./+x /+/+G./+G.G.G.x x h.. . ",
+" r g.g.$.2.9+o h r v+B.a.f.@+r+V.r+++I.S.P H.5+& j.d+d+d+2+].D+/+/+` /+/+/+/+` G.G./+/+/+/+/+G.G./+h.. . ",
+" p+B *+2.h 0+o 6 6 A.W w+}+6.Y Y .~+x.q.6+m.6+3+y+y+1+5+p+[.5+2+/+/+/+p.` p.y+;+;+p./+/+/+/+/+/+G.G.G.x . . ",
+" *+2.W.h 9+o 6 j R #+F F F +z ++n+.+)+= @+>.I.E+]+C+<+' ,.i 1.l ` p.p.p.8+5+>+p+s+y+p.p.p.d+d+d+w d+_ G.).. ",
+" 7.h h 0+V q+7+7.[+2 m P.x+h+#+7.o.F+x.1.L.| `.C.> ]+R.=.4 B.v e l 2+y+]+s+E+C.1 A+%.1+2+2+2+& 0 [.U [.] 2+_ x . ",
+" l.0+0+q+6 6 7.j m+G+q >.d.4 ++++++- ,.D.1+&+R.%.E+C+i.r.A+4+T.= ] ].;+]+3+#+4+a B.z.{+B+;+& ].[.:.K F+' D.<.D+}.. . ",
+" 4.6 6 6 7+7+[+b+t z 4. +v+t+=.++)+I.P E+1+5+ .> &.1+].'+g K (. .].;+;+F.C+u.z+F ~.c+%.5+1+[.w.~ H.' 4 z.' c & 2+D+Q. ",
+" 7+7.m+m+[+b+b+b+a+z >.z.z+>.z *.'.1 #+^ y+l.e+%.1+].j.0 L.:.I.[.& y+y+8+T C.0.,.P.u.C+s+r.u.b.n+1 K 6+E {.w.0 & w x ",
+" 0 m+m+b+b+G+a+f+M.M.8.)+I..+Y C+~+4+z.( | B+3+C.[.8+;+;+<.C.~ D.<.& 8+8+1+l.s.0.5.{.~ C+p+D.k+S.v 1.1.* e+f.{ 0 & 2+d+x ",
+" G+a+a+G+f+f+M.M.3 N.Y x+A.A+k.u+Y (.h+#+@+<+D.= 5+;+y+].e E ~ R.0 8+8+n.8+]+D.,.{.I.g r.s.P {.b.D.5+'+5+{ E 1.] ].& }.. ",
+" x z f+M.M.M.M.3 l+l+N.k.~+%+k.l.F.8.n+n+h+' >.D.p+1+;+;+].c t.{ ; 8+n.i.F.]+C+C.P.P >.Y p+e+F+n+z.| ] '+3+{ x.c l & ;+l & x ",
+" ;.U.3 3 3 3 l+l+l+V.;.&+k.&+;.F.1+3+)+4 (.F+$+@+s+1+8+].] .d 1.0 1+p F.p B+1.6+P.k+Y g %+m.P.t.e+[.]+5+| D.~ [.0 8+8+y+b . ",
+" &+l+l+l+N.N.N.N.@.5 5 F.;.F.i.n.n.]+%. .~+D.{+^ p y+n.l [.1.y [.8+1+F.F./.r.e+- (.( 8.E+{+1 d.z.s.C+]+[.~ D.E+5+1+1+8+8+y+& ",
+" N.5 5 5 5 V.5 5 u+u+i.i.i.n.n.y+y+y+y+]+'+&+;.8+y+8+n.1+U 1. .'+]+F./.&+;.%.n+4+5.C.r.<+=.E J.K 1.[.'+p+K ~ %.'+]+p ]+1+l ]. ",
+"j.5 5 5 u+u+u+F.F.F.F.F.n.X.n.n.J ;+;+j.y+y+8+1+8+n.n.F.]+5+'+5+]+F.&+5 /.;.E+f.E..+g @ %.%+z.M {.u.Y <+f t.~ [.B+B+F.]+F.p p l ",
+"y+u+u+u+F.p p i.n.8+1+n.y+8+;+;+y+;+J ;+;+;+;+n.n.n.8+n.i.]+]+F.;.&+5 5 &+s+>+z.m.u.8.s+r.>+K M z+t.1 ( z.4+D.&./.F././.]+]+1+8+",
+";+n.n.i.i.i.i.u+^ r+R.N.y+j.j.p.j.j.;+;+y+y+;+X.n.p F.p i.F.]+/.&+5 s+N.s+s+r+=.>+q r.r.r.[ #+(.(.F+x+n+E.1 >+&.'+&+;.&+;.F.F.1+",
+"n.i.X.n.n.n.5 8.u.K.x.Y ;.;+;+j.p.y+y+8+;+J X.8+F.i.n.F./.;./.5 5 N.@.N.@.N.s+r.r.@ r.@ r.8.f n+9 d.P.z+- >.<+s+s+l.T &+&+'+]+p ",
+"J X.J X.8+F.k.,+.+z+x.%.1+j.;+].B+p+R.C+0 8+n.8+8+]+]+;./.&+&+T @.N.N.L N.@ N.@ r.@ 3 r.3 o+<+@+C.q.q.x.s.E+r.N.s+N.s+T &+&+;.]+",
+";+J j.;+X.B+=.'.a B.x.C+y+` l 8.C.n+q.D.B+;+8+n.]+l.[.r.s+&+&+5 N.N.@ @ @ 3 o+3 +.M.M.M.o+M.o+[ <+| E+%+r+r.r.@ @ N.N.l.@.&+&+F.",
+"j.;+p.j.j.y+1.4 x+D {+0 ].j.B+C.h+a x.<+B+;+1+&+%.s.C.e+{+r+s+5 N.N.@ r.r.r.o+r++.M._+_++.M.r+r+r+[ r+[ o+r.r.r.r.@ @ s+s+T T &+",
+"p.j.j.j.p.2+C+t.t.t.R.d+p.2+> P F J.x.[.]+8+&.~+I.S.F P..+f r+s+N.r.l+r.r.r+M.+.M._+_+q q q q _+_+M.[ M.r+M.r++.o+r.@ N.N.V.l.F.",
+"` p.p.p.p.2+%.{.m.~+B+D+d+d+3+P F+0.D.1+<.B+{+z.P f.F+,.h+++%+r.o+r+^.@+@+@+>+[ _+_+_+_+_+_+M.q _+z q _+_+_+M.M.o+k.o+@ @ s+s+&+",
+"/+` d+` D+2+ .D = 3+& D+/+p.[.z.O {.p+l B+p+x.$ n+m.n+z+- x.=.<+t s.m.j+-+f.G 4.q q a+^.^.>+>+<+^.^.^.^.q q _+[ M.o+r.r.r.N.s+&+",
+"/+` d+/+2+5+A+{.{+1+d+/+D+2+8.K.k+e+^ l [.H.c+k+C.{+x.x+z.m., @+Z.t+j+d.!+x+, ^.q ^.4.%+s.( ( >.g q q ^._+q _+_+M.r+o+r.r.@ @ s+",
+"G./+/+` ].D.x.P 3+2+/+G.D+y+{+5.x.1.B+& %.3.v {+%.s+=.f...t+ +V P z+d.v.~.j+++%+^.^.# x.f.,.$ ~.t+# %+^.^.^.q q _+_+M.o+o+r.C+&+",
+" ` /+/+B+H.e+++B+}.D+G.d+[.C.D ~ '+B+0 { 3.C.R.r.r.@+f.6.Z *.=.t+(.d.v.z+E.*.=.Y.u.-.x+5.w+i+d.n+( # t t e.^.^._+[ M.o+r.@ r. ",
+" /+/+D+[.P C.p+2+/+G./+].Y 6+b.E+0 0 e ~ b.{ '+C+%.*.P q.*.Y q >.) d.v.F+q.u.Y.m.F+~.|.8 ~.d.y.) f.*.S S t %+4.q q [ M.r+r.@ ",
+" . G.}.0 `.C+0 D+/+x /+B+#+x.6+[.& <.1.v 5.D.T k.{+m t.u.%+<+[ ,+(.~.: f.Z.( Z f.w+,.!+-+- j+d.5.n+u.S S e.e.%+^.q _+_+r+r.'+ ",
+" Q./+/+& '+].D+G.x /+D+C+I.#+D.B+& [.i f.5.s.C+>+x.k+.+~+r+o+k.f ,.$ w+1 *.+ f.,._.W f.q.*.1 z+j+f.u.R e.e.S e.^.^.q r++.c b ",
+" Q.G.D+d+/+/+G.G./+w '+++E+[.y+2+5+H.z.3.u.p+f 1 t+u.%+r.r+[ x.s F 5.t+*.t+j+w+J.I q.g+*.} ~.x+..*.R N e.e.t ^.q q [ o+r. ",
+" h.G.x G.G.G./+/+G.D+1+1.5+& & ;+5+= K 4+6+~+)+4+x.=.k.r.r+Y 1 y.!+'.t+V ..=+d.|.P u.*.*.} i+-+q., R R N e.S t ^.^.q [ & ",
+" h.x /+x G.G./+G.}.d+].].2+d+2+] E+e+K.- 1 -. +Y Q r.@ <+C.f.8 j+t+ +Z.P d.i+i+k+*.V Z.P k % Z *.R R R e.e.e.^.q q [ ",
+" G./+x /+/+/+G.G.x G.D+/+D+d+;+8+[.@+t.3.(.)+D.3+N.N.r.<+- F+w+P Z.A g+j+|.s ) !.G u.q.% i+E.( G G c.R R e.^.^.^._+[. ",
+" . h.G.G.x x x G.G.x D+d+p.d+p.& l s+E+D.f <+r.s+s+N.r.=.{.9 W 1 *.*.*.-+_.d.!+:+V q.E.j+W n g+c.R j R R N t ^.q q r. ",
+" G.G.G.G.G.G.G.G./+/+/+d+;+;+y+8+0 B+l.&.&.T s+@ r.r.@+F+F+F+( N s.G n+u B.z+1 Z.n W !+5.t+V *.c.G R N e.S ^.^.Q ",
+" h.G./+/+x /+G.G.D+` D+2+;+;+8+8+8+]+;.;.&+&+N.@ r.>+m.q.q.s.^.N *.E.v.8 w+9 E.j+=+!+-+q.V c.c.j R R e.%+%+[ ",
+" )./+G.G./+x G./+/+d+p.;+j.;+8+8+]+F.F.&+T N.N.s+r.[ =.Y.7.^.4.S s.z.(+(+8 i+w+i+i+j+n + V G R R R e.t S ^.0 ",
+" . G.G.G./+G./+/+D+D+& ;+;+8+n.8+]+F.F.T T N.@ L o+r+^.q ^.q ^.R q.5.=+}+d.w+w+W f.7 , c.G c.R N S t ^.<+ ",
+" x x x x x G.G.d+p.p.j.;+;+8+i.p /.5 &+N.s+N.@ r.o+r+[ M.^.%+e.++E.9 8 i+i+W !+n g+*.G R R R R e.S ^. ",
+" . h.G.G.x /+G./+D+d+j.y+;+8+1+i.F.&+&+@.T N.N.r.3 U.[ M._+q ^.N , q.f.f.f.E...g+G Y.j R N e.=.^.4.c ",
+" . x x G.G./+/+d+p.j.;+8+8+8+p F.F./.l.s+@ r.r.o+o++._+q _+^.%+N Y.*.Z.+ g+#.Y.Y.R R e.R S e.>+l ",
+" . . x x /+/+d+d+d+j.;+8+1+]+]+;./.5 &+T N.N.r.U.r+_+q q ^.^.^.e.N Y.Y.R Y.R R e.R e.e.^.^.c ",
+" Q.G.G.G.G.D+d+p.;+;+;+8+8+F.F.;.&+s+N.@ r.r.o++.r+_+_+_+q t %+S %+S =.e.e.e.e.%+%+%+>+l ",
+" . . _ /+/+d+d+2+;+;+8+8+p F.F.F.&+&+@.@ N.r.+.r.M.r+_+_+q _+^.a+^.S %+%+S e.e.%+^.r. ",
+" h.G.D+D+d+;+;+;+y+8+1+]+/.&+&+V.s+s+@ N.@ o+o+_+M.<+_+q q ^.^.^.^.^.^.^.^.^. ",
+" . _ /+D+d+2+;+y+8+8+1+]+F./.&+5 s+s+L r.r.r.r++.[ _+_+q q q ^.^.a+q [ r. ",
+" G.d+D+;+& ;+;+8+8+F.]+&+&+&+5 s+@ N.r.r.o+k.r+r+[ _+_+_+_+q <+[ ",
+" x _ p.& ;+;+8+8+p 1+F./.'+&+&+s+N.@ N.@ r.o+3 r+r+r+M.r+r+r. ",
+" _ 2+y+;+y+1+p ]+B+/.&+&+T T s+@ r.@ r.o+r.o+r.&. ",
+" w w & 8+8+p F././.;.&+l.l.s+N.N.C+@ &+s+ ",
+" y+8+1+1+]+/.&+/.&+&+s+s+ "};
diff --git a/arts/builder/pics/Synth_MIDI_ROUTER.xpm b/arts/builder/pics/Synth_MIDI_ROUTER.xpm
new file mode 100644
index 00000000..43b8a59d
--- /dev/null
+++ b/arts/builder/pics/Synth_MIDI_ROUTER.xpm
@@ -0,0 +1,323 @@
+/* XPM */
+static char * Synth_MIDI_ROUTER_xpm[] = {
+"64 64 256 2",
+" c None",
+". c #161E54",
+"+ c #AE922C",
+"@ c #4A5A94",
+"# c #363E64",
+"$ c #DECA34",
+"% c #3E4E84",
+"& c #D2AE1C",
+"* c #222E64",
+"= c #A6721C",
+"- c #42425C",
+"; c #3A3A54",
+"> c #FEE61C",
+", c #626EB4",
+"' c #FEAE04",
+") c #3A4674",
+"! c #2E3664",
+"~ c #CE9214",
+"{ c #52669C",
+"] c #4A4E84",
+"^ c #E2DA4C",
+"/ c #2E3E7C",
+"( c #CABE5C",
+"_ c #2A2E5C",
+": c #CEA21C",
+"< c #565E94",
+"[ c #A68224",
+"} c #FACA14",
+"| c #3E427C",
+"1 c #CE8A14",
+"2 c #1A2664",
+"3 c #46568C",
+"4 c #D6AE24",
+"5 c #3E4E8C",
+"6 c #B28A24",
+"7 c #3E4A7C",
+"8 c #52629C",
+"9 c #FABE0C",
+"0 c #D29A14",
+"a c #4A5A9C",
+"b c #363E84",
+"c c #22265C",
+"d c #FEF62C",
+"e c #4A5694",
+"f c #2A3274",
+"g c #D6B624",
+"h c #464E8C",
+"i c #3A3E6C",
+"j c #222E74",
+"k c #323A74",
+"l c #2A367C",
+"m c #FAD214",
+"n c #DED23C",
+"o c #364684",
+"p c #2A3264",
+"q c #3E4A8C",
+"r c #D69E14",
+"s c #BE9A2C",
+"t c #323664",
+"u c #5E66AC",
+"v c #DEA614",
+"w c #B28224",
+"x c #525AA4",
+"y c #6A76BC",
+"z c #FAB60C",
+"A c #565EA4",
+"B c #B68A24",
+"C c #FAC60C",
+"D c #CE9E14",
+"E c #36427C",
+"F c #222A6C",
+"G c #DEBA24",
+"H c #323A64",
+"I c #BA9224",
+"J c #364274",
+"K c #26326C",
+"L c #FEEE24",
+"M c #2E3A74",
+"N c #4A528C",
+"O c #FEDA14",
+"P c #32427C",
+"Q c #DABE2C",
+"R c #D2AA1C",
+"S c #FACE14",
+"T c #3E467C",
+"U c #1E2A6C",
+"V c #42528C",
+"W c #464A84",
+"X c #FEFE34",
+"Y c #4A569C",
+"Z c #D6BA2C",
+"` c #46528C",
+" . c #E2D644",
+".. c #3A4A84",
+"+. c #2A326C",
+"@. c #36428C",
+"#. c #162254",
+"$. c #525A8C",
+"%. c #323E74",
+"&. c #C6B654",
+"*. c #262E64",
+"=. c #464A64",
+"-. c #2A3674",
+";. c #D69614",
+">. c #5A66AC",
+",. c #CEA61C",
+"'. c #1E266C",
+"). c #DEB21C",
+"!. c #424A7C",
+"~. c #FAC20C",
+"{. c #4E5E9C",
+"]. c #222A5C",
+"^. c #3A426C",
+"/. c #263274",
+"(. c #2E3A7C",
+"_. c #FAD61C",
+":. c #BA8224",
+"<. c #FABA0C",
+"[. c #5662A4",
+"}. c #D29E14",
+"|. c #363A64",
+"1. c #FEE21C",
+"2. c #DAC634",
+"3. c #3E468C",
+"4. c #DECE3C",
+"5. c #464E74",
+"6. c #D2B224",
+"7. c #3E466C",
+"8. c #FEEA24",
+"9. c #AA7E24",
+"0. c #AE8624",
+"a. c #4E5274",
+"b. c #6672BC",
+"c. c #5A629C",
+"d. c #D6B224",
+"e. c #AE8E2C",
+"f. c #5E6AB4",
+"g. c #6E7ABC",
+"h. c #B6962C",
+"i. c #4E5E94",
+"j. c #D29614",
+"k. c #AA8624",
+"l. c #CE8E14",
+"m. c #B28624",
+"n. c #B68E24",
+"o. c #C69A24",
+"p. c #3A4A7C",
+"q. c #525E9C",
+"r. c #FEF22C",
+"s. c #FEDE14",
+"t. c #DAC234",
+"u. c #E6A614",
+"v. c #FEB204",
+"w. c #FEFA2C",
+"x. c #1A2264",
+"y. c #2A2E6C",
+"z. c #323A84",
+"A. c #4A529C",
+"B. c #FEFE44",
+"C. c #46529C",
+"D. c #464E84",
+"E. c #5666A4",
+"F. c #323E7C",
+"G. c #FECA0C",
+"H. c #1E265C",
+"I. c #DAAE1C",
+"J. c #424E8C",
+"K. c #4E5AA1",
+"L. c #4E5692",
+"M. c #DAB624",
+"N. c #E2D244",
+"O. c #3A4686",
+"P. c #2E3262",
+"Q. c #424A94",
+"R. c #FEB604",
+"S. c #3A427C",
+"T. c #FECE0F",
+"U. c #42467C",
+"V. c #1A225C",
+"W. c #262A64",
+"X. c #FED614",
+"Y. c #FEBA04",
+"Z. c #5A62AC",
+"`. c #B28E24",
+" + c #B2922C",
+".+ c #666EB4",
+"++ c #D29214",
+"@+ c #D2A21C",
+"#+ c #FEBE0C",
+"$+ c #262E74",
+"%+ c #2E367C",
+"&+ c #FED214",
+"*+ c #DA9E14",
+"=+ c #FEC60C",
+"-+ c #4E569C",
+";+ c #DABA2C",
+">+ c #2E326C",
+",+ c #3A428C",
+"'+ c #363E74",
+")+ c #2E3674",
+"!+ c #D2A61C",
+"~+ c #FEC20C",
+"{+ c #DEC634",
+"]+ c #626AB4",
+"^+ c #BA962C",
+"/+ c #D28E14",
+"(+ c #B68624",
+"_+ c #BA8E24",
+":+ c #363E6C",
+"<+ c #DECA3C",
+"[+ c #D2AE24",
+"}+ c #222E6C",
+"|+ c #FEE624",
+"1+ c #3A467C",
+"2+ c #2E366C",
+"3+ c #5266A4",
+"4+ c #2A2E64",
+"5+ c #465694",
+"6+ c #3E4A84",
+"7+ c #D29A1C",
+"8+ c #2A327C",
+"9+ c #D6B62C",
+"0+ c #464E94",
+"a+ c #3A3E74",
+"b+ c #DED244",
+"c+ c #3E4A94",
+"d+ c #32366C",
+"e+ c #CE9E1C",
+"f+ c #364284",
+"g+ c #222A74",
+"h+ c #323A6C",
+"i+ c #4A5294",
+"j+ c #324284",
+"k+ c #3E4684",
+"l+ c #425294",
+"m+ c #FEFE3C",
+"n+ c #465294",
+"o+ c #E2D64C",
+"p+ c #3A4A8C",
+"q+ c #525A94",
+"r+ c #262E6C",
+"s+ c #424A84",
+"t+ c #222A64",
+"u+ c #3A4274",
+"v+ c #26327C",
+"w+ c #2E3A84",
+"x+ c #5662AC",
+"y+ c #D29E1C",
+"z+ c #363A6C",
+"A+ c #3E4674",
+"B+ c #6E7AC4",
+"C+ c #525EA4",
+"D+ c #FEDE1C",
+"E+ c #323E84",
+"F+ c #1E2664",
+"G+ c #424E94",
+" /.f f 8+8+/.$+j g+F U F+ ",
+" ].k f+f+z.w+(.l v+$+/.$+j j F j x.. . . ",
+" d+s+q 3.,+f+E+w+%+%+l v+/.$+g+j U U U '.x.x.. . ",
+" k K.-+Y G+c+3.@.b z.w+(.l v+$+j j j g+j j g+U U 2 x.. . . . ",
+" q+A C+Y A.0+c+O.@.j+z.%+l l l 8+/.$+j g+U U U U g+U U '.'.x.. . ",
+" L.]+>.x+x -+C.G+c+O.@.b E+w+%+8+/./.$+j }+j g+g+g+'.U U '.U '.U x.. . . ",
+" , , f.Z.C+K.Y 0+Q.3.3.@.E+z.w+%+8+v+v+$+$+g+}+U U g+'.U U '.U '.U '.2 x.. . ",
+" % y b.]+u x+A K.Y C.Q.c+@.b z./ (.l l f /./.j j g+j g+U g+'.'.U '.U '.'.'.'.x.. . . ",
+" | y b.b.f.>.x+x -+C.G+c+3.o @.z.w+(.l v+v+$+j $+j g+}+g+U U U '.U '.'.2 '.'.2 '.x.. . . ",
+" L.g.b.b.]+>.c.C+K.Y C.G+c+3.,+b E+%+l 8+8+$+v+$+j F g+U U U U U U '.U U U '.U U '.U x.. . . ",
+" | b.y .+, f.E.A x Y A.0+Q.O.@.f+E+E+w+%+-.8+$+$+j j }+g+j g+U U '.g+'.'.'.U 2 '.U 2 '.2 x.. . . ",
+" 5.g.y b..+f.>.A C+K.Y n+G+c+3.,+E+E+(.%+l 8+/././.$+j U g+U U '.'.U '.U U '.'.'.2 '.'.U '.'.x.. . . ",
+" .+b..+, u u Z.C+K.Y C.G+c+p+o @.E+z.(.(.l l v+j j j j j U U U g+U U '.'.U U U U '.U '.2 '.2 2 x.. . ",
+" b.b.b., f.>.x+C+K.Y A.0+G+c+,+,+b z.w+w+l l /.$+$+$+g+g+U g+g+g+U g+U U U U U U U U U U U U '.'.U x.. . ",
+" W .+]+]+u >.A C+x -+A.G+Q.3.3.,+@.b z.%+l /.y.K r+j $+r+j j j j j U j j j j U g+g+j g+j j g+j U U U U 2 x.. ",
+" f.f.u >.x+A C+K.Y A.C.G+c+c+O.@.b E+(.(.l ! h.& +_ }+j g+g+U }+g+j j j j j j j j j }+F F }+F j F g+F U . . ",
+" L.>.>.A c.[.< < q+e N ] D.U.T S.u+'+'+k d+P.s _.O m I *.r+j /.j /.$+j j j $+/././.r+/././.j /.}+j }+}+g+}+U 2 . ",
+" b Z.[.A @ ( o+o+o+N.N.4.n <+<+{+{+Q Q Z 9+g G _.D+O X.S 6 K /.$+$+j /././././.$+/././././.$+/.$+/.K $+j r+j F F V.. ",
+" h x K.x L.^ B.m+m+m+m+X X w.d r.L 8.|+> 1.1.D+O O O X.X.!+p /./.f /.f /.f /.-././.l /./.-./.-./././.K /.r+/.K }+F 2 ",
+" K.-+-+Y N &. .b+b+n 4.<+$ 2.t.Q Q Q ;+Z 9+4 M._.X.X.X.} 6 +.v+v+/./.v+-.-.l v+l -.f l -./.-./.f f -.f /./.$+$+}+K V. ",
+" ! Y 5+C.0+0+h ] D.W W !.| | | E '+k h+d+d+2+>+P.^+m X.X.I.; /.-.l l -.l l -.(.)+l (.-.l (.l M l l -.l -.-.-./.f r++.}+H. ",
+" 0+G+0+Q.G+c+c+c+3.O.o @.@.E+E+k w+w+l l v+f /.f P.n.I.G.G._+P.-.-.%+%+%+l %+l (.(.l (.(.l (.l M (.-.-.-.-.-.-.-.-./.* . ",
+" H.Q.c+Q.c+q 3.O.3.3.@.b b b z.w+w+l %+l f l l v+f v+>+P.I C } B ! M (.(.(.(.(.(.(./ (.(.F.(./ (.(.(.(.(.%+l -.-.-.-.f -.K H. ",
+" k O.3.3.,+,+O.@.@.b b E+E+/ w+(.%+%+l f v+/./.f l -.l l P.n.C C B ! l (.(.(.(.(.(.k / / (./ k / (./ (.(.(.M (.l l -.-.f * . ",
+" F.@.o ,+,+@.@.E+j+E+E+w+z.(.%+l l 8+8+f 8+8+l v+l l -.l l ! _+C ~.B ! / / / E+E+/ E+E+P E+E+E+F.F.F.F./ F.(.k M )+-.-.)+f K ",
+" @.b b j+j+b b E+z.z.z.w+%+l l l l /./.v+/.f f l f l l (.(.%+t o.C ~.B d+k E+F.E+f+b b E+b j+F.j+F.E+F.F./ F./ (./ (.M -.-.f ",
+"$+E+E+z.z.w+w+z.w+w+(.%+l %+l 8+/.8+v+f v+l l -.l l l l (.(.(.(.=.o.#+~.B |.E+f+F.j+j+E f+E f+f+f+E j+f+b F.E+F.(.F.(.M M M M -.",
+"f w+w+w+w+w+w+(.(.%+l l l l 8+f 8+/././.-././.8+-.l (.(.(.(.(./ z.H B 9 9 B # '+f+f+o o o f+o f+f+f+f+E j+E E f+P / F.F.(.M l -.",
+"8+%+%+%+%+%+l l l l l l v+f v+$+/.$+v+v+v+l l l l -.(.(.w+/ z.F.E+F.|.B <.9 r m.i S.,+o O.O.O.O.o O.o O.f+f+P b b F.F./ (.k M )+",
+"-.l l l l l 8+8+>+>+>++.>++.p p y.+.p p 2+P.2+2+d+k 2+%+F.E+/ j+f+j+F.- v #+~+z (+i ) | u+u+u+J a.5.| u+J J a+J J :+k F.F./ (.M ",
+"8+8+8+v+/.l /.K + g d.6.6.6.[+& & & R !+R !+!+!+!+!+k.M (.E+F.E+E f+'+w 9 #+~+#+<.0 0 0 j.j.j.j.v u.++++/+~ l.1 l.l.= %.F./ (.(.",
+"$+/./.f 8+$+v+y.g 1.1.s.s.O O O X.X.X.X.&+&+&+&+T.G.@+z+E+P E+j+f+f+u+}.#+~+#+#+Y.#+Y.R.Y.R.R.R.R.R.R.v.v.' ' ' ' ' l.i P F.F.M ",
+"$+$+j j /.$+/.r+e.6.d.[+[+[+R R R !+!+R !+@+@+@+!+@+[ '+E+j+f+j+o o J m.<.#+#+#+z 0 0 j.j.j.++++~ /+~ ~ l.l.l.1 1 /+w i f+P P F.",
+"j v+/.$+j j $+}+*.4+*.4+4+*.4+y.4++.>+p >+! M d+d+h+'+(.F.f+f+f+@.O.O.^.(+<.#+R.(+7.k+7 6+7 % !.!.7 !.A+!.A+A+A+7.^.!.f+E b b (.",
+"F g+j j $+g+j j j j }+j g+U j j $+/./.-.-.-.(.(./ (.E+E+E+P f+o o O.O.6+^.w 0 w 7.5 G+V G+J.V J.V J.V 5 J.5 6+p+q 6+..O.o E E F.",
+"U j j g+g+}+g+}+U g+U U }+g+U j K j v+/.l l l (.(.E+F.E f+f+O.O.O.p+p+..6+7 7 !.J.V V V ` n+l+l+l+V J.J.5 J.5 6+....O.o O.E E F.",
+"U F j }+U j g+g+F g+g+U U g+F g+$+$+/./.-.(.(.(.(.E+E+E+f+f+@.O.O.q q 5 q 5 5 l+l+l+n+5+5+V 5+` l+5+l+` V V V J.6+6+6+O.O.o o E ",
+"'.U g+U g+F U F U U U U F U j }+/./.f l l l l (./ F.F.f+f+o O.O.p+p+p+q J.J.l+G+` n+l+l+n+5+5+5+5+n+3 5+l+G+J.5 J.5 p+....1+S.F.",
+" U g+U U g+U U g+U '.U U U j F $+/./.f -.(.(.k / E+j+f+f+o o O.p+q 5 5 G+J.V l+5+3 5+5+e e 5+e @ 5+5+` 3 l+n+J.J.J.6+..O.o O. ",
+" U U g+U U U g+U g+g+U F g+U j j $+f -.l l w+w+z.F.E+j+@.o O.q q 5 5 l+V l+n+n+n+5+e @ a @ a @ 5+5+5+5+5+3 V V J.5 5 q 6+O.o ",
+" . 2 g+'.g+U U U U U '.'.F j }+/./.v+-.(.l (./ E+b E o S.O.O.O.q q 5 5 V l+5+5+e @ 5+5+a @ a K.@ @ a 5+5+5+5+V V J.% 5 6+O.%. ",
+" V.U '.U U '.'.'.'.'.U U U U $+j /./.8+-.(.(.k / P f+@.o o p+q q 5 J.l+n+3 5+5+5+5+a {.@ a @ i.{.K.@ @ e 5+` 5+V V J.6+6+) *. ",
+" 2 U '.U U 2 t+t+c t+W.*.*.4+*.p ! 2+2+M h+'+z+%.'+f+O.o p+p+q 5 J.l+l+l+5+5+a @ @ K.i.{.{.{.i.{.K.@ e @ 5+n+V J.J.5 ..O. ",
+" x.'.U '.'.t+[ @+,.: : D : D @+: e+D D }.e+7+D 7+9.E o O...q 5 5 G+J.` 5+5+a @ {.a {.{.q.{.{.{.{.i.{.a 5+e 3 ` l+V % % p ",
+" x.U U '.].,.T.T.T.T.G.T.G.=+=+=+=+~+=+=+~+~+~+0 u+O.O.p+q q 5 l+l+n+5+5+e @ i.{.{.{.{.8 8 8 8 {.i.K.@ e 5+3 V J.J.% ",
+" 2 '.'.U H.[ @+@+D D : y+D @+D y+}.e+0 0 }.0 0 9.a+o O...q J.J.J.V 5+n+5+a a a {.{.8 8 8 8 8 {.i.{.i.@ @ 5+l+l+V 5 J ",
+" . 2 '.'.'.H.].].].c ].*.*.p p +.! 2+M M h+%.%.J f+O.O.p+p+5 V G+V 5+5+5+e @ @ {.{.8 8 3+8 3+8 8 {.a @ @ e ` ` J.J.1+ ",
+" 2 2 2 2 '.2 '.'.U F F }+$+/.-.f -.%+k / F.E j+o o O...5 5 5 V l+` 5+5+@ K.{.{.{.8 3+8 3+8 8 {.i.i.@ e 3 5+V V p. ",
+" x.'.U '.'.'.'.U F g+}+}+$+-.-.M (.(.z.E+b f+f+O.O.O.q q J.J.l+` 5+5+@ @ {.{.{.{.8 [.E.8 8 {.{.a @ @ 3 n+` % ",
+" x.U '.'.U U '.'.U }+j j /./.-.l -.(./ / P f+f+o O.q p+5 5 V V l+5+5+5+@ @ {.{.8 8 8 8 8 {.{.@ @ @ 5+n+3 V ! ",
+" . U 2 2 U 2 U '.F }+j /././.l M M k E+F.f+f+o o O.q q q J.V ` 5+e 5+a @ {.{.{.8 {.8 8 8 {.{.@ e 5+` V J. ",
+" 2 '.'.2 U F+U F }+K j /.-.-.l %+(.(.E+P f+o O.O.O.5 5 5 l+l+V 5+e 5+@ @ a {.{.{.{.{.a i.@ @ @ 5+3 V ",
+" . V.'.F+2 '.U F F r+$+/.-.-.(.(./ F.F.P f+f+O...O.q q q J.l+V l+5+5+5+@ @ @ {.@ @ i.@ @ e 5+3 l+J.1+ ",
+" . 2 2 F+U '.U }+j /././.-.-.M (./ F.E+F.E o o ....% J.5 J.l+5+` 5+5+5+5+@ @ a @ a @ e @ 3 5+` ! ",
+" . . 2 2 '.'.F F r+/././.l )+M (.F.j+j+E S.O.O.O...5 5 J.J.V V 5+5+e 5+5+@ @ 5+e @ 5+e ` V ) ",
+" V.x.'.'.U }+}+j $+/.-.f l %+(.k F.b j+f+f+O.O.p+6+% 5 J.V n+` ` 5+5+3 5+5+e 5+n+` V V ! ",
+" . #.'.'.U F }+r+/.-.-.-.(.(.k / F.P f+f+O.O.O.3.6+% Q.% J.V V ` n+` ` 3 3 3 5+` V 1+ ",
+" 2 U F }+}+j $+/.-.-.-.M (.F.F.E+P E o O.......p+% Q.5 5 J.J.V V V l+V V V V ",
+" . F+F }+}+r+$+-.-.l M (.(.F.F.P b E f+O.O.......% 5 5 5 J.J.V J.J.J.% 1+ ",
+" U F }+j K /.f -.-.-.(.k F.F.P F.E E o O.O.6+q 6+% 5 5 5 5 J.5 % ",
+" H.}+}+r+/./.f )+M (.(./ F.P j+f+E f+o o O...k+6+6+6+6+% 6+O. ",
+" U }+K -.-.-.M M k (.F.F.P E E S.O.o O...O.....E ",
+" t+* /.f -.l M (.F.k E+E j+E E E f+O.%.P ",
+" -.-.M )+(./ k F.F.F.E E "};
diff --git a/arts/builder/pics/Synth_MOOG_VCF.xpm b/arts/builder/pics/Synth_MOOG_VCF.xpm
new file mode 100644
index 00000000..7f9662c3
--- /dev/null
+++ b/arts/builder/pics/Synth_MOOG_VCF.xpm
@@ -0,0 +1,305 @@
+/* XPM */
+static char * Synth_MOOG_xpm[] = {
+"64 64 238 2",
+" c None",
+". c #161E54",
+"+ c #4A962C",
+"@ c #3A5A6C",
+"# c #2E4254",
+"$ c #5ACA1C",
+"% c #3A4E74",
+"& c #6A7694",
+"* c #52AE24",
+"= c #3A427C",
+"- c #222E64",
+"; c #66E614",
+"> c #4E6E7C",
+", c #263664",
+"' c #464E8C",
+") c #4E5A9C",
+"! c #32466C",
+"~ c #7E86AC",
+"{ c #8692B4",
+"] c #5EDA14",
+"^ c #6EF614",
+"/ c #4E629C",
+"( c #2E3E74",
+"_ c #56BE1C",
+": c #3A4A74",
+"< c #2E3674",
+"[ c #3E4E84",
+"} c #767EA4",
+"| c #62D21C",
+"1 c #7EFE1C",
+"2 c #222E74",
+"3 c #46568C",
+"4 c #969ECC",
+"5 c #323E84",
+"6 c #1A2664",
+"7 c #6A76BC",
+"8 c #5AB62C",
+"9 c #72FE14",
+"0 c #5A62AC",
+"a c #4EA22C",
+"b c #5E6AB4",
+"c c #565EA4",
+"d c #868EB4",
+"e c #8E9ABC",
+"f c #3A467C",
+"g c #2A3674",
+"h c #4E5E94",
+"i c #5AC61C",
+"j c #3A4A8C",
+"k c #425684",
+"l c #7276A4",
+"m c #5AAE2C",
+"n c #5662A4",
+"o c #36427C",
+"p c #2E367C",
+"q c #425284",
+"r c #66D224",
+"s c #222A64",
+"t c #465A8C",
+"u c #2A3E64",
+"v c #62CA2C",
+"w c #3A5674",
+"x c #52B21C",
+"y c #223264",
+"z c #6AEE14",
+"A c #2A3A64",
+"B c #46528C",
+"C c #7E8AA4",
+"D c #8E92C4",
+"E c #62E214",
+"F c #76FA14",
+"G c #324274",
+"H c #2A3274",
+"I c #4E5694",
+"J c #3E4E74",
+"K c #36467C",
+"L c #5EC22C",
+"M c #324284",
+"N c #4EAA24",
+"O c #6672BC",
+"P c #3A468C",
+"Q c #32426C",
+"R c #162254",
+"S c #4E9E2C",
+"T c #6E76A4",
+"U c #6EE624",
+"V c #4E727C",
+"W c #2A3664",
+"X c #4E5AA4",
+"Y c #66DA24",
+"Z c #6EFA14",
+"` c #52669C",
+" . c #323E74",
+".. c #5AC21C",
+"+. c #3A4A84",
+"@. c #424E94",
+"#. c #7E82B4",
+"$. c #5ED614",
+"%. c #263274",
+"&. c #4A569C",
+"*. c #1E2A6C",
+"=. c #7AFE14",
+"-. c #666EB4",
+";. c #525EA4",
+">. c #424A94",
+",. c #2E3A7C",
+"'. c #4A5A9C",
+"). c #2E426C",
+"!. c #46529C",
+"~. c #7E8AB4",
+"{. c #4A9A2C",
+"]. c #5ECE1C",
+"^. c #365264",
+"/. c #6E7694",
+"(. c #56AE2C",
+"_. c #3A428C",
+":. c #262E6C",
+"<. c #364A74",
+"[. c #8A96BC",
+"}. c #62DE14",
+"|. c #5ABE2C",
+"1. c #2E3A6C",
+"2. c #424E8C",
+"3. c #7A82AC",
+"4. c #86FE1C",
+"5. c #4A5694",
+"6. c #9AA2CC",
+"7. c #1E2664",
+"8. c #6E7ABC",
+"9. c #3E626C",
+"0. c #56BA1C",
+"a. c #62CE24",
+"b. c #6AEA14",
+"c. c #5A66AC",
+"d. c #626EB4",
+"e. c #727AA4",
+"f. c #6EF214",
+"g. c #56AA2C",
+"h. c #4EA624",
+"i. c #5666A4",
+"j. c #8E96BC",
+"k. c #3E5274",
+"l. c #6EEA24",
+"m. c #526E8C",
+"n. c #5EC62C",
+"o. c #1A2264",
+"p. c #52728C",
+"q. c #62D624",
+"r. c #3A5274",
+"s. c #425294",
+"t. c #222A74",
+"u. c #56BA2C",
+"v. c #525A94",
+"w. c #8A92BC",
+"x. c #8A8EBC",
+"y. c #929AC4",
+"z. c #3E4684",
+"A. c #525E9C",
+"B. c #3E4A8C",
+"C. c #6AD224",
+"D. c #4A5A8C",
+"E. c #2E3E64",
+"F. c #56B224",
+"G. c #263264",
+"H. c #364284",
+"I. c #1A225C",
+"J. c #62D61C",
+"K. c #323A84",
+"L. c #5ECA1C",
+"M. c #36466C",
+"N. c #62DA14",
+"O. c #72F614",
+"P. c #52629C",
+"Q. c #5ABE1C",
+"R. c #82FE1C",
+"S. c #262E74",
+"T. c #9A9ECC",
+"U. c #363E84",
+"V. c #76FE14",
+"W. c #626AB4",
+"X. c #5EC61C",
+"Y. c #66E214",
+"Z. c #3E468C",
+"`. c #525AA4",
+" + c #72FA14",
+".+ c #3E4A84",
+"++ c #4A529C",
+"@+ c #828AB4",
+"#+ c #4E9A2C",
+"$+ c #66CE24",
+"%+ c #5E66AC",
+"&+ c #767AA4",
+"*+ c #52AE2C",
+"=+ c #3A4284",
+"-+ c #222E6C",
+";+ c #26366C",
+">+ c #464E94",
+",+ c #7E86B4",
+"'+ c #2E3E7C",
+")+ c #3A4A7C",
+"!+ c #3E4E8C",
+"~+ c #767EAC",
+"{+ c #465694",
+"]+ c #868EBC",
+"^+ c #8E9AC4",
+"/+ c #3A4684",
+"(+ c #2A367C",
+"_+ c #4E5E9C",
+":+ c #5662AC",
+"<+ c #42528C",
+"[+ c #66D22C",
+"}+ c #222A6C",
+"|+ c #52B224",
+"1+ c #2A3A6C",
+"2+ c #465294",
+"3+ c #7E8AAC",
+"4+ c #76FA1C",
+"5+ c #32427C",
+"6+ c #2A327C",
+"7+ c #4E569C",
+"8+ c #364684",
+"9+ c #2A366C",
+"0+ c #5266A4",
+"a+ c #323E7C",
+"b+ c #26327C",
+"c+ c #7AFE1C",
+"d+ c #2E3A84",
+"e+ c #6E769C",
+"f+ c #2E3A74",
+"g+ c #1E266C",
+"h+ c #6E7AC4",
+"i+ c #4EA62C",
+"j+ c #8E96C4",
+"k+ c #3E4A94",
+"l+ c #4A5A94",
+"m+ c #2E3E6C",
+"n+ c #26326C",
+"o+ c #36428C",
+" %.H H 6+6+%.S.2 t.}+*.7. ",
+" s f+H.H.K.d+,.(+b+S.%.S.2 2 }+2 o.. . . ",
+" < .+>.Z._.H.5 d+p p (+b+%.S.t.2 *.*.*.g+o.o.. . ",
+" 1.) 7+5.>+>.P o+U.K.d+,.(+b+S.2 2 2 t.2 2 t.*.*.6 o.. . . . ",
+" v.c ;.7+++@.k+P o+M K.p (+(+(+6+%.S.2 t.*.*.*.*.t.*.*.g+g+o.. . ",
+" I W.%+:+`.7+2+@.>.Z.o+U.5 d+p 6+%.%.S.2 -+2 t.t.t.g+*.*.g+*.g+*.o.. . . ",
+" d.d.b 0 c X &.>+>.Z.P o+5 K.d+p 6+b+b+S.S.t.-+*.*.t.g+*.*.g+*.g+*.g+6 o.. . ",
+" ' 7 O W.c.:+;.X &.!.k+j _.U.K.'+,.(+(+H %.%.2 2 t.2 t.*.t.g+g+*.g+*.g+g+g+g+o.. . . ",
+" = T O O W.c.n `.&.++>+>.Z.P H.K.d+,.(+b+b+S.2 S.2 t.-+t.*.*.*.g+*.g+g+6 g+g+6 g+o.. . . ",
+" I 8.O O W.c.0 ;.) &.2+@.B.P o+U.5 p (+6+6+S.b+S.2 }+t.*.*.*.*.*.*.g+*.*.*.g+*.*.g+*.o.. . . ",
+" = T 7 -.d.b c.c `.7+!.@.k+Z._.o+5 5 d+p g 6+S.S.2 2 -+t.2 t.*.*.g+t.g+g+g+*.6 g+*.6 g+6 o.. . . ",
+" ' 7 O O -.b c.c ;.X &.!.@.k+P H.5 5 ,.p (+6+%.%.%.S.2 *.t.*.*.g+g+*.g+*.*.g+g+g+6 g+g+*.g+g+o.. . . ",
+" O 7 -.d.%+c.:+;.X &.!.>+>.B.P o+5 K.,.,.(+(+b+2 2 2 2 2 *.*.*.t.*.*.g+g+*.*.*.*.g+*.g+6 g+6 6 o.. . ",
+" O O -.6.T.c.0 ;.X &.++>+!+B._.o+U.K.d+d+(+(+%.S.S.S.t.t.*.t.t.t.*.t.*.*.*.*.*.*.*.*.*.*.*.*.g+g+*.o.. . ",
+" .+-.-.W.4 4 c ;.`.7+!.>+>.Z.P _.H.U.K.p (+6+6+%.%.2 S.:.2 2 2 2 2 *.2 2 2 2 *.t.t.2 t.2 2 t.2 *.*.*.*.6 o.. ",
+" W.W.c.c.:+;.;.`.&.++!.@.>.j P H.U.5 ,.,.(+(+%.b+S.S.2 2 t.t.*.-+t.2 2 2 2 2 2 2 2 2 -+}+}+-+}+2 }+t.}+*.. . ",
+" I c.0 :+:+c X X 7+{+>+@.k+Z.P _.5 5 K.p p (+6+%.b+%.2 2 S.2 %.2 %.S.2 2 2 S.%.%.%.:.%.%.%.2 %.-+2 -+-+t.-+*.6 . ",
+" U.0 c :+Z.`.j+j+&.!.>+@.k+k+P _.5 U.,.,.,.(+%.%.%.S.2 %.S.%.%.S.S.2 %.%.%.%.%.S.%.%.%.%.%.S.%.S.%.n+S.2 :.2 }+}+I.. ",
+" ' ;.X ) /+&.D w.!.@.>.k+P _.o+o+5 K.d+(+(+(+6+b+%.%.S.%.%.%.%.%.H %.H %.H %.g %.%.(+%.%.;+%.;+%.%.%.n+%.:.%.n+-+}+6 ",
+" X 7+7+7+_.++{ ]+@.>.k+Z._.o+U.5 K.d+p p 6+6+%.H b+H %.%.%.%.%.b+b+%.%.9+;+).%.(+g H (+(+H (+6+H 6+;+H %.%.S.S.S.y I. ",
+" W ++!.!.>+U.>+]+@+k+Z._.P =+U.K.'+K.,.(+(+H 6+%.%.b+(+H 6+6+(+g g (+H , h.].u.W g ,.g (+,.g 1+(+g (+(+g g ;+%.%.S.H -+6 ",
+" >+s.>+@.@.!+k+Z.Z.P 8+=+U.5 5 a+d+,.(+(+H b+;+6+6+%.%.(+%.(+H (+(+g A * +9 ^ h.g (+,.,.(+,.p ,.,.< g g (+g g g g n+- . ",
+" 7.>.k+k+k+Z.Z.Z.Z._._.o+U.5 5 K.p (+p (+6+g 6+b+H (+(+%.(+H (+(+g (+, * ^ Z J.^ ].A f+,.a+,.'+,.f+,.,.,.< p < g g g H 9+n+7. ",
+" K.P Z.Z._.P d+8+,+,+U.5 5 5 d+p ,.p 6+6+;+b+%.H (+(+H (+(+,.,.(+,.A * ^ ^ g.# ].^ i+1+'+,.a+K.'+,.'+,.,.,.f+,.(+< g g H :.. ",
+" .o+o+_._.U.p o+,+,+5 K.K.p d+p (+(+H 6+6+6+(+%.6+(+(+(+(+(+,.(+A F.O.Z * u 1+i+^ ].1.a+a+a+a+5 a+a+a+'+'+,.f+,.p < g g H G. ",
+" U.H.U.M 5 5 H K.#.3.d+,.(+,.(+6+(+%.b+%.%.(+%.(+(+g p ,.p ,.,.u *+^ Z *+u '+a+E.$ f.i+).5 M U.5+5 5 a+5 a+a+a+f+'+,.f+g 9+H ",
+"%.5 5 K.5 5 d+%.,.~+3.,.p (+(+(+%.6+%.b+H %.(+g (+(+(+g ,.,.,.^.n. +O.*+m+5 5 M G h.f.L.).a+M H.o o M o 5 a+5 a+,.'+,.,.,.1+1+g ",
+"H d+d+d+p d+,.,.d+,.p (+(+6+H %.6+%.%.%.(+6+6+(+g (+,.,.,.1+u L +O.|+E.a+U.H.H.H.m+$ z a o /+H.H.H.H.H.o M o M 5+a+a+a+,.,.p g ",
+"H p p d+p p p (+6+6+6+(+b+b+%.S.S.S.S.%.%.;+6+(+,.g 1+1+A N | + +*+m+5 H.8+H.H.8+o h.z $ ).K 8+8+/+8+8+H.H.o U.a+a+a+a+K.f+f+< ",
+"6+(+(+6+(+(+6+-+(+} e.n+;+, n+;+;+;+;+n+;+9+9+9+;+A g.a.| 4+V. +*+m+5+8+8+H.8+8+/+8+Q $ b.a o P P /+/+/+/+8+H.K H.o a+ .a+a+,.1+",
+"6+6+(+b+b+(+b+}+b+~+& m C.C.r $+$+$+r r $+a.$+a.a.J.O.c+V.V.U L E.U.H.H.8+_./+8+P P f h.z L.! +.j P /+/+/+/+H.8+H.H.M 5+a+a+K.,.",
+"S.%.S.%.%.S.%.}+%.&+& C.4.4.4.R.R.R.1 1 1 1 =.=.=.c+V.l.U [+@ r.H.8+H.8+P +.P B.B..+/+! i b.a f B.+.j j +.j +./+8+8+o U.5+a+a+f+",
+"S.b+S.S.b+S.%.}+2 e.& g.r $+r C.r $+$+a.a.a.a.a.].v |.9.r.r.M M H.8+P 8+P j +.j !+!+B.)+a b.i M.B.!+!+B.+.Z.+./+/+/+8+o o 5+5+a+",
+"2 2 S.S.2 2 2 2 2 t.t.y y y - - - , , , W A 1+1+1.m+m+'+5+5 M 8+8+P /+j +.B.B.!+B.B.!+>.M.i ; a % 2.B.!+B.[ B.+./+8+8+H.o U.U.,.",
+"t.2 2 2 S.t.t.2 S.2 t.}+t.-+-+-+-+2 %.;+(+g (+,.,.K.a+5 H.H.H.o+/+P P P j j B.!+!+2.<+<+)+a ; ..<.2.!+2.B.B.!+B..+z.+.8+8+o o a+",
+"}+2 2 t.t.S.2 *.-+l e.*.-+t.*.2 S.%.H 6+6+(+,.(+,.'+5 a+M H.=+/+8++.B.B.B.!+!+!+s.s.@.<+<+% i ; S [ <+<+<+2.>.[ B.+./+/+f H.o a+",
+"g+}+-+-+*.t.}+g+}+T e.*.*.t.}+2 2 2 %.;+(+(+,.,.'+K.M a+H.8+8+P P j +.!+!+2.@.2.<+<+s.2+2+[ a ; ..: 2.s.<+<+!+[ B.B.j /+/+8+K o ",
+"*.*.t.*.t.*.*.g+*.l l *.*.*.2 -+S.%.b+6+g (+,.,.K.a+a+H.H.H._.+.+.j !+!+@.!+<+s.s.{+2+{+3 3 % ..E S q s.<+<+<+2.!+[ .++.+./+=+a+",
+" *.t.*.t.t.*.*.*.T l t.}+*.t.-+S.%.;+(+g (+,.,.'+5 5 M H.8+P P Z.B.B.!+s.@.<+2+s.{+{+{+5.5.q a E _ J {+2+B s.<+!+!+B.+./+8+/+ ",
+" *.*.*.*.*.*.g+t.}+*.g+*.}+-+2 2 S.H H p ,.,.'+5 a+H.H.8+8+8++.j B.!+!+2.<+2+s.{+{+{+{+'.t {+k...E S q {+s.<+' 2.2.!+.+.+/+K ",
+" . g+*.g+t.*.*.*.g+*.g+*.*.2 S.%.%.(+;+(+,.,.,.5 a+H.H.=+P P +.!+B.@.s.s.<+{+{+5.5.'.5.'.'.) t 8 E _ % 3 {+{+2+<+2.!+!+.+/+ . ",
+" I.*.*.*.*.*.6 g+l T *.g+t.}+-+S.S.%.(+(+(+,.a+a+M M H.8+/++.B.j !+!+2.<+2+{+5.{+'.t _+) _+l+l+> Y }.S k 5.{+k <+<+2..+.+f - ",
+" o.*.g+g+g+6 *.l T *.g+*.2 2 %.%.%.g ,.p ,.'+a+U.H.H.8+P j B.!+2.!+s.s.2+2+5.t '.'.l+_+_+_+_+m.v E 0.J {+5.2+<+2.2.!++.z. ",
+" o.g+*.*.*.g+g+e+l g+*.t.*.-+2 S.H (+g ,.,.K.5 5+M 8+_./+/+B.B.!+s.2.3 {+{+'.&.) '._+_+A.P._+h V J.N.S q {+{+2+<+<+[ [ G. ",
+" o.g+g+*.6 *.e+T g+*.}+t.:.%.%.H (+g ,.'+K.a+H.H.8+/+j +.B.!+2.s.s.2+{+{+l+l+h _+_+/ _+P.P.A.m.v }.0.J 3 {+{+<+2.2.2. ",
+" 6 *.*.6 *.g+g+6 *.*.*.-+2 2 b+;+H ,.,.,.'+5 a+H.H.8+/+j !+B.!+2.<+{+{+{+l+'.'._+_+_+P.P.P.P.P.V | ] {.q 3 <+<+<+[ = ",
+" . o.g+g+g+6 *.6 g+*.}+-+S.n+%.(+%.g ,.,.,.5 a+H.8+/+/+P !+!+<+@.<+<+{+{+l+) l+_+A.P.0+0+0+i.P.m.n.}.0.J {+2+B 2.[ z. ",
+" g+*.g+6 g+T l 6 g+*.*.-+2 %.%.(+(+< a+a+a+M H.H.H.P +..+>.!+<+s.{+{+&.t '.h _+/ / P.P.i.P.P._+> L.$.{.q 3 <+<+: ",
+" o.g+g+g+T l *.g+}+2 :.S.%.%.g ,.(+,.a+a+5+H.8+8+P j +.B.2.2.@.B {+5.l+'.l+_+A./ P.P.0+P.P._+h {.F.+ q s.B 2. ",
+" o.6 6 7.e+e+e+l *.*.l e.&+~+;+g 3.3.3.#.5 H.,+~ @+@+B.!+d { w.{ {+{+w.j.j.j._+A.y.^+y.^+_+h [.C C ~ <+3 <+W ",
+" o.g+g+T T e+l }+-+e.e.} &+b+g } 3.~ ~ a+o @+3+~ @+B.B.@+d ]+d 2+{+w.[.[.[._+_+e e e ^+_+) e [.[.w.B B 2. ",
+" 6 6 o.g+6 *.*.*.}+n+S.%.g (+,.1+,.'+5+U.H.H./+/+/+j 2.!+<+s.{+{+{+'.l+) '.h _+_+_+h h h ) l+3 5.3 q ",
+" . o.6 g+o.6 g+*.g+*.-+}+;+(+S.n+H H a+a+1+,.f+,..+j a+a+5+a+<+3 o H.K 8+'.) /+/+/+/+l+l+f f {+2+2.z. ",
+" . g+6 6 g+*.}+-+:.S.%.H %.g (+,.,.'+5 U.H.8+/++..+.+!+2.<+<+s.2+{+{+5.5.l+l+) ) l+l+5.{+{+3 q W ",
+" . I.7.7.*.*.*.-+:.%.g g < g f+a+a+5+a+H.8+H.8+j .+B.B.2.2.<+B B 3 {+{+{+t t l+5.{+{+B 2+<+f ",
+" . 6 6 7.g+-+}+2 :.%.H g p ,.,.'+a+M a+H.8+/+/+P .+[ !+<+<+<+s.2+3 3 5.5.5.{+{+3 3 {+q W ",
+" . o.*.7.*.-+2 :.%.%.;+(+g f+,.a+5+5+H.H.8+/++.j B..+B.2.<+<+s.B <+s.<+B {+{+B <+<+z. ",
+" o.*.}+}+-+-+%.%.g g ,.p f+K.a+U.o o =+8+8+z.+.B.!+!+2.!+2.<+s.B 2+<+<+<+<+' ",
+" R *.*.-+-+%.S.H H g ,.f+,.( a+M 5+o /+8+/++.+..+.+[ !+!+2.!+<+<+2.2.2.)+ ",
+" *.}+}+:.n+%.;+g g ,.f+K.'+a+a+H.H.H./+8+/+P +.B.[ B.[ 2.!+2.!+[ ",
+" 7.*.:.n+%.H %.g < f+K. .a+a+a+o H./+/+/++.+.z..+.++..+.+.+f ",
+" *.:.%.g g g g f+,.a+a+5+o 5+o o 8+/+/++.+.+..+o ",
+" s s ;+g g < f+,.,.'+a+a+H.o o o H./+U.G ",
+" H g g f+f+f+K.a+a+a+U.o "};
diff --git a/arts/builder/pics/Synth_MUL.xpm b/arts/builder/pics/Synth_MUL.xpm
new file mode 100644
index 00000000..9261785e
--- /dev/null
+++ b/arts/builder/pics/Synth_MUL.xpm
@@ -0,0 +1,309 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 238 2",
+/* colors */
+" c #A3A8C1",
+" . c #354280",
+" X c #4E5688",
+" o c #A0A4BE",
+" O c #2F3C7A",
+" + c #1B2463",
+" @ c #3A4888",
+" # c #3E4982",
+" $ c #293474",
+" % c #CDD0E0",
+" & c #626B98",
+" * c #38437C",
+" = c #232E6E",
+" - c #4A5487",
+" ; c #C1C4D4",
+" : c #1C2667",
+" > c #2F3973",
+" , c #3E4B85",
+" < c #2A3678",
+" 1 c #253073",
+" 2 c #35417C",
+" 3 c #202A6E",
+" 4 c #2F3A80",
+" 5 c #1E286C",
+" 6 c #455085",
+" 7 c #1C266A",
+" 8 c #AAAFC7",
+" 9 c #29347A",
+" 0 c #263077",
+" q c #253076",
+" w c #374581",
+" e c #475594",
+" r c #232E74",
+" t c #323F7C",
+" y c #313D7B",
+" u c #576393",
+" i c #3D4B8A",
+" p c #2B3775",
+" a c #BBC0D4",
+" s c #3A4787",
+" d c #4B579B",
+" f c #5C67AF",
+" g c #394786",
+" h c #263170",
+" j c #354382",
+" k c #242F6E",
+" l c #445194",
+" z c #6872B4",
+" x c #38447E",
+" c c #343F84",
+" v c #1D276A",
+" b c #2D377D",
+" n c #C0C3D5",
+" m c #434D82",
+" M c #283378",
+" N c #3A4883",
+" B c #273177",
+" V c #263176",
+" C c #525A8A",
+" Z c #252F75",
+" A c #242F74",
+" S c #455491",
+" D c #35427E",
+" F c #212B71",
+" G c #202B70",
+" H c #6C76AA",
+" J c #404E8C",
+" K c #616CB3",
+" L c #2D3876",
+" P c #555E90",
+" I c #2B3674",
+" U c #3A4886",
+" Y c #374483",
+" T c #A1A6C0",
+" R c #232E6C",
+" E c #313E7D",
+" W c #2D3A79",
+" Q c #3E4A8D",
+" ! c #2A3676",
+" ~ c #384487",
+" ^ c #273273",
+" / c #253071",
+" ( c #414C93",
+" ) c #43518B",
+" _ c #1E286A",
+" ` c #1C2668",
+" ' c #1B2667",
+" ] c #2B367A",
+" [ c #4B5B96",
+" { c #273276",
+" } c #242E73",
+" | c #222C71",
+". c #455390",
+".. c #212C70",
+".X c #202A6F",
+".o c #1F2A6E",
+".O c #1E286D",
+".+ c #3F4D8A",
+".@ c #2F3B77",
+".# c #3E4D89",
+".$ c #3E4B89",
+".% c #4C599A",
+".& c #384583",
+".* c #283370",
+".= c #3C467D",
+".- c #555FA6",
+".; c #424F90",
+".: c #212B69",
+".> c #3F4D8D",
+"., c #3E4D8C",
+".< c #333C74",
+".1 c #2D3978",
+".2 c #4F59A0",
+".3 c #6E759A",
+".4 c #2C3777",
+".5 c #2B3776",
+".6 c #485399",
+".7 c None",
+".8 c #263171",
+".9 c #DCDEE8",
+".0 c #212B6C",
+".q c #313B7F",
+".w c #9A9FBB",
+".e c #3F4B90",
+".r c #283376",
+".t c #4A5A94",
+".y c #263174",
+".u c #394680",
+".i c #354186",
+".p c #182059",
+".a c #232D71",
+".s c #45548F",
+".d c #323D83",
+".f c #7279A4",
+".g c #2E397F",
+".h c #C1C5D7",
+".j c #1D276B",
+".k c #404E8A",
+".l c #3E4C88",
+".z c #2A357B",
+".x c #29357A",
+".c c #9399B7",
+".v c #283379",
+".b c #3B4885",
+".n c #263177",
+".m c #475694",
+".M c #5862A8",
+".N c #777EA2",
+".B c #435290",
+".V c #33407D",
+".C c #435090",
+".Z c #41508E",
+".A c #3E4C8B",
+".S c #3C4A89",
+".D c #2B3675",
+".F c #293473",
+".G c #384685",
+".H c #8E95B5",
+".J c #273271",
+".K c #B7BBD0",
+".L c #CBCEDD",
+".P c #354282",
+".I c #1F2A69",
+".U c #1E2868",
+".Y c #3D488D",
+".T c #384288",
+".R c #4A5993",
+".E c #C6CADB",
+".W c #353F7B",
+".Q c #B0B5CC",
+".! c #AEB3CA",
+".~ c #414F8A",
+".^ c #1C2669",
+"./ c #2B367B",
+".( c #8087AA",
+".) c #293479",
+"._ c #283278",
+".` c #2B3571",
+".' c #273277",
+".] c #4A5996",
+".[ c #263076",
+".{ c #253075",
+".} c #7B81A5",
+".| c #242E74",
+"X c #232E73",
+"X. c #465592",
+"XX c #222C72",
+"Xo c #212C71",
+"XO c #445390",
+"X+ c #202A70",
+"X@ c #1F2A6F",
+"X# c #42518E",
+"X$ c #495181",
+"X% c #2F3B78",
+"X& c #3C4988",
+"X* c #D0D3E1",
+"X= c #A6ABC5",
+"X- c #4E5C93",
+"X; c #4C5A91",
+"X: c #344180",
+"X> c #323F7E",
+"X, c #222D6B",
+"X< c #2E3B7A",
+"X1 c #6C7399",
+"X2 c #293575",
+"X3 c #B3B8CE",
+"X4 c #222D6E",
+"X5 c #434D95",
+"X6 c #878EB0",
+"X7 c #20296C",
+"X8 c #5C6693",
+"X9 c #333E78",
+"X0 c #2F3B7E",
+"Xq c #1E296A",
+"Xw c #1D2769",
+"Xe c #2C377B",
+"Xr c #3B458D",
+"Xt c #293378",
+"Xy c #495894",
+"Xu c #485893",
+"Xi c #242F73",
+"Xp c #353F87",
+"Xa c #475692",
+"Xs c #232D72",
+"Xd c #222D71",
+"Xf c #455490",
+"Xg c #212B70",
+"Xh c #202B6F",
+"Xj c #43528E",
+"Xk c #C3C7DA",
+"Xl c #1F296E",
+"Xz c #42508D",
+"Xx c #1E296D",
+"Xc c #41508C",
+"Xv c #D4D6E4",
+"Xb c #4E5C9C",
+"Xn c #E6E7EF",
+"Xm c #3A4885",
+/* pixels */
+".7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7 1 {XtXt._ 0 Z r F 3Xq :.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7 I y.TXp.d 4 b.z 9 B q ZXsXXXo GX+Xl + +.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7X&X5 (.Y.TXp.d 4 b.z 9 B q ZXsXXXo G.XX@XlXl 5 +.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7 x.2.2.6X5 (Xr.TXp.d 4 b.z.v B q.|XsXXXo G.XX@XlXx.O.O 5.^ +.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.M.M.-.2.6X5.eXr.TXp.d 4 b.z.v B q.|XsXX F G.X.oXlXx.O 5 5 5.j `.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.7.7.7.7.% K f.-.2 d.6X5.eXr.TXp.d.g b.z.v.n.{.|XsXX F G.XXlXlXx.O 5 5.j.j.j.^ +.7.7.7.7.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.7.7.7 z K f.M.-.2 d.6 (.YXr.T c.d.g b.z._.n Z.|Xs |XgX+.XXlXlXx.O 5 5.j.j.j v v '.7.7.7.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.7 ) z z K f.M.-.2.6 l (.YXr.T.d 4.g./ 9._.[ ZX XsXoXg.XX@XlXl.O 5 5 5.j.j v v v v `.p.7.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7X; z z K K f.-.2 d.6X5.eXr.TXp.d 4 b.z 9.'.[ AX XsXoXg.X.oXlXx.O 5 5.j.j.j v v vXw.^ :.p.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7X- z z z K f.M.-.2 d.6X5.eXr.T c.d 4 b.z.v B q.|XsXX F G.X.oXlXx.O 5 5.j.j.j v v vXw.^.^ :.p.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7X; z z z K f.M.-.2.2.6X5 (.YXr.i c 4.gXe 9._.n Z.|Xs |XgXh.XXlXlXx 5 5.j.j.j v v vXw.^.^.^ ` :.p.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7 ) z z z K f.M.-.-.%.6 l (.YXr.TXp.d 4 b./ 9.'.[ ZX XsXoXg.X.oXlXl.O 5 5 5 v.^.^ ` `.^ ` `.^ ` ` :.p.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7 z z z K f.M.M.-.MXb e.;.eXrXr.T c.d.g b.z.v B.{ AXsXXXo G.X.oXlXlXxXx 5 5.j _.U.U.UXwXw.^ `Xw ` ` :.7.7.7.7.7.7.7",
+".7.7.7.7.7.7 z z K K f.M.M.M &.} H &Xa.$ ~.T c.d 4 b./ 9._ V Z }Xs |Xg G.X.X 3 3 3 3X7Xq.: R.`.<.*.:.U.U v _ _XwXw +.7.7.7.7.7.7",
+".7.7.7.7.7.% K K K f.M.-.- H.(X=.w.H & 6.& c.d.d.g b.zXt.'.[ AX Xs |.................0.0.* *X$X8.=.*.:.IXqXqXqXqXq.U.p.7.7.7.7.7",
+".7.7.7.7.7 K f f f.M.-.2.- HX6X3.Q.Q.(X8 m.V.q.g b./ 9._ V Z.|X XsXsXdXdXd.a.a.aX4X4 R.`.= &.N.HX8.=.*X,.0.0.0.0X7Xq.U.7.7.7.7.7",
+".7.7.7.7.M f.M.M.-.-.2.2Xb H.cXk %Xv.Q.H P x O b ].zXt B.[ Z.| } } }XiXiXiXiXiXi.a k.` mX1 X3XkX6X8.< RX,X4X4X4.0.0.0.U.7.7.7.7",
+".7.7.7 x.M.-.-.-.2.2 d.6XyXb.f T aXv.h.!.} C.= LXt M B V.[.{ Z Z 1 1 1 1 1.y 1 / h >X$X1.H a.KX3.NX$ > k k.a / k =X4X4.0 +.7.7.7",
+".7.7.7.2.-.2.2.2 d d.6 l.C.C u.(X=X*XvXv 8X6 CX9 I { V B V V.y.y.y.y.y { { { ^.J > m.3X= n.9 nX= &.=.` h h /.8 / / k = R.:.7.7.7",
+".7.7.7.2.2 d d.6.6.6X5 (.e Q ) P.NX= aXv aX=.f -.<.J.y V V { { {.'.'.r.r { $.`.<X$.3.c ; ; ;.HX1X$ >.*.J.J $ ^.J.8 / / k =.7.7.7",
+".7.7X&.6.6.6.6 lX5X5 (.eXrXr ~.b P.( X*X*Xv .}X$ >.J { { {.r M MXt.)XtX2 $.<X$.3 8.h.9 ; 8X1 m.<.`.FX2X2X2X2 $.F.J.J h k.U.7.7",
+".7.7X5X5X5X5 ( (.e.e.YXr.T.T cX:.= X.f T.KX*.K .3X$.<.J ^.r M.x.x < ! ! I.<X$.N.c.h.h ;.c.3X$.< > p.5.4.4.4.4 !X2 $.F.J.8 k.7.7",
+".7 I ( (.e.e.Y.YXrXrXr.T.TXp.d.qX0.W X.} TX*X*X* o.NX$ >.FX2Xt.x.x <.4.D.< -.N.!Xk.9 ; 8.3X$.< L.1 W.1 W.1.1.1.4 ! !X2.F.J.J.:.7",
+".7 y.YXrXrXrXrXr.T.T.iXp c.d 4.gXe.1.WX$.3 o.KX*.K oX1X$.< I ! ].4 < >X9 X.N.wXk.h ;.c.3X$X9.@.1 O O OX0 OX< W.1.1.4 !X2 $.F.:.7",
+".7.T.T.T.T.T.T.TXp c c.d.d 4.g b.z.) I >X$.N TX*X* % o.NX$.< p ].4 L.W X.N.Q.E.9 nX=.3X$ * O O E E E E E E y O O W.1.4.5.DX2.*.7",
+".7XpXpXpXpXp c.d.d.d 4 4.g b b./ 9 M ^.J.<X$.3 T.KX*.K oX1X$.W.@.< * C.N.w.EXk n.c.3X$ *X9 EX>X>X:X:X>X>X> E y y OX< W.1 L.DX2.7",
+" 1.d.d.d.d.d.d 4 4 4.g b b./.z 9Xt._ V.y.J >X$.} TX*X* % o.f X * m C.}X3.E.9.hX=.3X$.=.VX>.PX:.P.P .X:X:X:X>X> E y O O W.1 L p.*",
+" { 4 4 4 4.g.g.g b bXe./.z 9Xt._ B V.[.y ^.J.<X$.3 .KX*.K o.NX8.3.( .EXk n.c.3 X.= 2X: j Y Y Y Y Y j.P .X:X:X>X> E y OX%.1 L I",
+"Xt b b b b b b./.z.z 9 9.v._.' V.[.[ V V { {.F >X$.} XvXvX*.K T.QXkX*.9 nX=.3 -.= . j Y.G.G.G.G.G.G.& Y Y j .X:X:X> E y OX%.1 p",
+"Xt.z.z.z.z.z.z 9 9.v._.' B V.[ Z Z.{ V { {.r $ I.< -.N.! ;Xv.L.h.LXv.L.E.c.3 X.= x Y.G s s s s g g g g.G.&.& Y j .X:.VX> y OX% L",
+"._ 9 9.v.v.v._._.' B.n.[.{ Z A.|.| Z.y {.r MXt ! p.< C.H.Q.9XnXnXn.9.E.Q.N X.= w.G g @.S.S.S.SX&X& @ @ s g.G.&.& j .X:.VX> E O.1",
+" 0 B B B B.n.n.[.[ q Z Z A }X X } Z.y { M.x.x ].D.@X$X6 8.9XnXnXnXnXkX=X1 6 # g s.S.S i i i i i i.S.SX&X& U g.G.& Y . D.VX> yX%",
+" Z q q q q.{ Z Z A.|.|X XsXsXsXs } 1.y.' M.x ] ].4 LX$.( 8.9XnXnXnXn n.w & m N @.S Q.A.A.,.,.,.A.A.A.A i.SX& @ U.G.& Y . D.V t O",
+" r Z Z.|.|.|.|X X XsXsXsXX | |Xs } 1.y.'Xt < <.4 >.=X8.w a.9.9XnXnXn.LX3.} P 6 ,.S.A.>.>.>.> J J J J.,.A.A i.SX& U g.& Y . D.V y",
+" FXsXsXsXsXsXsXsXsXX |XoXoXg..XdXi 1.y.r.).).4 p * C.( ;X*Xn.9X*.9XnXv %.w.f C.l.$ J.>.Z.Z.Z.Z.Z.Z.Z.Z J.,.+.A.$X&.b.G.& Y . D t",
+" 3XXXXXXXXXX |XoXo FXgXg G G..XdXi 1 { { !.1X9.=X8.( .LXk a TX6 oX3.hX*X3.w.3 C ).~.Z.Z.B.B.B.B.C.CX#.Z.Z J.+.$.$X&Xm.G.& w D t",
+"XqXoXoXo F FXgXgXg GXh.X.X.X..XdXi 1.y {.4.W -X1.H n.LXv.K.w.NX8.f.H.QXvX*.E.c.f C ) ).BXO S S SXOXOXOXjX#.Z J.+.$.$X&Xm.&.& . 2",
+" : G G G G GX+.X.X.X.X.o.o.X...aXi 1 ^.D * C.3.c.!.L nX3X6 & C m XX8.}.! a %.Q.c.3 P.s. . X. eX.X.X. SXO.B.CXzXc.+.$.S.bXm.& w 2",
+".7X+.X.X.X.X.XX@.o.oXlXlXl 3...aXs 1X2.W C.( T.E %Xv.Q.c & 6 #.&.u #X8X6.!Xv %Xk.c.f P.sXf.m.mXy.m.m.mX. SXOXjXz.~.+.lX&.b.& w.7",
+".7XlX@X@.oXlXlXlXlXlXlXlXl 3XhXd /.F * C.N .K % a.!.( & -.u w g N #X$X8.(X3.hX*.Q.c.3 PX;XuXu.].]XyXy.mX. SXOXjXc.k.#.l.bXm.u.7",
+".7 +XlXlXlXlXlXlXxXxXx.OXx 3Xh =.JX9 C.( .L %X*.!.HX8 m.u Y g @X&.S # mX8.w.K.9 %.h.c.f u.RXy.] [.].]Xy.mX. SXOX#Xc.+.lX&.bX9.7",
+".7 +XlXxXxXxXx.O.O.O 5 5 5XlX4 h.W C.NX=.K.L a 8.(X8 6 x w.G g.S.S i , , C.N.w.E.E.E 8.c.f uX-.t [ [ [.]Xu.mX.. XjXc.k.$X&.bX9.7",
+".7.7 5.O.O.O.O 5 5 5 5 5.jX7 k.< C.(X=.L.L %X=X6X8 # x . Y g @.S.A.A J J.sX8.(.Q n %Xk n.c.f u [ [.%.% [.]XuXa SXOX#.~.#.l N.7.7",
+".7.7 +.O 5 5 5 5 5 5 v.j.I R.< C.}X=.K.L.KX=.} u m 2 D j Y s.S i.A.> J.Z )X; &X6 .hXk.E 8.H.f uX- [ [ [ [XyXuX.XOXj.~.#.l 2.7.7",
+".7.7.7 5 5 5 5 5.j.j 7XwX, > CX6X= %.L.L .( P.= 2X>X: Y.G s.S i.,.>.Z.BXO. X; &X6.KXk %Xk a.H H uXb [Xb [.]XuXaXfXjXc.k.l.7.7.7",
+".7.7.7.^ 5.j.j.j.j.jXw.U > -.NX=.K.LX3 T.N C #X9 yX>.P Y.G s.S i.,.>.Z.BXO SXaX-X1.HX=XkXkXkX=.H.3 uX-Xb [.]XyXaXfXjXc.k ,.7.7.7",
+".7.7.7 +.j.j.j.j.j.j.UX,.=.f.w.E.E.E o.} C *X9 O EX:.P Y.G s.S i., J.Z.B S eXaXu u H.H aXk %.h.KX6 & u [ [ [XyXaXfXjXc.k.u.7.7.7",
+".7.7.7.7 `.j.j v v vXw.I.<X8.( 8 T.c.3 X *.@X% O EX:.P Y.G gX& i.A J.Z.B SX..mXuX; u.f.H 8Xk a.Q.( &X- [ [ [XyXaXfXjXc ,.7.7.7.7",
+".7.7.7.7.7.^ v v v vXw.U > X.3.c.(X1X$X9 L.1 WX0X>X:.P Y.G gX& i.A J.Z.CXOX..mXyXy.t u.f.H aX3 8.N uX- [ [.tXuXa.sXj.k.7.7.7.7.7",
+".7.7.7.7.7 + v v v v `Xw.: >.= XX$.=.< I.D.4 W y EX: . Y.G g @.S.A J.Z.CXOX..mXy.].]X- u.3X6.(.NX8X-X; [.].]XuX.. Xj.u.7.7.7.7.7",
+".7.7.7.7.7.7 ' vXwXw ` `.U.:X,.*.*.*.J $ !.1X< O EX>X: j.& g @.S.A.,.ZX#XO S.mXy.].].t [ u & & uX-X;.t [ [XyXaXfXj.~.7.7.7.7.7.7",
+".7.7.7.7.7.7.7 `.^.^.^ ` `.U.:.: R k.8 $X2.1 WX0 EX>X:.P Y.G sX& i.A J.ZXjXOX..mXy.].].tX- PX-X;X;.t.t [.tXuXa.s ).7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.p :.^.^.^Xw vXq.0X4 / ^ $ !.4.1 O EX>X: . Y.& gX&.S.A.,.ZX#.B SX..mXu.].].t.t.t.t [.] [.tXuXaXf ).=.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.p : ` `Xw _Xq.0X4 /.8 $X2.4.1X< y EX>X: j.&.G UX& i.+ J.Z.CXO SX..mXuXyXyXy.t.tXy.]XyXuXaXf ).=.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.p : ` ` _Xq.0 = /.8 ^X2.4.1 W O yX>X: . Y.& g @.S.A.+ JXzXjXO SX.XaXuXuXyXyXyXuXuXaXaXf ) *.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.p : `XwXq.0X4 k /.J $ !.4.1 O y EX>X: j.&.G UX&.$.$.+XcXzXjXO. SX.XaXaXaXaXaX.Xf.s ).=.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.7.p :XwXqX7.0 = /.8.FX2 !.1 W O yX>X: . j.&.G UX&.$.$.+.~XcX#XjXOXOXfXfXfXf.s. Xj ).=.7.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.7.7.7 +.UXq.0X4 k /.J $ !.4.1X< O EX>X: . Y.& g.bX&.$.$.+.kXcXcX#XjXjXjXjXjXjXj.~.7.7.7.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.7.7.7.7.p.U.0X4 = /.J.FX2 !.4 W O y E.VX: . Y.&.GXmX&.S.l.#.+.k.~.~XcXcXcXc.k.u.7.7.7.7.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.U.0 R k h.J.FX2.5.1 W O yX>.V D . Y.&.GXm.bX&.l.l.$.#.#.k.k.k ,.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7 +.: = k.8.J $.D L.1X% O yX>.V D . Y.&.&Xm.b.bX&X&.l.l.l ,.u.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.U k.J.FX2.D L.1X% O EX>.V D . w.&.&.&Xm.b.b N 2.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.:.:.*X2 p L.1X% O y t.V D D . w w.uX9X9.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7",
+".7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.* I p L.1X% O y t t 2 2.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7"
+};
diff --git a/arts/builder/pics/Synth_MULTI_ADD.xpm b/arts/builder/pics/Synth_MULTI_ADD.xpm
new file mode 100644
index 00000000..ec088b69
--- /dev/null
+++ b/arts/builder/pics/Synth_MULTI_ADD.xpm
@@ -0,0 +1,1510 @@
+/* XPM */
+static char * Synth_MULTI_ADD_xpm[] = {
+"64 64 1443 2",
+" c None",
+". c #253073",
+"+ c #273276",
+"@ c #293378",
+"# c #283278",
+"$ c #263077",
+"% c #252F75",
+"& c #232E74",
+"* c #212B71",
+"= c #202A6E",
+"- c #1E296A",
+"; c #1C2667",
+"> c #2B3671",
+", c #313D7B",
+"' c #384288",
+") c #353F87",
+"! c #323D83",
+"~ c #2F3A80",
+"{ c #2D377D",
+"] c #2A357B",
+"^ c #29347A",
+"/ c #273177",
+"( c #253076",
+"_ c #232D72",
+": c #222C72",
+"< c #212C71",
+"[ c #202B70",
+"} c #202A70",
+"| c #1F296E",
+"1 c #1B2463",
+"2 c #3C4988",
+"3 c #434D95",
+"4 c #414C93",
+"5 c #3D488D",
+"6 c #202A6F",
+"7 c #1F2A6F",
+"8 c #1E286C",
+"9 c #37437E",
+"0 c #4F59A0",
+"a c #485399",
+"b c #3B458D",
+"c c #283379",
+"d c #242E74",
+"e c #1E296D",
+"f c #1E286D",
+"g c #1C2669",
+"h c #5862A8",
+"i c #555FA6",
+"j c #3F4B90",
+"k c #1F2A6E",
+"l c #1D276B",
+"m c #1C2668",
+"n c #4B5A97",
+"o c #616CB3",
+"p c #5C67AF",
+"q c #4B579B",
+"r c #2E397F",
+"s c #263177",
+"t c #253075",
+"u c #6872B4",
+"v c #343F84",
+"w c #222C71",
+"x c #212B70",
+"y c #1B2666",
+"z c #1B2366",
+"A c #45538B",
+"B c #445194",
+"C c #2B367B",
+"D c #263076",
+"E c #232E73",
+"F c #1D266B",
+"G c #1E266C",
+"H c #1A2264",
+"I c #1D276A",
+"J c #171F57",
+"K c #4A5996",
+"L c #273277",
+"M c #242F74",
+"N c #1A2664",
+"O c #1E296C",
+"P c #1D296B",
+"Q c #1E2A6C",
+"R c #354186",
+"S c #2C377B",
+"T c #202B6F",
+"U c #6672BC",
+"V c #666EB4",
+"W c #5E6AB4",
+"X c #5A66AC",
+"Y c #565EA4",
+"Z c #525EA4",
+"` c #4E5AA2",
+" . c #4A569C",
+".. c #465296",
+"+. c #424E94",
+"@. c #3E4A8E",
+"#. c #3E468C",
+"$. c #36428C",
+"%. c #363E84",
+"&. c #626EB4",
+"*. c #5E66AC",
+"=. c #5662AB",
+"-. c #525AA4",
+";. c #4E5997",
+">. c #4D578F",
+",. c #4F5789",
+"'. c #4E528A",
+"). c #485381",
+"!. c #444D84",
+"~. c #414984",
+"{. c #3F477B",
+"]. c #3E457B",
+"^. c #3C4376",
+"/. c #3B4174",
+"(. c #383F70",
+"_. c #323A71",
+":. c #31386F",
+"<. c #32396C",
+"[. c #2F376C",
+"}. c #313769",
+"|. c #2F3669",
+"1. c #313868",
+"2. c #2C3469",
+"3. c #2C3368",
+"4. c #2D3566",
+"5. c #2C3267",
+"6. c #2D3465",
+"7. c #2D3464",
+"8. c #2E3263",
+"9. c #2A2F66",
+"0. c #2A3366",
+"a. c #2D3564",
+"b. c #343C60",
+"c. c #333761",
+"d. c #2C3565",
+"e. c #535C94",
+"f. c #676682",
+"g. c #7A7368",
+"h. c #857C5F",
+"i. c #867C58",
+"j. c #817559",
+"k. c #78705D",
+"l. c #766C59",
+"m. c #756B57",
+"n. c #766D52",
+"o. c #766C4D",
+"p. c #776C49",
+"q. c #73694A",
+"r. c #6B634D",
+"s. c #69614D",
+"t. c #6B624B",
+"u. c #6E6549",
+"v. c #716647",
+"w. c #736845",
+"x. c #716546",
+"y. c #68614A",
+"z. c #675F4B",
+"A. c #696149",
+"B. c #6E6347",
+"C. c #6F6545",
+"D. c #726843",
+"E. c #686048",
+"F. c #665F49",
+"G. c #6A6247",
+"H. c #796F3F",
+"I. c #85793A",
+"J. c #82793B",
+"K. c #615F4B",
+"L. c #363D60",
+"M. c #1E286A",
+"N. c #1D2769",
+"O. c #6A687F",
+"P. c #9F8E4A",
+"Q. c #CBAB28",
+"R. c #D6B21D",
+"S. c #DCB719",
+"T. c #D6B31C",
+"U. c #CDAC22",
+"V. c #C8A821",
+"W. c #CCAB1E",
+"X. c #CFAD1B",
+"Y. c #CEAC1A",
+"Z. c #D5B115",
+"`. c #D1AE17",
+" + c #C8A71C",
+".+ c #C4A41D",
+"++ c #CAA91B",
+"@+ c #CDAA18",
+"#+ c #CDAB19",
+"$+ c #D0AD17",
+"%+ c #D1AE18",
+"&+ c #C4A51B",
+"*+ c #D8B513",
+"=+ c #E3BF0E",
+"-+ c #E5C10C",
+";+ c #BBA423",
+">+ c #636151",
+",+ c #2F3568",
+"'+ c #222E74",
+")+ c #1E2868",
+"!+ c #1A235E",
+"~+ c #5A62AC",
+"{+ c #565A91",
+"]+ c #847B69",
+"^+ c #D1B023",
+"/+ c #F7CA05",
+"(+ c #FBCD02",
+"_+ c #F6C905",
+":+ c #EFC409",
+"<+ c #F1C607",
+"[+ c #F5C905",
+"}+ c #F1C507",
+"|+ c #FACC02",
+"1+ c #F4C805",
+"2+ c #EEC308",
+"3+ c #F5C804",
+"4+ c #F2C606",
+"5+ c #F8CB03",
+"6+ c #FACD02",
+"7+ c #FECF00",
+"8+ c #E5C10D",
+"9+ c #7F753F",
+"0+ c #353D69",
+"a+ c #222A6F",
+"b+ c #212B6C",
+"c+ c #20296C",
+"d+ c #4E569C",
+"e+ c #525987",
+"f+ c #8A7F5B",
+"g+ c #DFB918",
+"h+ c #FACC03",
+"i+ c #F8CB04",
+"j+ c #E2BB11",
+"k+ c #DDB713",
+"l+ c #E0B910",
+"m+ c #E3BB0E",
+"n+ c #E1B910",
+"o+ c #E9C00B",
+"p+ c #E5BD0D",
+"q+ c #DCB612",
+"r+ c #DBB612",
+"s+ c #E0B90F",
+"t+ c #E9C00A",
+"u+ c #E5BC0D",
+"v+ c #DBB512",
+"w+ c #DCB712",
+"x+ c #E2BB0E",
+"y+ c #EAC10A",
+"z+ c #F1C807",
+"A+ c #F5CC04",
+"B+ c #D1B517",
+"C+ c #716C45",
+"D+ c #34405B",
+"E+ c #262E73",
+"F+ c #222E6C",
+"G+ c #222D6E",
+"H+ c #4E5AA4",
+"I+ c #4A5A9C",
+"J+ c #4A529C",
+"K+ c #4D558B",
+"L+ c #7E7564",
+"M+ c #CEAE22",
+"N+ c #F6CA06",
+"O+ c #F2C608",
+"P+ c #DCB714",
+"Q+ c #B99C29",
+"R+ c #9D8936",
+"S+ c #92813A",
+"T+ c #958238",
+"U+ c #968238",
+"V+ c #9C8634",
+"W+ c #988435",
+"X+ c #917F38",
+"Y+ c #8D7C3B",
+"Z+ c #917F39",
+"`+ c #958236",
+" @ c #968335",
+".@ c #9C8733",
+"+@ c #998537",
+"@@ c #928037",
+"#@ c #8E7D3B",
+"$@ c #92803B",
+"%@ c #968239",
+"&@ c #978437",
+"*@ c #9D8833",
+"=@ c #998639",
+"-@ c #927E39",
+";@ c #8F7E3B",
+">@ c #948238",
+",@ c #A4902F",
+"'@ c #AF9A29",
+")@ c #B09C29",
+"!@ c #867B40",
+"~@ c #4D5165",
+"{@ c #293071",
+"]@ c #263273",
+"^@ c #252D72",
+"/@ c #253071",
+"(@ c #242F6E",
+"_@ c #232E6E",
+":@ c #46529C",
+"<@ c #425294",
+"[@ c #424A94",
+"}@ c #424D8A",
+"|@ c #605E73",
+"1@ c #9C8945",
+"2@ c #D2B01F",
+"3@ c #EDC30B",
+"4@ c #F2C707",
+"5@ c #E4BC0F",
+"6@ c #BB9E27",
+"7@ c #857643",
+"8@ c #5F5A56",
+"9@ c #474963",
+"0@ c #484863",
+"a@ c #464860",
+"b@ c #474860",
+"c@ c #434564",
+"d@ c #42455F",
+"e@ c #454661",
+"f@ c #474761",
+"g@ c #484B5F",
+"h@ c #47495C",
+"i@ c #494A60",
+"j@ c #444767",
+"k@ c #43485D",
+"l@ c #484A61",
+"m@ c #474966",
+"n@ c #484B68",
+"o@ c #484A60",
+"p@ c #4C4E61",
+"q@ c #43476A",
+"r@ c #474D5B",
+"s@ c #4A4D67",
+"t@ c #565759",
+"u@ c #525855",
+"v@ c #464964",
+"w@ c #2B3A69",
+"x@ c #263171",
+"y@ c #232E6C",
+"z@ c #212B69",
+"A@ c #464E94",
+"B@ c #3A468C",
+"C@ c #444984",
+"D@ c #63626C",
+"E@ c #958345",
+"F@ c #CAAA20",
+"G@ c #ECC20A",
+"H@ c #F0C508",
+"I@ c #BDA022",
+"J@ c #7A6F46",
+"K@ c #494963",
+"L@ c #2C366F",
+"M@ c #28326E",
+"N@ c #2B3472",
+"O@ c #273173",
+"P@ c #283272",
+"Q@ c #2B3572",
+"R@ c #2B3471",
+"S@ c #2B3773",
+"T@ c #2C3775",
+"U@ c #2C3574",
+"V@ c #2B3673",
+"W@ c #2D3877",
+"X@ c #2B3578",
+"Y@ c #2B3672",
+"Z@ c #2E3977",
+"`@ c #2E397B",
+" # c #2C3772",
+".# c #2C377A",
+"+# c #2D347A",
+"@# c #2F3971",
+"## c #2E3579",
+"$# c #2D387A",
+"%# c #2A3274",
+"&# c #2A327C",
+"*# c #26366C",
+"=# c #293474",
+"-# c #273273",
+";# c #273271",
+"># c #3E4A94",
+",# c #3A428C",
+"'# c #3E467C",
+")# c #5A576A",
+"!# c #8E7F44",
+"~# c #C3A521",
+"{# c #E9C00C",
+"]# c #FFD000",
+"^# c #BC9F23",
+"/# c #7B7048",
+"(# c #4A4C5E",
+"_# c #303A6A",
+":# c #293475",
+"<# c #2A357A",
+"[# c #2A3675",
+"}# c #2A3674",
+"|# c #2C3878",
+"1# c #2D3978",
+"2# c #2D3777",
+"3# c #2D3976",
+"4# c #2D3775",
+"5# c #2B3873",
+"6# c #2F3B77",
+"7# c #30397E",
+"8# c #2F3775",
+"9# c #2A386E",
+"0# c #2A367C",
+"a# c #2E3A7D",
+"b# c #293579",
+"c# c #293574",
+"d# c #293575",
+"e# c #293473",
+"f# c #263170",
+"g# c #323E84",
+"h# c #3A447E",
+"i# c #4E5064",
+"j# c #807349",
+"k# c #C0A123",
+"l# c #EAC10B",
+"m# c #F6C904",
+"n# c #E5BD0E",
+"o# c #BC9E25",
+"p# c #847643",
+"q# c #515160",
+"r# c #333B72",
+"s# c #2C3779",
+"t# c #2B3679",
+"u# c #2B3877",
+"v# c #2E397C",
+"w# c #2D397C",
+"x# c #2D397A",
+"y# c #2E3B7A",
+"z# c #2E387D",
+"A# c #2F3B7D",
+"B# c #2E3C7A",
+"C# c #2F387D",
+"D# c #2F3B7F",
+"E# c #313D7F",
+"F# c #303E7E",
+"G# c #2F387C",
+"H# c #2E367C",
+"I# c #2C3877",
+"J# c #2C3777",
+"K# c #2A3676",
+"L# c #2B3571",
+"M# c #323A84",
+"N# c #2E3676",
+"O# c #484C67",
+"P# c #7A6F49",
+"Q# c #BD9F23",
+"R# c #EEC309",
+"S# c #C8A81E",
+"T# c #90803E",
+"U# c #565661",
+"V# c #323D77",
+"W# c #2E387B",
+"X# c #2E3A7C",
+"Y# c #2E3B7B",
+"Z# c #2F3C7C",
+"`# c #2F3D7C",
+" $ c #303D7D",
+".$ c #303D7E",
+"+$ c #313F7E",
+"@$ c #313E80",
+"#$ c #313D7D",
+"$$ c #313E7F",
+"%$ c #324081",
+"&$ c #323E81",
+"*$ c #2E3E7C",
+"=$ c #2D3A79",
+"-$ c #283677",
+";$ c #283378",
+">$ c #494B69",
+",$ c #796F46",
+"'$ c #B89C27",
+")$ c #E3BB0F",
+"!$ c #CBAA1D",
+"~$ c #8B7D43",
+"{$ c #525363",
+"]$ c #353F79",
+"^$ c #2F3C7D",
+"/$ c #2F3C7E",
+"($ c #303C7D",
+"_$ c #313E7E",
+":$ c #323E7E",
+"<$ c #333F7F",
+"[$ c #323F7E",
+"}$ c #333F80",
+"|$ c #344081",
+"1$ c #333F7E",
+"2$ c #33417F",
+"3$ c #354183",
+"4$ c #34407E",
+"5$ c #2F3B7E",
+"6$ c #303980",
+"7$ c #2F3C7A",
+"8$ c #2A347C",
+"9$ c #2A3279",
+"0$ c #2F3676",
+"a$ c #484B66",
+"b$ c #7B6F4B",
+"c$ c #B59A29",
+"d$ c #DFB912",
+"e$ c #EDC30A",
+"f$ c #C8A820",
+"g$ c #8C7E43",
+"h$ c #5B5C64",
+"i$ c #3B4578",
+"j$ c #313E7D",
+"k$ c #313F81",
+"l$ c #334082",
+"m$ c #334080",
+"n$ c #344183",
+"o$ c #354284",
+"p$ c #35417E",
+"q$ c #344284",
+"r$ c #364386",
+"s$ c #364385",
+"t$ c #364282",
+"u$ c #354383",
+"v$ c #344180",
+"w$ c #2B3776",
+"x$ c #2B3675",
+"y$ c #283370",
+"z$ c #29337C",
+"A$ c #273375",
+"B$ c #293477",
+"C$ c #2E3870",
+"D$ c #454969",
+"E$ c #746B51",
+"F$ c #AE962C",
+"G$ c #E2BB10",
+"H$ c #EBC20B",
+"I$ c #D1AF1B",
+"J$ c #9C8A3D",
+"K$ c #636160",
+"L$ c #414976",
+"M$ c #344181",
+"N$ c #344281",
+"O$ c #354280",
+"P$ c #344282",
+"Q$ c #34427F",
+"R$ c #374280",
+"S$ c #364482",
+"T$ c #374487",
+"U$ c #374582",
+"V$ c #374586",
+"W$ c #384485",
+"X$ c #344080",
+"Y$ c #2D3876",
+"Z$ c #26327B",
+"`$ c #273477",
+" % c #2A3475",
+".% c #2B357A",
+"+% c #2E3A72",
+"@% c #43496B",
+"#% c #706951",
+"$% c #B2992D",
+"%% c #E0B912",
+"&% c #D7B418",
+"*% c #9E8B3D",
+"=% c #636161",
+"-% c #404A77",
+";% c #354283",
+">% c #364283",
+",% c #364382",
+"'% c #374385",
+")% c #384584",
+"!% c #354482",
+"~% c #384588",
+"{% c #384587",
+"]% c #394585",
+"^% c #394587",
+"/% c #394686",
+"(% c #394687",
+"_% c #374483",
+":% c #354382",
+"<% c #354282",
+"[% c #2B3775",
+"}% c #26327C",
+"|% c #2A337C",
+"1% c #283570",
+"2% c #2B377D",
+"3% c #2D377C",
+"4% c #2B3678",
+"5% c #43496E",
+"6% c #706B57",
+"7% c #AA9333",
+"8% c #DDB814",
+"9% c #F3C807",
+"0% c #F0C509",
+"a% c #D1B01C",
+"b% c #9E8D3D",
+"c% c #666561",
+"d% c #444D7A",
+"e% c #374681",
+"f% c #374482",
+"g% c #384585",
+"h% c #374684",
+"i% c #374685",
+"j% c #374480",
+"k% c #3A4686",
+"l% c #394885",
+"m% c #3A4988",
+"n% c #3A4A8A",
+"o% c #3A4989",
+"p% c #3A4786",
+"q% c #2F3B78",
+"r% c #2B3674",
+"s% c #263176",
+"t% c #283473",
+"u% c #2C387D",
+"v% c #2A3778",
+"w% c #2E3B7C",
+"x% c #444A73",
+"y% c #6A665B",
+"z% c #AB9433",
+"A% c #DBB716",
+"B% c #EFC40A",
+"C% c #D5B21B",
+"D% c #9E8D3F",
+"E% c #616266",
+"F% c #414B7E",
+"G% c #374682",
+"H% c #3A4785",
+"I% c #394884",
+"J% c #394888",
+"K% c #3C4886",
+"L% c #3C4A8B",
+"M% c #3C4A87",
+"N% c #3A4887",
+"O% c #394685",
+"P% c #384685",
+"Q% c #384583",
+"R% c #2A337B",
+"S% c #2E3976",
+"T% c #333D79",
+"U% c #313D77",
+"V% c #333E7A",
+"W% c #484F74",
+"X% c #6E6A5B",
+"Y% c #A99337",
+"Z% c #DCB815",
+"`% c #F3C707",
+" & c #F1C608",
+".& c #CEAE20",
+"+& c #7E7754",
+"@& c #485077",
+"#& c #3B4987",
+"$& c #364582",
+"%& c #384682",
+"&& c #3C498A",
+"*& c #3C4B85",
+"=& c #3B4A87",
+"-& c #3D4C8C",
+";& c #3E4B8C",
+">& c #3D4B8C",
+",& c #3B4988",
+"'& c #394786",
+")& c #33407D",
+"!& c #263174",
+"~& c #27347B",
+"{& c #2D3A7F",
+"]& c #2F3A7B",
+"^& c #364280",
+"/& c #4B5173",
+"(& c #807752",
+"_& c #BFA428",
+":& c #E6BE10",
+"<& c #F2C708",
+"[& c #D7B41A",
+"}& c #897E51",
+"|& c #4D557A",
+"1& c #3B4983",
+"2& c #384883",
+"3& c #3D4A88",
+"4& c #3D4C8A",
+"5& c #3C4B88",
+"6& c #394986",
+"7& c #3C4A84",
+"8& c #3F4C8C",
+"9& c #3F4E8E",
+"0& c #3E4E8A",
+"a& c #3E4E8D",
+"b& c #3E4D8B",
+"c& c #3D4B8A",
+"d& c #3A4888",
+"e& c #3A4787",
+"f& c #242E73",
+"g& c #263279",
+"h& c #283276",
+"i& c #283478",
+"j& c #2A3771",
+"k& c #303C7F",
+"l& c #33407F",
+"m& c #384681",
+"n& c #54576E",
+"o& c #8B7E4A",
+"p& c #C7A925",
+"q& c #E9C00E",
+"r& c #F0C609",
+"s& c #CDAD21",
+"t& c #7E7658",
+"u& c #4B5380",
+"v& c #394783",
+"w& c #3B488A",
+"x& c #3B498A",
+"y& c #3B4B88",
+"z& c #3F4D89",
+"A& c #3E4D88",
+"B& c #3F4F89",
+"C& c #414E91",
+"D& c #404F8E",
+"E& c #404E8D",
+"F& c #404D8C",
+"G& c #3E4C8B",
+"H& c #3C4A89",
+"I& c #3A4886",
+"J& c #35427E",
+"K& c #262F73",
+"L& c #283277",
+"M& c #27327C",
+"N& c #2B3579",
+"O& c #2C387B",
+"P& c #37437F",
+"Q& c #54566E",
+"R& c #807451",
+"S& c #BCA029",
+"T& c #BBA12E",
+"U& c #6D6B64",
+"V& c #455085",
+"W& c #3B4986",
+"X& c #3E4B8A",
+"Y& c #3C4B89",
+"Z& c #3F4C88",
+"`& c #404F8D",
+" * c #41518D",
+".* c #42518C",
+"+* c #42508F",
+"@* c #41518E",
+"#* c #404F90",
+"$* c #3F4E8C",
+"%* c #323F7C",
+"&* c #243073",
+"** c #26346F",
+"=* c #2B3779",
+"-* c #2F3B79",
+";* c #354078",
+">* c #55586D",
+",* c #867A4E",
+"'* c #BFA229",
+")* c #E6BE0F",
+"!* c #EEC40B",
+"~* c #E7BF0F",
+"{* c #C9AA23",
+"]* c #8D814B",
+"^* c #575C78",
+"/* c #3F4B85",
+"(* c #3E4C88",
+"_* c #3F4E8B",
+":* c #41508E",
+"<* c #425190",
+"[* c #414E8A",
+"}* c #43538D",
+"|* c #42528E",
+"1* c #435190",
+"2* c #41508C",
+"3* c #404E8C",
+"4* c #3E4D8C",
+"5* c #232D71",
+"6* c #242E71",
+"7* c #283077",
+"8* c #28327C",
+"9* c #283477",
+"0* c #28347C",
+"a* c #2A3678",
+"b* c #3B4478",
+"c* c #5B5B65",
+"d* c #8C7D49",
+"e* c #C6A821",
+"f* c #E9C00D",
+"g* c #F5C906",
+"h* c #E5BE10",
+"i* c #BFA329",
+"j* c #8D824E",
+"k* c #5F6170",
+"l* c #444E85",
+"m* c #3F4D8E",
+"n* c #3E4C8D",
+"o* c #3E4D8A",
+"p* c #414E90",
+"q* c #425090",
+"r* c #425290",
+"s* c #44548E",
+"t* c #44538E",
+"u* c #455294",
+"v* c #43528E",
+"w* c #445295",
+"x* c #435391",
+"y* c #42518F",
+"z* c #3F4D8A",
+"A* c #3E4B89",
+"B* c #3B4885",
+"C* c #212A6F",
+"D* c #212D72",
+"E* c #2A3477",
+"F* c #364068",
+"G* c #5F5F62",
+"H* c #958441",
+"I* c #CBAA20",
+"J* c #BDA22A",
+"K* c #837851",
+"L* c #595D72",
+"M* c #424F83",
+"N* c #3C4A88",
+"O* c #3F4D8C",
+"P* c #42508D",
+"Q* c #41508D",
+"R* c #43528C",
+"S* c #43548F",
+"T* c #445494",
+"U* c #44548C",
+"V* c #445293",
+"W* c #445391",
+"X* c #435090",
+"Y* c #42518E",
+"Z* c #3A4885",
+"`* c #374581",
+" = c #232C71",
+".= c #242F76",
+"+= c #252F73",
+"@= c #253176",
+"#= c #2D3970",
+"$= c #3E456C",
+"%= c #65635A",
+"&= c #9B893D",
+"*= c #CEAD1C",
+"== c #EEC30A",
+"-= c #E3BC11",
+";= c #B89E2D",
+">= c #7E7756",
+",= c #535972",
+"'= c #3F4A88",
+")= c #3C4B8C",
+"!= c #3E4E8E",
+"~= c #414F8C",
+"{= c #455391",
+"]= c #475694",
+"^= c #445493",
+"/= c #455394",
+"(= c #424F8C",
+"_= c #465494",
+":= c #46588F",
+"<= c #45568F",
+"[= c #455491",
+"}= c #445390",
+"|= c #35417C",
+"1= c #212D71",
+"2= c #222D71",
+"3= c #253173",
+"4= c #2E3575",
+"5= c #424866",
+"6= c #71694F",
+"7= c #A79133",
+"8= c #D6B218",
+"9= c #DBB616",
+"0= c #AD9634",
+"a= c #756F5A",
+"b= c #4E5379",
+"c= c #3B4889",
+"d= c #3A4684",
+"e= c #3B4B8C",
+"f= c #404E90",
+"g= c #435290",
+"h= c #42538D",
+"i= c #455494",
+"j= c #455593",
+"k= c #44558D",
+"l= c #465690",
+"m= c #475793",
+"n= c #485495",
+"o= c #475594",
+"p= c #465592",
+"q= c #202C71",
+"r= c #222B70",
+"s= c #222E72",
+"t= c #2B3570",
+"u= c #474961",
+"v= c #786E4B",
+"w= c #B59A28",
+"x= c #D9B517",
+"y= c #A79138",
+"z= c #6E6C5D",
+"A= c #495176",
+"B= c #384687",
+"C= c #3B478C",
+"D= c #3A4A8C",
+"E= c #3D498D",
+"F= c #3E4E8C",
+"G= c #435191",
+"H= c #465491",
+"I= c #485795",
+"J= c #475496",
+"K= c #485894",
+"L= c #46568B",
+"M= c #495A92",
+"N= c #495996",
+"O= c #495992",
+"P= c #414F8A",
+"Q= c #1F2B6E",
+"R= c #222C70",
+"S= c #232E72",
+"T= c #262F72",
+"U= c #464966",
+"V= c #7A6E46",
+"W= c #B99D26",
+"X= c #E3BC0F",
+"Y= c #F0C507",
+"Z= c #D5B218",
+"`= c #A49038",
+" - c #6C6A5F",
+".- c #474E7B",
+"+- c #384481",
+"@- c #3E4B8D",
+"#- c #424F8F",
+"$- c #425292",
+"%- c #435291",
+"&- c #45528D",
+"*- c #465594",
+"=- c #43548C",
+"-- c #475991",
+";- c #4A5A99",
+">- c #485791",
+",- c #485593",
+"'- c #4B5B9A",
+")- c #4C5B98",
+"!- c #4A5A95",
+"~- c #495894",
+"{- c #404E8A",
+"]- c #3E4D89",
+"^- c #394680",
+"/- c #1F2A6D",
+"(- c #1F286D",
+"_- c #26306E",
+":- c #424460",
+"<- c #786C45",
+"[- c #BC9F22",
+"}- c #E7BF0C",
+"|- c #C9A91E",
+"1- c #9A873B",
+"2- c #646362",
+"3- c #454B77",
+"4- c #384581",
+"5- c #384688",
+"6- c #384888",
+"7- c #3B498C",
+"8- c #42508E",
+"9- c #435292",
+"0- c #455492",
+"a- c #465695",
+"b- c #475691",
+"c- c #48568F",
+"d- c #47578F",
+"e- c #495993",
+"f- c #48568C",
+"g- c #4C5C9C",
+"h- c #4C5D9C",
+"i- c #4D5E98",
+"j- c #333E78",
+"k- c #1E296E",
+"l- c #1E2A6D",
+"m- c #2A3168",
+"n- c #494A5C",
+"o- c #7C6F42",
+"p- c #BEA021",
+"q- c #EBC10A",
+"r- c #F5C904",
+"s- c #BB9F25",
+"t- c #867940",
+"u- c #585862",
+"v- c #3E4877",
+"w- c #344483",
+"x- c #384285",
+"y- c #384684",
+"z- c #3A4687",
+"A- c #3E4A84",
+"B- c #414E92",
+"C- c #405090",
+"D- c #44528F",
+"E- c #45558F",
+"F- c #4A5898",
+"G- c #485A92",
+"H- c #4A599C",
+"I- c #4A5891",
+"J- c #4B5A95",
+"K- c #4B5B96",
+"L- c #4D5D97",
+"M- c #4E5F98",
+"N- c #505E99",
+"O- c #4F5E9D",
+"P- c #4C5D98",
+"Q- c #485893",
+"R- c #455390",
+"S- c #2E3566",
+"T- c #535054",
+"U- c #8E7C38",
+"V- c #C5A51D",
+"W- c #BDA023",
+"X- c #7C7146",
+"Y- c #4D4F63",
+"Z- c #363E74",
+"`- c #2F3B7C",
+" ; c #344280",
+".; c #364483",
+"+; c #3A478C",
+"@; c #3B4A8D",
+"#; c #414E8C",
+"$; c #445291",
+"%; c #465593",
+"&; c #46568E",
+"*; c #485A91",
+"=; c #485897",
+"-; c #4A578D",
+";; c #4B5C95",
+">; c #4B5A93",
+",; c #4E5E99",
+"'; c #4E5E97",
+"); c #4D5D98",
+"!; c #4F5F9C",
+"~; c #4C5C97",
+"{; c #475692",
+"]; c #3A4883",
+"^; c #1E276C",
+"/; c #2A3266",
+"(; c #545052",
+"_; c #968333",
+":; c #D5B114",
+"<; c #F3C705",
+"[; c #C5A51E",
+"}; c #87793D",
+"|; c #585759",
+"1; c #40466F",
+"2; c #3E466F",
+"3; c #434B72",
+"4; c #474E7A",
+"5; c #495077",
+"6; c #4A527B",
+"7; c #4A537F",
+"8; c #4D567E",
+"9; c #4D567F",
+"0; c #4D577F",
+"a; c #4C5782",
+"b; c #4D5785",
+"c; c #4D5788",
+"d; c #4E5889",
+"e; c #525E8A",
+"f; c #525E87",
+"g; c #535E8C",
+"h; c #56608B",
+"i; c #53608C",
+"j; c #536090",
+"k; c #535F8B",
+"l; c #556396",
+"m; c #526296",
+"n; c #52639D",
+"o; c #4D5E9C",
+"p; c #4A5991",
+"q; c #4F5A94",
+"r; c #1D286C",
+"s; c #1D276C",
+"t; c #232A69",
+"u; c #434459",
+"v; c #8E7D36",
+"w; c #D3B015",
+"x; c #D8B314",
+"y; c #BA9D24",
+"z; c #988535",
+"A; c #807445",
+"B; c #7E734A",
+"C; c #817545",
+"D; c #887B43",
+"E; c #8A7C48",
+"F; c #8B7F4D",
+"G; c #897E4F",
+"H; c #867C53",
+"I; c #867D54",
+"J; c #8C8151",
+"K; c #8E8351",
+"L; c #8D8152",
+"M; c #867E57",
+"N; c #817B5C",
+"O; c #7E7960",
+"P; c #807A62",
+"Q; c #837E60",
+"R; c #89835C",
+"S; c #8C8460",
+"T; c #8A835A",
+"U; c #878063",
+"V; c #817B64",
+"W; c #7B796A",
+"X; c #7B7B70",
+"Y; c #777771",
+"Z; c #687086",
+"`; c #5A6894",
+" > c #52629B",
+".> c #4B5A8D",
+"+> c #4A5A9A",
+"@> c #4E5E94",
+"#> c #4A5994",
+"$> c #495693",
+"%> c #455490",
+"&> c #1C276A",
+"*> c #282F66",
+"=> c #5A554E",
+"-> c #BE9F1F",
+";> c #F8CB02",
+">> c #EDC209",
+",> c #E7BF0B",
+"'> c #DEB812",
+")> c #D6B316",
+"!> c #D6B217",
+"~> c #DCB713",
+"{> c #E0BA11",
+"]> c #E0BA12",
+"^> c #DEB915",
+"/> c #D9B619",
+"(> c #D9B61A",
+"_> c #DFBA16",
+":> c #E2BC14",
+"<> c #DCB818",
+"[> c #D9B61B",
+"}> c #D3B220",
+"|> c #CEAF24",
+"1> c #CEAF25",
+"2> c #D3B321",
+"3> c #D8B61E",
+"4> c #D9B71E",
+"5> c #D3B323",
+"6> c #CBAD2A",
+"7> c #C2A834",
+"8> c #C1A834",
+"9> c #B9A33C",
+"0> c #9B9055",
+"a> c #70757C",
+"b> c #535E87",
+"c> c #4F6097",
+"d> c #4B5C97",
+"e> c #4A5A9B",
+"f> c #4A5A94",
+"g> c #3E4B85",
+"h> c #282F65",
+"i> c #59544F",
+"j> c #BA9C1F",
+"k> c #F2C605",
+"l> c #F7CA03",
+"m> c #F4C806",
+"n> c #F6CA04",
+"o> c #F7CA04",
+"p> c #F4C906",
+"q> c #F6CA05",
+"r> c #F3C808",
+"s> c #F0C60A",
+"t> c #F0C60B",
+"u> c #F4C808",
+"v> c #F7CB05",
+"w> c #F5C907",
+"x> c #F4C908",
+"y> c #F0C60C",
+"z> c #ECC30F",
+"A> c #ECC40F",
+"B> c #ECC410",
+"C> c #CCAF2C",
+"D> c #88815F",
+"E> c #5D678B",
+"F> c #50609A",
+"G> c #4B5A92",
+"H> c #212A66",
+"I> c #40415B",
+"J> c #7F703D",
+"K> c #B89A22",
+"L> c #CDAB18",
+"M> c #D2AF15",
+"N> c #D3B016",
+"O> c #D5B116",
+"P> c #D7B316",
+"Q> c #D6B216",
+"R> c #DDB815",
+"S> c #E3BD13",
+"T> c #E4BD12",
+"U> c #E8C010",
+"V> c #E4BE12",
+"W> c #E0BB16",
+"X> c #E0BA17",
+"Y> c #E5BE13",
+"Z> c #E9C110",
+"`> c #E8C012",
+" , c #E9C111",
+"., c #E6BF13",
+"+, c #E4BE15",
+"@, c #E8C111",
+"#, c #CCAE28",
+"$, c #888367",
+"%, c #5C6789",
+"&, c #4A5888",
+"*, c #4A5A8D",
+"=, c #465694",
+"-, c #46528C",
+";, c #1D266A",
+">, c #232C62",
+",, c #3E4058",
+"', c #59544E",
+"), c #6B6348",
+"!, c #746944",
+"~, c #776C48",
+"{, c #7A6F47",
+"], c #796F47",
+"^, c #7A7046",
+"/, c #7D724A",
+"(, c #83774A",
+"_, c #887B45",
+":, c #897C47",
+"<, c #8A7D48",
+"[, c #867B4C",
+"}, c #857B51",
+"|, c #8D8250",
+"1, c #95884B",
+"2, c #9A8B46",
+"3, c #A18F42",
+"4, c #9F8F45",
+"5, c #9C8D48",
+"6, c #9D8E49",
+"7, c #A29246",
+"8, c #A79543",
+"9, c #A89744",
+"0, c #A99744",
+"a, c #A69645",
+"b, c #AA9846",
+"c, c #B49F3E",
+"d, c #BDA536",
+"e, c #B8A13A",
+"f, c #9A8F56",
+"g, c #6E727C",
+"h, c #515B84",
+"i, c #4C5C94",
+"j, c #45548F",
+"k, c #222B68",
+"l, c #273068",
+"m, c #2C3361",
+"n, c #2E3565",
+"o, c #343B69",
+"p, c #383E68",
+"q, c #373F66",
+"r, c #38406D",
+"s, c #3B426F",
+"t, c #3F4670",
+"u, c #404870",
+"v, c #444B71",
+"w, c #434B76",
+"x, c #454D75",
+"y, c #46507B",
+"z, c #48527D",
+"A, c #4C557D",
+"B, c #50587D",
+"C, c #555B74",
+"D, c #575C75",
+"E, c #5C6074",
+"F, c #5A5E78",
+"G, c #5A607A",
+"H, c #5E637B",
+"I, c #606577",
+"J, c #636875",
+"K, c #616677",
+"L, c #646978",
+"M, c #676B76",
+"N, c #6F6F6B",
+"O, c #76756F",
+"P, c #747475",
+"Q, c #656C81",
+"R, c #535C83",
+"S, c #4D5A94",
+"T, c #1B2667",
+"U, c #1C2768",
+"V, c #1B2767",
+"W, c #1B2665",
+"X, c #1F2B6D",
+"Y, c #222D6F",
+"Z, c #232F6E",
+"`, c #253072",
+" ' c #273373",
+".' c #2D3979",
+"+' c #2D3977",
+"@' c #2E3A7B",
+"#' c #323F7F",
+"$' c #354281",
+"%' c #3C4C85",
+"&' c #3D4B88",
+"*' c #404D85",
+"=' c #414F89",
+"-' c #424F89",
+";' c #445289",
+">' c #45528F",
+",' c #46538E",
+"'' c #475591",
+")' c #495592",
+"!' c #4A588E",
+"~' c #4C5A90",
+"{' c #4F5C8C",
+"]' c #4F5B8B",
+"^' c #4B5788",
+"/' c #4A5894",
+"(' c #4A5992",
+"_' c #485794",
+":' c #4A5694",
+"<' c #1E266B",
+"[' c #1D2668",
+"}' c #1E2869",
+"|' c #1C2867",
+"1' c #1E2A69",
+"2' c #222E6D",
+"3' c #263173",
+"4' c #2D3A77",
+"5' c #2E3A7A",
+"6' c #323E7F",
+"7' c #394684",
+"8' c #3A4A84",
+"9' c #3E4A8C",
+"0' c #3D4987",
+"a' c #3D4C8B",
+"b' c #40508C",
+"c' c #44538F",
+"d' c #485592",
+"e' c #485792",
+"f' c #485895",
+"g' c #46568C",
+"h' c #42528C",
+"i' c #1A2665",
+"j' c #1E276B",
+"k' c #1F296C",
+"l' c #222C6F",
+"m' c #263271",
+"n' c #2A3574",
+"o' c #2A3576",
+"p' c #364684",
+"q' c #3C4884",
+"r' c #3D4A87",
+"s' c #3D4A89",
+"t' c #42508C",
+"u' c #44528B",
+"v' c #46548E",
+"w' c #465493",
+"x' c #475593",
+"y' c #475490",
+"z' c #4A5794",
+"A' c #424E8C",
+"B' c #3C477A",
+"C' c #1A2467",
+"D' c #1C2769",
+"E' c #1D2969",
+"F' c #1C2868",
+"G' c #202C6C",
+"H' c #232F6F",
+"I' c #243074",
+"J' c #243075",
+"K' c #2A3677",
+"L' c #2F3A7E",
+"M' c #333F7C",
+"N' c #354182",
+"O' c #3B4A88",
+"P' c #3F4D88",
+"Q' c #404F8C",
+"R' c #44518C",
+"S' c #445490",
+"T' c #445492",
+"U' c #43538F",
+"V' c #445491",
+"W' c #485693",
+"X' c #465284",
+"Y' c #1B2464",
+"Z' c #1C266A",
+"`' c #1E276D",
+" ) c #202A6C",
+".) c #1F2B6A",
+"+) c #25316F",
+"@) c #2C367D",
+"#) c #2E3A74",
+"$) c #2F3B7A",
+"%) c #303F7C",
+"&) c #324283",
+"*) c #404E8B",
+"=) c #404F8A",
+"-) c #43528F",
+";) c #44528E",
+">) c #475794",
+",) c #465294",
+"') c #3A4475",
+")) c #182059",
+"!) c #1A2462",
+"~) c #1D2869",
+"{) c #1F296A",
+"]) c #212A6D",
+"^) c #252F6F",
+"/) c #263272",
+"() c #283275",
+"_) c #2E3A77",
+":) c #3B4887",
+"<) c #3E4C89",
+"[) c #40508D",
+"}) c #42528F",
+"|) c #43538C",
+"1) c #45558C",
+"2) c #1B2565",
+"3) c #202B6B",
+"4) c #25306F",
+"5) c #263172",
+"6) c #283373",
+"7) c #2B3777",
+"8) c #2D3A78",
+"9) c #303C7B",
+"0) c #3C4987",
+"a) c #3E4B88",
+"b) c #3E4C8A",
+"c) c #3E4E89",
+"d) c #3F4E8A",
+"e) c #414E89",
+"f) c #42518D",
+"g) c #414F8B",
+"h) c #445190",
+"i) c #42528D",
+"j) c #42518B",
+"k) c #3C467F",
+"l) c #1C2664",
+"m) c #1F2A6B",
+"n) c #242F6F",
+"o) c #3F4F8A",
+"p) c #40508B",
+"q) c #1D2765",
+"r) c #2A3575",
+"s) c #3C4A86",
+"t) c #3C4B87",
+"u) c #404F8B",
+"v) c #3D4B87",
+"w) c #3D4C88",
+"x) c #3F4C87",
+" . + @ @ # $ % & * = - ; ",
+" > , ' ) ! ~ { ] ^ / ( % _ : < [ } | 1 1 ",
+" 2 3 4 5 ' ) ! ~ { ] ^ / ( % _ : < [ 6 7 | | 8 1 ",
+" 9 0 0 a 3 4 b ' ) ! ~ { ] c / ( d _ : < [ 6 7 | e f f 8 g 1 ",
+" h h i 0 a 3 j b ' ) ! ~ { ] c / ( d _ : * [ 6 k | e f 8 8 8 l m ",
+" n o p i 0 q a 3 j b ' ) ! r { ] c s t d _ : * [ 6 | | e f 8 8 l l l g 1 ",
+" u o p h i 0 q a 4 5 b ' v ! r { ] # s % d _ w x } 6 | | e f 8 8 l l y z m m ",
+" A u u o p h i 0 a B 4 5 b ' ! ~ r C ^ # D % E _ < x 6 7 | | f 8 8 8 l F G G H I m J ",
+" K u u o o p i 0 q a 3 j b ' ) ! ~ { ] ^ L D M E _ < x 6 k | e f 8 8 l y G G N G H g m J ",
+" n u u u o p h i 0 q a 3 j b ' v ! ~ { ] c / ( d _ : * [ 6 k | e f 8 O P Q G Q Q G Q H g m J ",
+" K u u u o p h i 0 0 a 3 4 5 b R v ~ r S ^ # s % d _ w x T 6 | | e 8 8 G G Q N G Q N G N H m ; J ",
+" A u u U V W X Y Z ` ...+.@.#.$.%.! ~ { C ^ L D % E _ < x 6 k | | f G O Q G G G N G G Q G G H m ; J ",
+" u u u &.*.X =.Z -.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.a.b.c.d.G N G N N m m ; ",
+" u u o &.W X =.Y ` e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.C.E.F.G.H.I.J.K.L.Q Q G G M.N.N.1 ",
+" n o o o *.X Y Z -.;.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+++@+#+Z.$+ +.+++@+#+Z.%+ +&+@+*+=+-+;+>+,+'+Q Q - - - )+!+ ",
+" o p p p ~+Y Z ` .{+]+^+/+/+(+_+:+:+<+[+}+|+1+2+2+}+3+}+|+1+2+2+}+[+}+|+1+2+2+4+5+6+7+8+9+0+a+'+a+b+b+c+- )+ ",
+" h p h h i Z -.` d+ .e+f+g+h+i+/+:+j+k+l+m+n+o+p+q+r+s+m+s+t+u+q+v+l+m+s+o+u+w+q+x+y+z+A+B+C+D+E+'+F+G+G+b+b+b+)+ ",
+" 9 h i i i 0 H+I+ .J++.K+L+M+N+/+O+P+Q+R+S+T+U+V+W+X+Y+Z+`+ @.@+@@@#@$@%@&@*@=@-@;@>@,@'@)@!@~@{@]@]@^@/@(@_@G+G+b+1 ",
+" 0 i 0 0 0 q J+:@<@+.[@}@|@1@2@3@4@5@6@7@8@9@0@a@b@c@d@e@f@g@h@i@j@k@l@m@n@o@p@q@q@r@s@t@u@v@w@]@]@]@/@x@/@/@(@_@y@z@ ",
+" 0 0 q q a a :@A@+.[@@.B@C@D@E@F@G@H@p+I@J@K@L@M@N@O@P@Q@R@S@T@U@V@W@X@Y@Z@`@^ #.#+# #@###$#%#&#%#*#=#-#;#x@/@/@(@_@ ",
+" 2 a a a a B 3 +.>#[@B@,#B@$.'#)#!#~#{#]#y+^#/#(#_#:#<#[#}#|#S |#1#2#3#`@4#5#6#7#8#9#0#0#9#0#a#}#}#b#c#d#d#=#e#;#;#f#(@)+ ",
+" 3 3 3 3 4 4 j j 5 b ' ,#%.%.g#h#i#j#k#l#m#n#o#p#q#r#s#t#t#u#v#w#x#y#z#A#B#C#D#E#F#G#a#a#H#a#}#I#|#J#J#J#J#K#d#=#e#;#x@(@ ",
+" L#4 4 j j 5 5 b b b ' ' ) g#g#M#H#N#O#P#Q#n#R#p+S#T#U#V#W#X#Y#A#Z#`# $.$F#+$@$#$$$%$&$A#*$a#*$a#=$1#=$1#1#1#J#K#K#d#e#;#;#z@ ",
+" , 5 b b b b b ' ' R ) v ! g#M#H#a#-$;$>$,$'$)$H@R#!$~${$]$^$/$($_$_$:$<$[$}$|$[$1$2$3$4$5$*$6$B#7$7$5$7$y#=$1#1#J#K#d#=#e#z@ ",
+" ' ' ' ' ' ' ' ) v v ! ! ~ H#a#H#0#8$9$0$a$b$c$d$4@e$f$g$h$i$E#j$k$l$m$m$n$o$p$q$r$s$t$u$v$, j$j$j$j$j$j$, 7$7$=$1#J#w$x$d#y$ ",
+" ) ) ) ) ) v ! ! ! ~ ~ r { a#0#&#0#z$A$B$C$D$E$F$G$|+H$I$J$K$L$2$M$M$N$O$P$o$Q$R$S$T$U$V$W$X$[$v$v$[$[$[$j$, , 7$y#=$1#Y$x$d# ",
+". ! ! ! ! ! ! ~ ~ ~ r { { C ] 0#%#]@Z$`$ %.%+%@%#%$%%%[+[+&%*%=%-%;%>%,%s$'%)%!%~%{%]%^%/%(%_%:%<%O$v$v$v$[$[$j$, 7$7$=$1#Y$[%y$",
+"+ ~ ~ ~ ~ r r r { { S C ] ^ @ }%}%}%%#|%1%2%3%4%5%6%7%8%9%0%a%b%c%d%e%f%g%h%i%j%k%l%m%n%o%p%(%)%_%_%:%<%O$v$v$[$[$j$, 7$q%1#Y$r%",
+"@ { { { { { { C ] ] ^ ^ c # L s%D D s%}%t%2%u%v%w%x%y%z%A%3@B%C%D%E%F%i%G%H%I%J%l%p%K%2 L%M%m%N%O%P%Q%_%_%:%O$v$v$[$j$, 7$q%1#[%",
+"@ ] ] ] ] ] ] ^ ^ c # L / s%D % % t s%]@R%r%S%T%U%V%W%X%Y%Z%`% &.&+&@&#&$&(%%&&&*&=&-&-&;&>&&&,&N%'&'&P%Q%Q%_%:%O$v$)&[$, 7$q%Y$",
+"# ^ ^ c c c # # L / s D t % M d d % !&A$|%~&1#{&]&[$^&/&(&_&:&<&[&}&|&1&2&3&4&5&6&7&8&9&0&a&b&c&2 d&d&e&'&P%Q%Q%:%O$v$)&[$j$7$1#",
+"$ / / / / s s D D ( % % M f&E '+E+g&h&i&j&S%=$q%k&l&m&n&o&p&q&r&s&t&u&v&w&x&y&z&A&9&B&C&D&E&F&G&c&H&H&2 2 I&'&P%Q%_%O$J&)&[$, q%",
+"% ( ( ( ( t % % M d d E _ _ _ '+K&]@L&M&N&2%O&a#D#P&Q&R&S&:& &3@T&U&V&W&X&Y&Y&-&Z&`& *.*+*@*#*$*b&G&G&c&H&2 d&I&P%Q%_%O$J&)&%*7$",
+"& % % d d d d E E _ _ _ : w _ d &*$ **t%0#[%=*-*;*>*,*'*)*!*~*{*]*^*/*>&>&(*_*:*<*[*D&}*|*1*2*:*`&3*4*G&G&c&H&2 I&'&Q%_%O$J&)&, ",
+"* _ _ _ _ _ _ _ _ : w < < * 5*6*&*7*8*9*0*a*a*b*c*d*e*f*g*h*i*j*k*l*(*m*n*o*p*q*r*s*t*u*v*w*x*y*:*:*:*3*4*z*G&A*2 B*P%Q%_%O$J&%*",
+"= : : : : : w < < * x x [ C*D*f&]@]@9*E*}#K#F*G*H*I*e$h+:&J*K*L*M*N*-&O*D&D&P*Q*1*r*R*S*T*U*V*W*X*X*Y*:*:*3*z*A*A*2 Z*P%Q%`*J&%*",
+"- < < < * * x x x [ T 6 6 C*D* =.=+=@=c##=$=%=&=*===O+-=;=>=,='=)=8&!=#*~=q*Q*{=]=^=/=(=_=:=<=[=}=}=}=v*Y*:*3*z*A*A*2 Z*Q%Q%O$|=",
+"; [ [ [ [ [ } 6 6 6 6 k T < 1=2=6*+=3=4=5=6=7=8=e$G@9=0=a=b=c=h%d=e=O*f=1*g=1*h=i=j=k=l=m=n=o=p=p=p=[=}=g=X*P*2*z*A*H&B*Z*Q%`*|=",
+" } 6 6 6 6 6 7 k k | a+T = q=r=s=. t=u=v=w=d$<+ &x=y=z=A=B=C=D=E=N*F=F=3*P*G=x*H=I=J=K=L=M=N=O=]=]=]=p=[=}=v*P*P=z*(*2 B*Q%`* ",
+" | 7 7 k | | | Q G C*k Q=6 6 R=S=T=U=V=W=X=Y=:+Z=`= -.-p%+-d=d=D=4*@-#-$-%-&-*-=---;->-K=,-'-)-!-~-~-]=p=[=}=v*2*{-]-(*B*Z*^- ",
+" 1 | | | | | | e e /-(-6 6 T 2=_-:-<-[-p+R#}-|-1-2-3-4-5-6-7-B@@.F=F=E&8-9-i=0-a-b-c-d-e-f-g-h-i-!-K ~-]=p=[=}=Y*2*z*(*2 B*j- ",
+" 1 | e e e e f f k-f l-e C*T m-n-o-p-q-r-p+s-t-u-v-w-x-y-z-e&A-@.F=B-C-q*D-*-E-F-G-H-I-J-K-L-M-N-O-P-K Q-]=p=R-v*2*{-A*2 B*j- ",
+" 8 f f f f 8 8 f Q G = e S-T-U-V-t+]#q-W-X-Y-Z-`- ;.;d&+;@;D=@.F=4*#;r*$;}=%;&;*;=;-;;;>;,;M-';);!;~;K Q-{;[=}=Y*P=]-(*]; ",
+" 1 f 8 8 8 8 f f ^;O 8 /;(;_;:;4+<;o+[;};|;1;2;2;3;4;5;6;7;8;9;0;a;b;c;d;e;f;g;h;h;i;j;k;l;m;n;i-o;p;q;~-Q-p=}=v*P=]-(*|= ",
+" 8 8 8 8 8 r;s;8 (-t;u;v;w;1+5+Y=x;y;z;A;B;C;D;E;F;G;H;I;J;K;L;M;N;O;P;Q;R;S;T;U;V;W;X;Y;Z;`; >.>+>@>#>$>{;%>v*2*{-(* ",
+" g 8 l l l s;l 8 &>*>=>->1+;>5+1+>>,>'>)>!>~>{>]>j+^>/>(>_>:><>[>}>|>1>2>3>3>4>5>6>7>8>9>0>a>b>c>d>e>f>f>{;%>v*2*{-g> ",
+" 1 l l l l l l ^;s;h>i>j>k>l>l>5+1+m#[+m>1+n>(+o>(+/+p>g*/+(+q>/+r>s>t>u>v>w>v>x>y>z>A>B>C>D>E>F>G>e>f>f>{;%>v*2*{-^- ",
+" m l l I l l m g H>I>J>K>L>M>w;N>O>P>Q>Q>P+{>]>j+R>/>(>_>S>T>U>V>W>X>Y>Z>`> ,.,+,@,z>z>#,$,%,&,!-*,=,-,{;%>v*2*g> ",
+" g I I I I ;,F l >,,,',),C.!,~,{,],^,/,(,_,:,<,[,},H;|,1,2,3,4,5,6,7,8,9,0,a,b,c,d,e,f,g,h,i,f>e>f>f>{;j,v*{- ",
+" 1 I I I I I m I l k,l,m,n,1.o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,n #>f>f>=,p=R-v*^- ",
+" T,I N.N.I ;,U,V,W,8 X,Y,2=Z,`, 'B$.'+'@'($#'$'P%d&H&G&%'&'*'='-';'>',''')'!'~'{']'^'/'('_'!-f>:'=,%>v*P= ",
+" N N <'m [';,I ;,}'|'1'2'(@3'h&d#a*4'5'6':$P$7'd=8'9'y&0'Y&a'$*b'2*s*c's*p=d'e'c-f'{;K=K=#>f>f>g'g'h' ",
+" J H G W,i'j'T,N.^;k'6 l'Y,/@m'n'o'x#5'`-#'|$p'd=8'D=q'#&r's'b&O*~=8-t'W*u't*v'w'b-x'y'$>z'=,=,<@A'B' ",
+" J ; W,C'F m D'E'F'G'Y,H'I'J'=#K#K'w%L'M'N'd=B@8'A-a'O'N*&'&'P'F&Q'2*+*R'S'T'U'V'V'W']=O=g'g'X'B' ",
+" J ; Y'T,; Z'l `' ).)l'+)+ c#K'@)#)$)%)&)p',#d=d=A-c=O'Y&3&&'(**)=)b'2*t'.*-)}=;)>)T':',)h'') ",
+" )); !); U,~){) )])Y,^)/)()[#s#_)Z#[$v$:%Q%P%I&2 3&:)M%<)<)<)b&Z&*)*)[)Q*})D-}=|)1)g'h'B' ",
+" J 2)1 U,N.M.3)G+_@4)5)6)[#7)8)9)[$v$O$:%Q%P%I&2 0)I&M%a)b)z*c)d)e)f)f)g)-)f)h)i)j)k) ",
+" 1 l)U,M.m)b+G+n)5) 'n'7)y#7$j$[$v$O$_%Q%'&B*2 0)#&M%r'<)z&d)d)o)o)g)p)f)v*P= ",
+" !+q){)3)3)G+n);# 'r)J#=$7$, j$)&v$O$_%Q%P%Z*2 ,&s)t)M%r'a)a)z&d){-u){-^- ",
+" )+b+y@(@f#;#e#d#w$1#=$7$, [$)&J&O$_%Q%P%Z*B*2 v)M%3&w)w)(*(*x)g> ",
+" 1 z@_@(@x@;#=#x$Y$1#q%7$, [$)&J&O$_%Q%Q%Z*B*B*2 2 (*(*(*g>^- ",
+" )+(@;#e#d#x$Y$1#q%7$j$[$)&J&O$`*Q%Q%Q%Z*B*B*];|= ",
+" z@z@y$d#[%Y$1#q%7$, %*)&J&J&O$`*`*^-j-j- ",
+" y$r%[%Y$1#q%7$, %*%*|=|= "};
diff --git a/arts/builder/pics/Synth_PLAY.xpm b/arts/builder/pics/Synth_PLAY.xpm
new file mode 100644
index 00000000..3ad46f6e
--- /dev/null
+++ b/arts/builder/pics/Synth_PLAY.xpm
@@ -0,0 +1,316 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 245 2",
+/* colors */
+" c #B1B1B1",
+" . c #BFBFC2",
+" X c #ADADAD",
+" o c #A9AAB3",
+" O c #ABABAB",
+" + c #323E7D",
+" @ c #5F6792",
+" # c #71789D",
+" $ c #2F3A7A",
+" % c #3E4C8C",
+" & c #A5A5A5",
+" * c #3A4488",
+" = c #273272",
+" - c #8D93B5",
+" ; c #78787C",
+" : c #253070",
+" > c #616B97",
+" , c #344082",
+" < c #232E6E",
+" 1 c #313C7F",
+" 2 c #B0B5CA",
+" 3 c #1F286A",
+" 4 c #959595",
+" 5 c #1C2667",
+" 6 c #5F6BAC",
+" 7 c #696A6D",
+" 8 c #374288",
+" 9 c #8D8D8D",
+" 0 c #36417D",
+" q c #6F79AB",
+" w c #43518D",
+" e c #1F2A6D",
+" r c #1E286C",
+" t c #414F8B",
+" y c #2D3774",
+" u c #1A235E",
+" i c #9599AF",
+" p c #D1D2D6",
+" a c #64666B",
+" s c #475394",
+" d c #777777",
+" f c #767DA1",
+" g c #536299",
+" h c #2F3B79",
+" j c #8E8F94",
+" k c #2A3574",
+" l c #5D68A6",
+" z c #4B5891",
+" x c #50598C",
+" c c #273171",
+" v c #575D7F",
+" b c #222D6C",
+" n c #212B6B",
+" m c #303B7D",
+" M c #404B90",
+" N c #1D2767",
+" B c #3C478C",
+" V c #4C5A95",
+" C c #38447E",
+" Z c #38427E",
+" A c #343E7A",
+" S c #858CAF",
+" D c #42508B",
+" F c #2E397E",
+" G c #1D276A",
+" H c #404E89",
+" J c #1C2769",
+" K c #303A76",
+" L c #2C377C",
+" P c #3E4C87",
+" I c #C7C7C8",
+" U c #AFB0B7",
+" Y c #E4E5EB",
+" T c #29326F",
+" R c #384481",
+" E c #DCDDE3",
+" W c #303C79",
+" Q c #3E4C8A",
+" ! c #3D4A89",
+" ~ c #414B83",
+" ^ c #3A4886",
+" / c #686971",
+" ( c #7B84A8",
+" ) c #515C8C",
+" _ c #656F99",
+" ` c #7880A5",
+" ' c #4A578F",
+" ] c #424C91",
+" [ c #202A69",
+" { c #3E488D",
+" } c #2C3878",
+" | c #1B2464",
+". c #797A7E",
+".. c #3A477F",
+".X c #9D9D9E",
+".o c #39457E",
+".O c #47558F",
+".+ c #D0D0D0",
+".@ c #212C6D",
+".# c #1E286A",
+".$ c #CACACA",
+".% c #283277",
+".& c #3B4783",
+".* c #253074",
+".= c #485793",
+".- c #BEBEBE",
+".; c #222C71",
+".: c #44538F",
+".> c #BCBCBC",
+"., c #6974B0",
+".< c #BABABA",
+".1 c #1E286D",
+".2 c #3E4D89",
+".3 c #848AA6",
+".4 c #5F6585",
+".5 c #4F599D",
+".6 c #B4B4B4",
+".7 c #B2B2B2",
+".8 c #394784",
+".9 c #ABADB5",
+".0 c #34417F",
+".q c #ACACAC",
+".w c #87878B",
+".e c #58649F",
+".r c #AAAAAA",
+".t c #414D8F",
+".y c #2D3978",
+".u c #6F6F70",
+".i c #57608A",
+".p c #A0A0A0",
+".a c #666871",
+".s c #283373",
+".d c None",
+".f c #CFD0D8",
+".g c #364184",
+".h c #465197",
+".j c #242F6F",
+".k c #BBBCC1",
+".l c #9A9A9A",
+".z c #313D7F",
+".x c #989898",
+".c c #A8A8AB",
+".v c #4D5480",
+".b c #52609C",
+".n c #A3A4A6",
+".m c #4E5E98",
+".M c #2B3579",
+".N c #6B739A",
+".B c #293577",
+".V c #293377",
+".C c #273175",
+".Z c #495893",
+".A c #394680",
+".S c #475691",
+".D c #717482",
+".F c #E0E1E5",
+".G c #42508C",
+".H c #DADBDF",
+".J c #1D276B",
+".K c #979DBB",
+".L c #8088AB",
+".P c #2C3673",
+".I c #5C6281",
+".U c #242F75",
+".Y c #3C457C",
+".T c #33407D",
+".R c #747474",
+".E c #41508E",
+".W c #B8B9BA",
+".Q c #646FAD",
+".! c #2E3A78",
+".~ c #808083",
+".^ c #2C3876",
+"./ c #2B3675",
+".( c #293473",
+".) c #384485",
+"._ c #242E6E",
+".` c #45518B",
+".' c #424F88",
+".] c #465082",
+".[ c #414D87",
+".{ c #2D387A",
+".} c #9FA2AB",
+".| c #2B3678",
+"X c #384288",
+"X. c #171F57",
+"XX c #343E84",
+"Xo c #DEDEE2",
+"XO c #353F7B",
+"X+ c #2F3A7F",
+"X@ c #1C2669",
+"X# c #2F3975",
+"X$ c #3E4B87",
+"X% c #D7D8DB",
+"X& c #C4C4C5",
+"X* c #4A5996",
+"X= c #36437F",
+"X- c #48548A",
+"X; c #202A70",
+"X: c #F1F1F1",
+"X> c #1F2A6F",
+"X, c #515BA0",
+"X< c #B4B4B5",
+"X1 c #3B4987",
+"X2 c #4C579B",
+"X3 c #7D7D7F",
+"X4 c #B2B2B3",
+"X5 c #3E4880",
+"X6 c #384584",
+"X7 c #495598",
+"X8 c #364382",
+"X9 c #5661A8",
+"X0 c #434F92",
+"Xq c #374079",
+"Xw c #53597A",
+"Xe c #A5A7B0",
+"Xr c #3E498D",
+"Xt c #5966A4",
+"Xy c #1E296A",
+"Xu c #1D2769",
+"Xi c #C9C9C9",
+"Xp c #929293",
+"Xa c #3B458D",
+"Xs c #3D4A85",
+"Xd c #4C5C97",
+"Xf c #E6E7EC",
+"Xg c #D4D5D7",
+"Xh c #C3C3C3",
+"Xj c #C1C1C1",
+"Xk c #232D72",
+"Xl c #465491",
+"Xz c #455490",
+"Xx c #212B70",
+"Xc c #34407C",
+"Xv c #43528E",
+"Xb c #CCCDCF",
+"Xn c #1F296E",
+"Xm c #323E7A",
+"XM c #1E296D",
+"XN c #525EA0",
+"XB c #313C79",
+"XV c #B7B7B7",
+"XC c #676A79",
+"XZ c #2A3472",
+"XA c #7C7C7D",
+/* pixels */
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d c.%.V.V.%.C.U.U.;XnXy N.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.P +X 8XXX+ L L.V.%.U.UXk.;.;XxX;Xn | u.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.dX1X0 M BX 8XXX+ L L.V.%.U.UXk.;.;XxX>X>XnXn r u.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d ZX,.5X7.h MXaX XXXXX+ L L.V.%.U.UXk.;.;XxX>X>XnXM.1.1 rX@ u.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.dX9X9X,.5X7X0 MXaX XXXXX+ L.M.V.%.U.UXk.;XxXxX>XnXnXM.1 r r r.J 5.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.dXd 6 6X9X,X2.hX0 MXa 8XXXXX+ L.M.V.C.*.UXk.;XxXxX>XnXnXM.1 r r.J.J.JX@ u.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.,., 6X9X9X,X2.h ] {Xa 8XX 1 F L.M.V.s = c :.;XxX;X>XnXnXM.1 r r.J.J.J G G 5.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.`.,.,.Q 6X9XN.5X7.h ] {Xa 8XX 1 F L m 0XOXOXB K.s.;XnX>XnXn.1 r r r.J.J G G G G 5X..d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d z.,.,., 6X9X9X,X2.hX0 MXaX 8XXX+ m Z x # f `.N @ ~ c.@XnXnXM.1 r 3 [ G G G G GXuX@ 5X..d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d V.,.,.,.Q 6X9X9X,X2.hX0 MXa 8XX 1X+ Z.' (.fX% E .Xe @ y.@XnXnXM r e._ T b rXu G GXuX@X@ 5X..d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d z.,.,.,.Q 6X9X9X,X2X7.h M {Xa 8XX , R.i ( U E.f I o j.4 y.@XnXnXM 3._Xq ).Y T [XuXu JX@X@ 5 5X..d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.`.,.,.,.Q 6X9X9XN.5X2.hX0 MXaX XXXX.&X-.L.f EXf.$ X j. Xw.P nXnXn.1 [ T ) - @Xq T.#XuXuXuX@ 5 5 5X..d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.,.,.,.Q 6 6X9XNX,X2.hX0 M {Xa 8.gX$ @ S 2 EXo.FXh &.w.RXwX# T.@ e r.@._.Y @ @ @X5 T n.# GXuXu 5 5 5.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.,.,.,.Q 6X9X9X9X,X2X7.h ] MXaX .gX$ ' S.f E YXo.H.>.X.~ / v KXBXm.(Xx.@.@.PXq @ i @XqXZ e 3 r.#.#XuXu |.d.d.d.d.d.d",
+".d.d.d.d.dXd.,.Q 6 6X9X9XNX,X2X7.hX0 MXaX *.[ > S 2X%Xb ..$XgXV.l.~ / vXqX- _X-Xm.( < c y.] @ > _.] c.@ e e 3 3Xy.# u.d.d.d.d.d",
+".d.d.d.d.d 6 6 6X9X9X9XNX,X2X7.hX0 M B *X H z S.fX%.H.W.xX4Xb.6.l.~ / v.Y >.K fX- A : : :X#.Y.N.9 @ K._.@.@.@ n nXyXu.d.d.d.d.d",
+".d.d.d.dX9 6X9X9X9XNX,.5X2X7 sX0.tXrX1 !.G > S 2.H IX4.p 9.qXbX4.l.~ /Xw A.v _ # ( x.y = :XZXq _.9 _XqXZ < < < <.@ n nXu.d.d.d.d",
+".d.d.d ZX9X9X9XNX,X9 lXtXt.e.b.b V V z z ) -.f.H.H.6 9.wX3 &.$.7.l.~ /.v yXq ~ # 2.N 0.(.C.sXB @.9.NX5 K c :.j.j < <.@.@ |.d.d.d",
+".d.d.dX,X,X,X,.5XN q.K.K.K.K.K.K.K - - -.K 2 EXbX<.xX3X3XA.n.$ .x.~ /Xw K A.o.N 2 f.[XB.s./.y.].N.N.N.]X# c c : :.j < b [.d.d.d",
+".d.d.d.5.5X2X2X7XN -X% EXfXfXfXfXfXf YXfXfXf Y.W 9.~.R dXA.pXi .x.~ /XwXm AXO _ 2.L ).&.|.|.BXO ~.N.9 _XqXZ.s = c : :.j <.d.d.d",
+".d.dX1X7X7.h.h s.b - E YXf Y.FXoXo E.H.H EXoXoXVXp.wXA.~.w &Xi .x.~ /Xw AXm $X- # `.L ) +.y.|XBX5 @ i @ Z.P k.(.s = c : : N.d.d",
+".d.dX0.hX0X0 ] ].m.KXfXf YXoX%XgXg p.+.+.+Xg.HXV 4 9.w.w 9.q.$ .x.~ /XwXOXm.{ Z.] f 2.N.& $.{ K.o.i (.i.o.^.|.B k.(.s = c.j.d.d",
+".d.P M M M M {Xr V -Xf.FXoXg.+Xb.$Xi I IXiXgXo p IXj.-XjXj.$.+.6.x.~ /Xw 0 W.{XO ~ _.K _X5XB m W.o @ i > ~Xm } }././ k.(.s c [.d",
+".d + BXaXaXaXa *Xl -XfXoXgXbX&XhXj.-.-.-Xj p YX:X:X:X:X:X:XfX%XV.x.~ /Xw Z h m WX5 @.L @ ~Xm mXB.. _ 2 #.].o h.y } }./ k.(.s [.d",
+".dX X X X 8 8.).` S YXoXg.$XjXj.-.-.>.-.-.+.F YXfXfXfXfXfXoXgXV 4X3 /Xw.oXB.z +X5 >.K.N.' Z +.TX= x # # # xXc h.!.y }.^./ k =.d",
+".d 8 8XXXXXXXX ,.[ S Y E.+XiXj.-.-.<.<.<.-XbXo.H.H.HX%X%X%Xg p.6 4X3 /Xw.o +.z.TXs.N 2 fX- ~ , ,.0X5X- # 2.NX5Xm $ $.!.y.^./ k.d",
+" cXXXXXXXXXX 1 +X$ S Y.H.+ I.-.>.<.WXV.W.<XiXgX& X.c O X.-Xb 4X3 / v.&.T ,.0.8 ) f f f ).&X8X8...' _ i _ ~Xm + W $.!.y.^./XZ",
+".%X+X+X+X+X+ F mXs.L Y.HXbX&.<.<.WXVXVXV.<X&.+.r.wX3 dXA.~ &X& X 4X3 / v.&.0X8X8.).[ x f 2 #.' RX8X=.[ @.3 @.[ 0 + +Xm W h.y.y k",
+".V L L L L L L.{.&.L YX%.$Xj.WXVXVX<.6XV.WXhXb &X3 d.u.RXA.pXh.q 4X3 / vXs.0X8.).)XsX-.N.K.N.` R.).A.' @.L @.' 0.0.T + + W h.!.^",
+".V L L L.M.M.M.| R (.FX% I.-XVXVX<.6X4X<XVXj.$.p d.u a.u.R.lXj O 4X3 / vXsX8.).).).&.` > S >X-.8 ^.&.' @.3 >.`X=.0.0.T +Xm W h.^",
+".%.V.V.V.V.V.%.B Z (.FXg I.-X<.6X4.7.7.6XVXj.$.p d.u a.u.R.lXj.rXpX3.a v.[ R ^ ^X1.&.` > S _.OXsX1.&.` @.L >.`.AX8X8.0.T + + W.!",
+".C.%.%.%.%.C.C.s 0 (.FXgX&.>.6X4.7 X4X<.-Xi.p d.u a.u.R.lXj.rXpX3.a v.[.8X1X1 !XsX- > S _ 'X$ !XsX- >.3 >X-.AX6X8X8.0.T +Xm h",
+".U.U.U.U.U.*.U = A `.F pXj.<.7 .7.6.- I.X.R.u a 7.R.lXj.rXpX3.aXw.[.8 ! ! QX$.O > S _ z.[ Q PX- >.3 >X-.&.8X6X8X=.0.0 + W",
+".U.U.U.U.U.U.U :Xm ` E pXj.W X4.- I.X.R.u a 7.R.xXj.rXpX3 /Xw P.& Q % %.2 ' _ S _ z H.t.[ ' > S _X-Xs ^.8X6X8X=.0XcXm",
+".;XkXkXkXkXkXk :XB f E pXjXV X X .7.- I.nX3 d.u dXA.pXj.rXp. .a v.'X1 % %.t.` ) #.K # z D.E H ' _ S _ 'XsX1 ^.8X6X8X=.0 +",
+"Xn.;.;.;.;.;.;.j K f E p.-XV X X X X .7.-Xi.c.w.~XA.~.w &Xj.rXp. .a.I.` P %.t.E z g ( 2 f z wXv D z _ S _ z PX$X1 ^.8 RX8.0Xc",
+"Xy.;.;.;XxXxXx bX# # E.+.-XV X X X.q.q X Xj.+ I.>.WXV.W.<XjXi XXp. .a.IX-.2.E.E.O > ( ( ( >.ZXl.:.O ) #.K.NX- P QX$X1 ^.8 RX=Xc",
+" NXxXxXxXxXxX; nXZ.N EXb.-X< X.q.q O O X X&X%.FX:X:X:X:X:Xo.+ Xp. .a.I.O H.E w V ` 2 ( g VXlXlXl V g ( 2.NX-.[ Q Q !X1.8.A RXc",
+".dX;X>X>X>X>X>.@ y # EXb.>.6.q.q O O.r X XjXg.H.F.F.FXoXoXgXb Xp. .a.I.O DX0.:.m f.K f g z.=.Z V > ( ( ( @.: t t Q PXs ^.8 R.d",
+".dXnX>X>XnXnXn.@ K ` EXb.<X4.q O O.r.r.q Xj.+.+.+.+.+.+.+Xb.$ XXp. .a.I '.GXl.O g # -.N g.ZX*.Z g ` 2 ( g z.: w.G t.2X$X1.8.A.d",
+".d |XnXnXnXnXn b K f E.$XV X & & & & &.c O.<.$.W.c &.p.n &X<X&.rXp. .a.4 '.:Xl z g `.K f g zX* V g f.K f g 'Xz.: w t Q PXs ^Xm.d",
+".d uXnXMXMXMXM nX# f.H I .r.p.p.p.p.p.n &X<Xh.pX3 d.u dXA.X.- &Xp. .a.4 '.SXl.m.e.L 2 ( g VXd V.e # -.N.m.OXlXzXv.G t QX$ ^Xq.d",
+".d.d r.1.1.1.1 [ y.N.kXe j.w.w.~.~.~.~.w 9.n.W.lXA.R 7.u d.x.- & 9. .a.4 ' z V _.L -.K q.b.m.m.m.e `.K # g.O.SXl.: w t.2X$.&.d.d",
+".d.d u.1 r r r [.P.4.} j.D.u / / / / /.u d j 4 ;.u a 7.u 4.> & 9. .a.4 z V.m ( 2.K q.e.m.m.m g >.L 2 ` g z.=Xl.: w t.2 PXq.d.d",
+".d.d.d r r r rXy._.Y.i vXwXwXwXwXwXwXwXw v.D j j 9X3.u.u.u 4.< & 9 ;.a.I z.m g.L 2 - l g.m.b.e.N.L.L.L _.m.Z.=.SXzXv.G H P.d.d.d",
+".d.d.dX@ r.J.J G r._ T TXZ.P yX# K KXmXq.Y v.D.w & 9 d.R.u 4.< & 9 ;.a.I '.m @.L 2.L.e.m.b.bXt.L 2.L > gXdX*.Z.SXzXv.G HXs.d.d.d",
+".d.d.d u.J.J.J.J G G 3 3 [ n b._ : =XZX#XO.] v.D.w 9 9.~ ;.l.< & 9 ; a.4 ) > ( S.K q.b.m.b g l.L 2.L.e.mXdX*.Z.SXzXv.G H...d.d.d",
+".d.d.d.d 5.J.J G G G G G r e.@.j : =.s.B } 0X5 v.D.w.nXp.~.p.> & 9 ; a.4 g ` 2 - q.e.m.m.b.e _ S 2 (.eXdXdX*.Z.SXzXv.G P.d.d.d.d",
+".d.d.d.d.dX@ G G G G G G r e.@.; :.*.s.B.| W 0.] v.D.w j.x &XV.p 9 ; a.4 ) _.L q.e.b.m.b.e.N (.L.L _ gXdXdX*.Z.SXz w H.d.d.d.d.d",
+".d.d.d.d.d u G G G GXu G r e.@ < :.*.s.B.|.y $ Z ~.I.D j X .X 9 ; a.4 z g.e.mXdXd.m g > (.K ( >.e.mXdXdX*.=Xl.: w...d.d.d.d.d",
+".d.d.d.d.d.d 5 GXuXu JXu.# e.@ < : c.C.B.| }.!Xm.o.v.I.D j.X .X.w d a.4 ' ' z.=X* V.m > ` ` ( _ g.mXdXdX*.Z.S.O.: H.d.d.d.d.d.d",
+".d.d.d.d.d.d.d 5X@X@X@Xu G 3.@ <.j :.C k.B }.{ $ +...].I.D j X.l.w d a.I ' wXl.=.Z z g f.K ` > g.mXdXdX*.Z.=.SXz D.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.dX. 5X@X@X@Xu r e.@.j : =.(.B.|.y $ mXc...v.I.D.w.~ d / a.IX- DXlXl.=.=Xd > # > gXdXdXdX*.Z.=.SXz w.Y.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.dX. 5 5 5Xu.# e.@ < : c.s k.|.{ $ m +.0X5.] vXC.a a a a vX- D.:XlXl.S.= V.mXd VX*X*X*.Z.=.SXl w.Y.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.dX. 5 5 5.# 3.@ <.j c.s k.| }.! $ + + 0X5.v v v v v v x.` D w.:XlXl.S.S.S.Z.=.Z.Z.=.S.SXz w.Y.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.dX. 5 5Xu 3 n <.j : =.(.B }.y $ m +.T.0.A ~ ~ ~.[.'.' Q t.G w.:XzXlXl.S.S.S.S.SXl.OXz w.Y.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.dX. 5XuXy n.@ < : c.s k./ }.! $ + +.0.0 0 C.A.&.&XsX$ Q t.G wXv.:.:XzXzXzXzXz.:.: D.Y.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d |.#Xy n <.j : =.(./ }.y $ W +.T.0X8X8X6.8 ^X1X$ Q Q t t.G w wXvXvXvXv w w H.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d uXu n.@ < : c.s k./ }.! $Xm +.T.0X8X8X6.8 ^X1 ! P.2 Q t t t.G.G.G.G H...d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.dXu.@ b.j : =.( k.^.y.! W + +.T.0X=X8X6.8 ^X1XsX$ P Q.2.2 H H H P.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d | [ < : c.s.(./.^.y h WXm +.T.0X=X8 R.8.8 ^X1XsX$X$ P PXs...d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d N.j c.s k./.^.y h W + +.0.0X=X8 R.A.8.8 ^ ^.&Xq.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d [ [ = k./.y.! h WXm +Xc.0.0X= R R.AXmXq.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d",
+".d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.dXZ k.^.^.! h WXm +XcXcXc.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d"
+};
diff --git a/arts/builder/pics/Synth_PLAY_AKAI.xpm b/arts/builder/pics/Synth_PLAY_AKAI.xpm
new file mode 100644
index 00000000..a7cedce2
--- /dev/null
+++ b/arts/builder/pics/Synth_PLAY_AKAI.xpm
@@ -0,0 +1,317 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 246 2",
+/* colors */
+" c #27326F",
+" . c #68D14E",
+" X c #303E7B",
+" o c #2E3A79",
+" O c #3B4889",
+" + c #2A3675",
+" @ c #293474",
+" # c #51FD0F",
+" $ c #273272",
+" % c #374285",
+" & c #4FFB0D",
+" * c #4EFB0C",
+" = c #44A73B",
+" - c #323E80",
+" ; c #434E94",
+" : c #202A6B",
+" > c #3E4A8F",
+" , c #1C2667",
+" < c #4BCA27",
+" 1 c #3D4B84",
+" 2 c #52F913",
+" 3 c #375074",
+" 4 c #45538F",
+" 5 c #1F2A6D",
+" 6 c #2F3A80",
+" 7 c #323D79",
+" 8 c #1E286C",
+" 9 c #414F8B",
+" 0 c #46ED07",
+" q c #46EB07",
+" w c #4CB935",
+" e c #3B4985",
+" r c #4C5999",
+" t c #4B5998",
+" y c #1A235E",
+" u c #3A5970",
+" i c #43DC0E",
+" p c #44CF19",
+" a c #384582",
+" s c #232E74",
+" d c #445191",
+" f c #323F7C",
+" g c #656FB8",
+" h c #6F76A4",
+" j c #408551",
+" k c #5CFE19",
+" l c #538967",
+" z c #56FE13",
+" x c #374384",
+" c c #46B332",
+" v c #303B7D",
+" b c #1D2767",
+" n c #2B3778",
+" m c #5BE22F",
+" M c #44E30B",
+" N c #4AF40A",
+" B c #42508B",
+" V c #1E296B",
+" C c #51629D",
+" Z c #48F208",
+" A c #1D276A",
+" S c #50609C",
+" D c #404E89",
+" F c #47EE07",
+" G c #2A357A",
+" H c #283378",
+" J c #29366F",
+" K c #263176",
+" L c #242F74",
+" P c #465492",
+" I c #222D72",
+" U c #202B70",
+" Y c #43508F",
+" T c #41508D",
+" R c #30496F",
+" E c #3E4C8A",
+" W c #52955B",
+" Q c #2D3876",
+" ! c #45EA08",
+" ~ c #45E808",
+" ^ c #5D68AF",
+" / c #3C4F7E",
+" ( c #4C569B",
+" ) c #394685",
+" _ c #4B845E",
+" ` c #4EEC14",
+" ' c #404E8F",
+" ] c #1E2867",
+" [ c #293475",
+" { c #283474",
+" } c #253071",
+" | c #4FF90E",
+". c #475E85",
+".. c #4A756A",
+".X c #4DF90C",
+".o c #4BF50A",
+".O c #4AF509",
+".+ c #1E286A",
+".@ c #49F108",
+".# c #1C2668",
+".$ c #4BD51E",
+".% c #4D5D98",
+".& c #293478",
+".* c #4C5B97",
+".= c #45D318",
+".- c #3B4783",
+".; c #273276",
+".: c #5B67A9",
+".> c #263075",
+"., c #485793",
+".< c #222C71",
+".1 c #44538F",
+".2 c #202A6F",
+".3 c #1F2A6E",
+".4 c #42518D",
+".5 c #1D286C",
+".6 c #699088",
+".7 c #45ED07",
+".8 c #3D4B88",
+".9 c #406B63",
+".0 c #4B5B99",
+".q c #34417F",
+".w c #505BA1",
+".e c #3C498A",
+".r c #6175A1",
+".t c #4EA645",
+".y c #45D814",
+".u c #3A5E6A",
+".i c None",
+".p c #242F6F",
+".a c #4A647D",
+".s c #4DF80B",
+".d c #232D6E",
+".f c #4CF80A",
+".g c #4CF60A",
+".h c #334077",
+".j c #556795",
+".k c #1E2969",
+".l c #2D397B",
+".z c #4E5E98",
+".x c #5DB950",
+".c c #38447F",
+".v c #242F72",
+".b c #34427B",
+".n c #43528D",
+".m c #1E296C",
+".M c #1D276B",
+".N c #60EB2E",
+".B c #404E8A",
+".V c #2C377D",
+".C c #47EE08",
+".Z c #5CF620",
+".A c #1D2661",
+".S c #4C5C99",
+".D c #485895",
+".F c #28346F",
+".G c #475694",
+".H c #364480",
+".J c #48598B",
+".K c #43954A",
+".L c #33407D",
+".P c #222C69",
+".I c #303C7A",
+".U c #808CAE",
+".Y c #2E3A78",
+".T c #2B3875",
+".R c #45E609",
+".E c #2B3675",
+".W c #53FD10",
+".Q c #44BF26",
+".! c #465296",
+".~ c #25306F",
+".^ c #757EA3",
+"./ c #496C71",
+".( c #42587E",
+".) c #2E3A7B",
+"._ c #2D387A",
+".` c #48E40F",
+".' c #3C468C",
+".] c #1B2465",
+".[ c #4A5B93",
+".{ c #46C821",
+".} c #273274",
+".| c #232E70",
+"X c #171F57",
+"X. c #46558F",
+"XX c #458D52",
+"Xo c #222C6F",
+"XO c #212C6E",
+"X+ c #52CE30",
+"X@ c #313C81",
+"X# c #43538C",
+"X$ c #6C9F7F",
+"X% c #48F108",
+"X& c #1C2669",
+"X* c #47EF07",
+"X= c #4F5F9B",
+"X- c #3F4D88",
+"X; c #4B5B97",
+"X: c #44DE0E",
+"X> c #273277",
+"X, c #495995",
+"X< c #253075",
+"X1 c #475793",
+"X2 c #384A77",
+"X3 c #465592",
+"X4 c #36417F",
+"X5 c #5663A5",
+"X6 c #212C71",
+"X7 c #4CE019",
+"X8 c #41765B",
+"X9 c #405282",
+"X0 c #41626F",
+"Xq c #45E708",
+"Xw c #394785",
+"Xe c #439D42",
+"Xr c #596D97",
+"Xt c #545FA6",
+"Xy c #334475",
+"Xu c #334275",
+"Xi c #427F55",
+"Xp c #394588",
+"Xa c #263172",
+"Xs c #38467D",
+"Xd c #354184",
+"Xf c #343F83",
+"Xg c #333F82",
+"Xh c #202B6C",
+"Xj c #49F408",
+"Xk c #1F296B",
+"Xl c #49F208",
+"Xz c #567E79",
+"Xx c #2F4074",
+"Xc c #51609C",
+"Xv c #1D2769",
+"Xb c #48F007",
+"Xn c #4A5A95",
+"Xm c #4C7D65",
+"XM c #475692",
+"XN c #232D72",
+"XB c #212B70",
+"XV c #1F296E",
+"XC c #1E296D",
+"XZ c #2D3A75",
+"XA c #48DD14",
+"XS c #3E517F",
+/* pixels */
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.iXa.; H H H K L s.<.2 V b.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.E fXpXdXf 6.V G HX>X< LXN.<X6 U.2XV.A y.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i O ; >.'XpXdXf 6.V G HX>X< LXN.<X6 U.2.2XVXV 8 y.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.iX4.w.w ( ; >.'XpXdX@ 6.V G HX>X< LXN.<X6 U.2.2XVXC 8 8 8X& y.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.iX5X5.w (.! ; >.'XpXfX@ 6.V G HX>X< LXN.<XB U.2.3XVXC 8 8 8.5.M.#.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i r ^ ^Xt.w (.! ; >.'XpXfX@ 6.V G H KX< LXN.<XB U.2XVXVXC 8 8 8.M.M.MX& y.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i g g ^.:Xt.w (.! ; >.' %XfX@ 6.V G H KX< LXN.<XB.2.2XVXVXC 8 8 8.M.M.M A A ,.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i B g g g ^X5Xt.w (.! ; >Xp %XfX@ 6.V G H.>X< s IX6XB.2.2XVXV 8 8 8.5.M.M A A A A.#X .i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.[ g g g ^.:Xt.w (.! ; >.'XpXd - 6.V G HX>.> L s IX6XB.2.3XVXC 8 8 8.M.M.M A A AXvX& ,X .i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.* g g g g ^X5Xt.w (.! ; >.'Xp a.-.q.V G HX>X< LXN.<XB U.2.3XVXC 8 8 8.M.M.M A A AXvX&X& ,X .i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.[ g g g g ^.:Xt.w (.! ; >.'Xp 1X0...( f.& H KX< LXN.<XB.2.2XVXVXC 8 8.M.M.M A A AXvX&X&X&.# ,X .i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i B g g g g ^.:XtXt.w C r ; >.' a / _.x..Xs nX>.>X< s IX6XB.2.3XVXV 8 8 8 8 8.M.M A A AXvXvX&.#.# ,X .i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i g g g g ^.:X5X5X5.r.6Xr P.'Xp.H 3 _.x...b [X>X< LXN.<X6 U.2.3XVXVXCXC 8.m.m.m 8 8 8 8.+ AXvXv.#.# ,.i.i.i.i.i.i.i",
+".i.i.i.i.i.i g g g g ^ ^.:.:.:X5.6X$.6., OXp.q 3XXX+Xm.b @ KX<.vXN.<XB U.2.2.2.2.2.2.2.2.2 5 5 5 : 5.mXk 8.+.+XvXv.].i.i.i.i.i.i",
+".i.i.i.i.i r g g ^ ^.:.: h.6.rXr.6 ..6X. OXdXs uXXX+Xm.b {.> L sXN.<XBXBXBXBXBXBXBXBXoXoXoXoXoXOXOXOXhXh : :XkXk.+.+ y.i.i.i.i.i",
+".i.i.i.i.i ^ ^ ^.:X5Xt.:.^X$.6XrX$ ..6.J.8Xd /.u.KX+Xm.h $X< L sXNXN.<.<.<XNXN.|.|.|.|.|.|.|.|.|.|.dXo.dXoXOXhXh : : ].i.i.i.i.i",
+".i.i.i.iX5 ^.U.UXtXt.w.:.6 .X$XrX$ . lX9 1 x.a.K.tX+Xm.h $ L L.v.v.v.v.v.v.v.v.v.v.v.v.v.v } }.v.v.v.v.p.|.|.d.dXOXh : ].i.i.i.i",
+".i.i.iX4X5Xt.U.U.w.w (X5.6 .X$XrX$ . W.( /.-XzX+X+ mXm.h $X< L LX<X<X<X<X<.>.>.>.>.>.>.>.}.}.}XaXaXaXa } } }.p.p.|.dXOXh.A.i.i.i",
+".i.i.i.w.w.w.w.w ( (.GXc.6 . .X$ . . W 3 /X9 l m m m _Xy J.>.>.>.>.>.>.}.} {.} [.;.;.;.;.; [ [ [ [ {.}.}.}XaXa } }.p.d.d :.i.i.i",
+".i.i.i.w ( ( ( (.!.! d.z.6 . ..N.N mXX 3 3.( l m m mXi RXx {.}.;X>X>.;.&.Y 7.Y n.&.&.&.&.&.&.&.& [ [ [ [ { {.} $Xa } }.p.d.i.i.i",
+".i.i O ( %.!.U.U ; ; d.zX$ ..N.N.N mXe.uX8 l.x.Z.Z ` =Xi.u R J H [ + Q.IX2X0 3.I n n n n n n n n n n n n + [ [ { { $Xa }.~.A.i.i",
+".i.i ; ;Xf ;.U.U > >XM.jX$.N.N k.Z.N.tX8.tX+ m 2 2 2X7 < j RXx n.Y f.h.bX0.K./.b Q.l.l.l.l.l.l.l.l._._ n n n n + [ @ { $Xa.~.i.i",
+".i.E > >X@ >.U.U.' '.j.6.x.N.Z k.Z.ZX+ =X+ m `.W.W | `X7 c j.u.h 3./.(X2./ _X0Xs.h.Y o.) v v v v.).) o.l o._ n n.E + @ @ $ $.P.i",
+".i f.'.'.).'.U.UXp BXz . m.Z k k k k.Z ` 2 2.W.W # #.X.g.$ w _ /.. W..XS./XmX0XsX2Xy.b X v v v v v v v v.) o o o n n.E + @ {.P.i",
+".iXpXpXpXpXp % % )X#Xz ..N k k k k k 2 2 2.W # # # &.X.gX7 < _.(Xm.t _./..Xm./XSX0X8 u.H.b f f - - - - v v v.).I o.Y Q.T.E @ $.i",
+".iXdXdXdXfXfXfXf 1. l m.Z k k k z z z z.W.W # # & &.X.gX7.$ WX0 _ w WXmXmXm./.(...t.. /.-.-.HXg.q.q - - - f X v.) o o.Y Q.E @.i",
+"XaXfXfX@.;X@.^.U.a l.x.N.Z k k z z z z.W.W # & &.X.X.g.o `X7 w W.t w W.. _ W...(Xm = _X0X0./.( a.q.H.q.q.q -.L f X.I.I o.Y Q.T.F",
+".; 6 6 6.} 6.^.UXz . m k k z z z z.W.W.W # # &.X.s.g.o.o.@.@X7.$.$ < W.a _ w _.( _ w.KX8XX.t.. /.H x xXd.H.q.q.q.L f X.I o.Y Q +",
+" H.V.V.V.v.V.^.U lX+ m z z z z.W.W.W # # & &.X.s.g.o.o NXl.@.`.`XAX7 w W.t <XX./.K.{ c = c wXX uX2XsXsXs.bXs.b.b.h f f X.I o.Y.T",
+" H G G.v.| G.^.U l m.Z z.W.W.W.W # # # & *.X.s.g.o.o N NXlXlX%X%.C qXA.$.=.= =X8 =.=.y.y.y.=Xe.9X0 u u uXSXS / 3 /XsXs f X.I o Q",
+" H H H H [XZ.u _.x.Z 2.W.W # # # # & *.X.s.s.g.o.o N NXl.@X%XbX* 0 q.`.`XAX:.Q =.QX:X:X:X: i.QXeXe.K.K.KXX _XXXXXi..X0Xs f X.I.Y",
+" KX>X>.^.^ R jX+X7 2.W # # # & & * *.X.s.g.g.o.o N NXlXlX%X%X*X* F F 0 0 q ~ MX7.`XqXq ~.R.RX:X7X7.= p.$.$ <.$ p.QX+X$.^.^ f X o",
+" LX<X<.^ h R jX+X7 2 | # & & * *.X.s.g.g.o.o N NXlXl.@X%XbX*X* F F 0 0 q q ~ MX7.`XqXq ~.R.R.`X7X7.= p.$.$ <.$ p.QX+X$.^.^.q f.I",
+" s L L L.~ R j <X7 | | & * *.X.X.f.g.o.o.O NXlXlXlXlX%X%X*X* F F 0 0 q q ~ ~ M.yX:.RXq ~.R.R i.y.=.= p p p.{.{ p.Q c j 3.b.q.L X",
+".<XNXNXN.| J.6X$.t ` `.X.X.s.f.g.o.o.O.O NXlXl ZX%X%XbX*X* F F 0 q ~.`XAX:X:.Q =.Q i iX: i i.QXeXe.K.K.K jXi j.K _X8.uXx.TX4.q f",
+".2.<.<.<.<XN.^.^Xi.$ `.f.g.g.o.o.O.O N NXlXlX%X%X%X%X*X* F F 0 0 ~.RXA.$.=.= =Xm =.=.=.y.= pXe././.a.a.(. . .(.(.(X9 1.- a.H.q f",
+" VX6X6X6XBXB h.^X8 <X7.o.o.o.O.O NXjXlXlXlX%X%XbX*X*X* F q !.`XAXA.y w W.t < W./ W.{ c = c w _. . X# B B D DX9 1 1 1 e.- a a.H.L",
+" b U U U U U h.^.9 w.$ N N.O N NXlXlXlXlX%X%XbXbX*X* F F ! ~XA.$.$ < W.a l w l.a l w.KXm W.tXz.[ 4X3 P d d Y.4 9 E E.8 e.- a.H.L",
+".i.2.2.2.2.2Xh } 3X8.tX7 `XjXlXlXl ZX%X%XbX*X*X* F F.7 qXA.= w W.t w WXz l WXz.a l.t l.aXzXz.j.[X3.GX1X3 P.1.n.4 9 EX- e e a a.i",
+".iXV.2.2.3XVXV.2 JXyXi.$X7XlXlXlX%X%XbXbX*X* F F F F ! ~.=.Q W.a l w W l l lXz.jXz.tXz.[.[.[XnX,.D.D.D.GX3 P.1.n B.BX-.8 e.-.c.i",
+".i.AXVXVXVXV h h.d JX8 <.$.CX*X%X* F !.R ~ q.7 0 0 q.RX: c.K... Xm.t lXzXz lXz.[.aXm.a.*.[.[Xn tX;X;X,.DX1X3 P.1.4 9 EX- e e.h.i",
+".i yXVXCXCXC h h : .9 w <.C.CXb F 0 MX: M q q 0 q q M.yXe.u.(X9./ WXz. Xz l.a.[.[. .[X; t.S.S.S.S.*X;Xn.DX1X3 4.n B.BX-.8 e.h.i",
+".i.i 8 8 8 8 h hXk.P RX8.tXA.`X* ~ M.{ =.Q.=X: ~ ~ ~.y.{.K uX9 D. ./.a. ./ WXz.[.[.[Xn.0.SX=X=X=X=.S.SX;Xn.,XM P.1.4 9X-.8.-.i.i",
+".i.i y 8 8 8 h h 8 b J RXi.$XAX* M.y =X8Xe.Q.=.R.R.R.=.Q j.(X- E.B BX#X#./ WXz.z.,.0.S.SX=X=X=X=X=X=.S.SX;.D.,X3.1.n 9X-X-.b.i.i",
+".i.i.i 8 8 8 8.5.M A.P JXi.{.$.`.y.=Xe.uX8Xi =XAXAXA = _.9 / e.e EX- BX.. Xz.j.[X,.0.SX=X= S C C C SX=.%X;Xn.,XM 4.n B.BX-.i.i.i",
+".i.i.iX&.5.M.M.M.M.M ] JX8 <.{.$.= p j R R 3XX.{.{.{ _.(XS e O E E ' Y dXM.[.[X, t.SX=X= S C C C C CX=X=.SXn.DXM 4.n B.B 1.i.i.i",
+".i.i.i y.M.M h h.M , ] JX8 w =XX =.{ j R RX2 _.{.{.{ _X9XsXw O E E T Y Y.1 4XM.D t.SX=X= C C C C C C SX=.SXn.DXM 4.n B.BXs.i.i.i",
+".i.i.i.i.#.M h h A , ] J.9 cXi.uXi c j R RXy _ < < <Xm 1.cXw O E E ' Y d PX3.DX, t.SX=X= C C CX5 C C SX=.SXn.DXM 4.n BX-.i.i.i.i",
+".i.i.i.i.iX& A A A A ].F.9XeX8 3Xi cX8 RXyXyX8.Q.Q <Xm 1.cXw O.e E ' T d dX3X1.DX;.SX=X= C C C C C CX=.z.*Xn.,XM 4.n D.i.i.i.i.i",
+".i.i.i.i.i y A A A A ].F.u.K.9 RX8 =.9XuXyXyX8 c.Q <Xm 1.cXw O.e E 9 T Y dX3.G.DX;.*.SX= S C C C C SX=.%X;Xn.,X3 4.nXs.i.i.i.i.i",
+".i.i.i.i.i.i , AXvXv ].P R.u 3Xx.9Xe.9.h.h 7.u j =.QXm 1.c ) O.e E E T Y d PX1.DX,X;.S.SX=X= S SX=X=.z.*Xn.DXMX..1 D.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.#X&X&.#.+.P J J.u.KX0.hXZ QXy.u j c.. 1.c )Xw O E E 9 T.1 dX3.G.DXnX;.S.%X=X=X=.z.%.*XnXn.,X3 4 B.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.iX ,X&X&.#Xv.k.P R.uX2XZ.E nXx u j =.. 1.H )Xw e.e E E T.4 d PX3X1.DXnX;X;.S.S.S.*X;XnXn.,XM 4.nXs.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.iX ,.#.#Xv.+ :.d.F.T @ @ @ nXZ RX8Xe./.-.H a ) e O.8 E 9 T Y.1 PX3X1.,.DXnXnXnXnXnXn.D.,XMX..nXs.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.iX ,.#.#.+XkXh.d.~ } $ [ n.TXx.u.9.(.c.q x )Xw O.8 E E 9.4.n.1 PX3XM.,.,.D.D.D.,.,XMX3 4.nXs.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.iX ,.#XvXkXh.d.p } $ { +.T.Y.h.b.b.q.q x a )Xw e.8 E E 9.4.n.1 4 PX3XMXMXMXMXMX3X. 4.nXs.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.iX ,Xv.+ :XO.| }Xa { [.E n.Y.Y.I f.q.q x a ) e e.8 E E 9 B.4.n.1.1 4 4 4 4 4 4.1 BXs.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.].+ :Xh.d.p } $ @ + n.Y o.I f.L.q.H a aXw e e.8 E E.B 9 B.4.n.n.n.n.n.n.n D.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i y ] :XO.d }Xa { @.E Q o.I X f.L.q.H a aXw e e.8X-X- E.B 9 9 B B B B DXs.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i ]Xh.d.p } $ @ +.T.Y o.I X f.L.q.H a aXw e e e.8X-X-X-X-.B.B.BX-.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.A :.d.~Xa $ @.E Q.Y o.I X f.L.q.H a a a.- e e e.8.8X-X- 1Xs.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.A.~ $ { @.E Q.Y o.I X f.q.qX4.H a a a.- e e.-.b.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.P.P $ @.T Q.Y o.I X f.L.q.q.H.H a.c.h.h.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.F +.T Q.Y o.I X f f.L.L.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i"
+};
diff --git a/arts/builder/pics/Synth_PLAY_AKAIS.xpm b/arts/builder/pics/Synth_PLAY_AKAIS.xpm
new file mode 100644
index 00000000..a7cedce2
--- /dev/null
+++ b/arts/builder/pics/Synth_PLAY_AKAIS.xpm
@@ -0,0 +1,317 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 246 2",
+/* colors */
+" c #27326F",
+" . c #68D14E",
+" X c #303E7B",
+" o c #2E3A79",
+" O c #3B4889",
+" + c #2A3675",
+" @ c #293474",
+" # c #51FD0F",
+" $ c #273272",
+" % c #374285",
+" & c #4FFB0D",
+" * c #4EFB0C",
+" = c #44A73B",
+" - c #323E80",
+" ; c #434E94",
+" : c #202A6B",
+" > c #3E4A8F",
+" , c #1C2667",
+" < c #4BCA27",
+" 1 c #3D4B84",
+" 2 c #52F913",
+" 3 c #375074",
+" 4 c #45538F",
+" 5 c #1F2A6D",
+" 6 c #2F3A80",
+" 7 c #323D79",
+" 8 c #1E286C",
+" 9 c #414F8B",
+" 0 c #46ED07",
+" q c #46EB07",
+" w c #4CB935",
+" e c #3B4985",
+" r c #4C5999",
+" t c #4B5998",
+" y c #1A235E",
+" u c #3A5970",
+" i c #43DC0E",
+" p c #44CF19",
+" a c #384582",
+" s c #232E74",
+" d c #445191",
+" f c #323F7C",
+" g c #656FB8",
+" h c #6F76A4",
+" j c #408551",
+" k c #5CFE19",
+" l c #538967",
+" z c #56FE13",
+" x c #374384",
+" c c #46B332",
+" v c #303B7D",
+" b c #1D2767",
+" n c #2B3778",
+" m c #5BE22F",
+" M c #44E30B",
+" N c #4AF40A",
+" B c #42508B",
+" V c #1E296B",
+" C c #51629D",
+" Z c #48F208",
+" A c #1D276A",
+" S c #50609C",
+" D c #404E89",
+" F c #47EE07",
+" G c #2A357A",
+" H c #283378",
+" J c #29366F",
+" K c #263176",
+" L c #242F74",
+" P c #465492",
+" I c #222D72",
+" U c #202B70",
+" Y c #43508F",
+" T c #41508D",
+" R c #30496F",
+" E c #3E4C8A",
+" W c #52955B",
+" Q c #2D3876",
+" ! c #45EA08",
+" ~ c #45E808",
+" ^ c #5D68AF",
+" / c #3C4F7E",
+" ( c #4C569B",
+" ) c #394685",
+" _ c #4B845E",
+" ` c #4EEC14",
+" ' c #404E8F",
+" ] c #1E2867",
+" [ c #293475",
+" { c #283474",
+" } c #253071",
+" | c #4FF90E",
+". c #475E85",
+".. c #4A756A",
+".X c #4DF90C",
+".o c #4BF50A",
+".O c #4AF509",
+".+ c #1E286A",
+".@ c #49F108",
+".# c #1C2668",
+".$ c #4BD51E",
+".% c #4D5D98",
+".& c #293478",
+".* c #4C5B97",
+".= c #45D318",
+".- c #3B4783",
+".; c #273276",
+".: c #5B67A9",
+".> c #263075",
+"., c #485793",
+".< c #222C71",
+".1 c #44538F",
+".2 c #202A6F",
+".3 c #1F2A6E",
+".4 c #42518D",
+".5 c #1D286C",
+".6 c #699088",
+".7 c #45ED07",
+".8 c #3D4B88",
+".9 c #406B63",
+".0 c #4B5B99",
+".q c #34417F",
+".w c #505BA1",
+".e c #3C498A",
+".r c #6175A1",
+".t c #4EA645",
+".y c #45D814",
+".u c #3A5E6A",
+".i c None",
+".p c #242F6F",
+".a c #4A647D",
+".s c #4DF80B",
+".d c #232D6E",
+".f c #4CF80A",
+".g c #4CF60A",
+".h c #334077",
+".j c #556795",
+".k c #1E2969",
+".l c #2D397B",
+".z c #4E5E98",
+".x c #5DB950",
+".c c #38447F",
+".v c #242F72",
+".b c #34427B",
+".n c #43528D",
+".m c #1E296C",
+".M c #1D276B",
+".N c #60EB2E",
+".B c #404E8A",
+".V c #2C377D",
+".C c #47EE08",
+".Z c #5CF620",
+".A c #1D2661",
+".S c #4C5C99",
+".D c #485895",
+".F c #28346F",
+".G c #475694",
+".H c #364480",
+".J c #48598B",
+".K c #43954A",
+".L c #33407D",
+".P c #222C69",
+".I c #303C7A",
+".U c #808CAE",
+".Y c #2E3A78",
+".T c #2B3875",
+".R c #45E609",
+".E c #2B3675",
+".W c #53FD10",
+".Q c #44BF26",
+".! c #465296",
+".~ c #25306F",
+".^ c #757EA3",
+"./ c #496C71",
+".( c #42587E",
+".) c #2E3A7B",
+"._ c #2D387A",
+".` c #48E40F",
+".' c #3C468C",
+".] c #1B2465",
+".[ c #4A5B93",
+".{ c #46C821",
+".} c #273274",
+".| c #232E70",
+"X c #171F57",
+"X. c #46558F",
+"XX c #458D52",
+"Xo c #222C6F",
+"XO c #212C6E",
+"X+ c #52CE30",
+"X@ c #313C81",
+"X# c #43538C",
+"X$ c #6C9F7F",
+"X% c #48F108",
+"X& c #1C2669",
+"X* c #47EF07",
+"X= c #4F5F9B",
+"X- c #3F4D88",
+"X; c #4B5B97",
+"X: c #44DE0E",
+"X> c #273277",
+"X, c #495995",
+"X< c #253075",
+"X1 c #475793",
+"X2 c #384A77",
+"X3 c #465592",
+"X4 c #36417F",
+"X5 c #5663A5",
+"X6 c #212C71",
+"X7 c #4CE019",
+"X8 c #41765B",
+"X9 c #405282",
+"X0 c #41626F",
+"Xq c #45E708",
+"Xw c #394785",
+"Xe c #439D42",
+"Xr c #596D97",
+"Xt c #545FA6",
+"Xy c #334475",
+"Xu c #334275",
+"Xi c #427F55",
+"Xp c #394588",
+"Xa c #263172",
+"Xs c #38467D",
+"Xd c #354184",
+"Xf c #343F83",
+"Xg c #333F82",
+"Xh c #202B6C",
+"Xj c #49F408",
+"Xk c #1F296B",
+"Xl c #49F208",
+"Xz c #567E79",
+"Xx c #2F4074",
+"Xc c #51609C",
+"Xv c #1D2769",
+"Xb c #48F007",
+"Xn c #4A5A95",
+"Xm c #4C7D65",
+"XM c #475692",
+"XN c #232D72",
+"XB c #212B70",
+"XV c #1F296E",
+"XC c #1E296D",
+"XZ c #2D3A75",
+"XA c #48DD14",
+"XS c #3E517F",
+/* pixels */
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.iXa.; H H H K L s.<.2 V b.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.E fXpXdXf 6.V G HX>X< LXN.<X6 U.2XV.A y.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i O ; >.'XpXdXf 6.V G HX>X< LXN.<X6 U.2.2XVXV 8 y.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.iX4.w.w ( ; >.'XpXdX@ 6.V G HX>X< LXN.<X6 U.2.2XVXC 8 8 8X& y.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.iX5X5.w (.! ; >.'XpXfX@ 6.V G HX>X< LXN.<XB U.2.3XVXC 8 8 8.5.M.#.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i r ^ ^Xt.w (.! ; >.'XpXfX@ 6.V G H KX< LXN.<XB U.2XVXVXC 8 8 8.M.M.MX& y.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i g g ^.:Xt.w (.! ; >.' %XfX@ 6.V G H KX< LXN.<XB.2.2XVXVXC 8 8 8.M.M.M A A ,.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i B g g g ^X5Xt.w (.! ; >Xp %XfX@ 6.V G H.>X< s IX6XB.2.2XVXV 8 8 8.5.M.M A A A A.#X .i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.[ g g g ^.:Xt.w (.! ; >.'XpXd - 6.V G HX>.> L s IX6XB.2.3XVXC 8 8 8.M.M.M A A AXvX& ,X .i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.* g g g g ^X5Xt.w (.! ; >.'Xp a.-.q.V G HX>X< LXN.<XB U.2.3XVXC 8 8 8.M.M.M A A AXvX&X& ,X .i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.[ g g g g ^.:Xt.w (.! ; >.'Xp 1X0...( f.& H KX< LXN.<XB.2.2XVXVXC 8 8.M.M.M A A AXvX&X&X&.# ,X .i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i B g g g g ^.:XtXt.w C r ; >.' a / _.x..Xs nX>.>X< s IX6XB.2.3XVXV 8 8 8 8 8.M.M A A AXvXvX&.#.# ,X .i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i g g g g ^.:X5X5X5.r.6Xr P.'Xp.H 3 _.x...b [X>X< LXN.<X6 U.2.3XVXVXCXC 8.m.m.m 8 8 8 8.+ AXvXv.#.# ,.i.i.i.i.i.i.i",
+".i.i.i.i.i.i g g g g ^ ^.:.:.:X5.6X$.6., OXp.q 3XXX+Xm.b @ KX<.vXN.<XB U.2.2.2.2.2.2.2.2.2 5 5 5 : 5.mXk 8.+.+XvXv.].i.i.i.i.i.i",
+".i.i.i.i.i r g g ^ ^.:.: h.6.rXr.6 ..6X. OXdXs uXXX+Xm.b {.> L sXN.<XBXBXBXBXBXBXBXBXoXoXoXoXoXOXOXOXhXh : :XkXk.+.+ y.i.i.i.i.i",
+".i.i.i.i.i ^ ^ ^.:X5Xt.:.^X$.6XrX$ ..6.J.8Xd /.u.KX+Xm.h $X< L sXNXN.<.<.<XNXN.|.|.|.|.|.|.|.|.|.|.dXo.dXoXOXhXh : : ].i.i.i.i.i",
+".i.i.i.iX5 ^.U.UXtXt.w.:.6 .X$XrX$ . lX9 1 x.a.K.tX+Xm.h $ L L.v.v.v.v.v.v.v.v.v.v.v.v.v.v } }.v.v.v.v.p.|.|.d.dXOXh : ].i.i.i.i",
+".i.i.iX4X5Xt.U.U.w.w (X5.6 .X$XrX$ . W.( /.-XzX+X+ mXm.h $X< L LX<X<X<X<X<.>.>.>.>.>.>.>.}.}.}XaXaXaXa } } }.p.p.|.dXOXh.A.i.i.i",
+".i.i.i.w.w.w.w.w ( (.GXc.6 . .X$ . . W 3 /X9 l m m m _Xy J.>.>.>.>.>.>.}.} {.} [.;.;.;.;.; [ [ [ [ {.}.}.}XaXa } }.p.d.d :.i.i.i",
+".i.i.i.w ( ( ( (.!.! d.z.6 . ..N.N mXX 3 3.( l m m mXi RXx {.}.;X>X>.;.&.Y 7.Y n.&.&.&.&.&.&.&.& [ [ [ [ { {.} $Xa } }.p.d.i.i.i",
+".i.i O ( %.!.U.U ; ; d.zX$ ..N.N.N mXe.uX8 l.x.Z.Z ` =Xi.u R J H [ + Q.IX2X0 3.I n n n n n n n n n n n n + [ [ { { $Xa }.~.A.i.i",
+".i.i ; ;Xf ;.U.U > >XM.jX$.N.N k.Z.N.tX8.tX+ m 2 2 2X7 < j RXx n.Y f.h.bX0.K./.b Q.l.l.l.l.l.l.l.l._._ n n n n + [ @ { $Xa.~.i.i",
+".i.E > >X@ >.U.U.' '.j.6.x.N.Z k.Z.ZX+ =X+ m `.W.W | `X7 c j.u.h 3./.(X2./ _X0Xs.h.Y o.) v v v v.).) o.l o._ n n.E + @ @ $ $.P.i",
+".i f.'.'.).'.U.UXp BXz . m.Z k k k k.Z ` 2 2.W.W # #.X.g.$ w _ /.. W..XS./XmX0XsX2Xy.b X v v v v v v v v.) o o o n n.E + @ {.P.i",
+".iXpXpXpXpXp % % )X#Xz ..N k k k k k 2 2 2.W # # # &.X.gX7 < _.(Xm.t _./..Xm./XSX0X8 u.H.b f f - - - - v v v.).I o.Y Q.T.E @ $.i",
+".iXdXdXdXfXfXfXf 1. l m.Z k k k z z z z.W.W # # & &.X.gX7.$ WX0 _ w WXmXmXm./.(...t.. /.-.-.HXg.q.q - - - f X v.) o o.Y Q.E @.i",
+"XaXfXfX@.;X@.^.U.a l.x.N.Z k k z z z z.W.W # & &.X.X.g.o `X7 w W.t w W.. _ W...(Xm = _X0X0./.( a.q.H.q.q.q -.L f X.I.I o.Y Q.T.F",
+".; 6 6 6.} 6.^.UXz . m k k z z z z.W.W.W # # &.X.s.g.o.o.@.@X7.$.$ < W.a _ w _.( _ w.KX8XX.t.. /.H x xXd.H.q.q.q.L f X.I o.Y Q +",
+" H.V.V.V.v.V.^.U lX+ m z z z z.W.W.W # # & &.X.s.g.o.o NXl.@.`.`XAX7 w W.t <XX./.K.{ c = c wXX uX2XsXsXs.bXs.b.b.h f f X.I o.Y.T",
+" H G G.v.| G.^.U l m.Z z.W.W.W.W # # # & *.X.s.g.o.o N NXlXlX%X%.C qXA.$.=.= =X8 =.=.y.y.y.=Xe.9X0 u u uXSXS / 3 /XsXs f X.I o Q",
+" H H H H [XZ.u _.x.Z 2.W.W # # # # & *.X.s.s.g.o.o N NXl.@X%XbX* 0 q.`.`XAX:.Q =.QX:X:X:X: i.QXeXe.K.K.KXX _XXXXXi..X0Xs f X.I.Y",
+" KX>X>.^.^ R jX+X7 2.W # # # & & * *.X.s.g.g.o.o N NXlXlX%X%X*X* F F 0 0 q ~ MX7.`XqXq ~.R.RX:X7X7.= p.$.$ <.$ p.QX+X$.^.^ f X o",
+" LX<X<.^ h R jX+X7 2 | # & & * *.X.s.g.g.o.o N NXlXl.@X%XbX*X* F F 0 0 q q ~ MX7.`XqXq ~.R.R.`X7X7.= p.$.$ <.$ p.QX+X$.^.^.q f.I",
+" s L L L.~ R j <X7 | | & * *.X.X.f.g.o.o.O NXlXlXlXlX%X%X*X* F F 0 0 q q ~ ~ M.yX:.RXq ~.R.R i.y.=.= p p p.{.{ p.Q c j 3.b.q.L X",
+".<XNXNXN.| J.6X$.t ` `.X.X.s.f.g.o.o.O.O NXlXl ZX%X%XbX*X* F F 0 q ~.`XAX:X:.Q =.Q i iX: i i.QXeXe.K.K.K jXi j.K _X8.uXx.TX4.q f",
+".2.<.<.<.<XN.^.^Xi.$ `.f.g.g.o.o.O.O N NXlXlX%X%X%X%X*X* F F 0 0 ~.RXA.$.=.= =Xm =.=.=.y.= pXe././.a.a.(. . .(.(.(X9 1.- a.H.q f",
+" VX6X6X6XBXB h.^X8 <X7.o.o.o.O.O NXjXlXlXlX%X%XbX*X*X* F q !.`XAXA.y w W.t < W./ W.{ c = c w _. . X# B B D DX9 1 1 1 e.- a a.H.L",
+" b U U U U U h.^.9 w.$ N N.O N NXlXlXlXlX%X%XbXbX*X* F F ! ~XA.$.$ < W.a l w l.a l w.KXm W.tXz.[ 4X3 P d d Y.4 9 E E.8 e.- a.H.L",
+".i.2.2.2.2.2Xh } 3X8.tX7 `XjXlXlXl ZX%X%XbX*X*X* F F.7 qXA.= w W.t w WXz l WXz.a l.t l.aXzXz.j.[X3.GX1X3 P.1.n.4 9 EX- e e a a.i",
+".iXV.2.2.3XVXV.2 JXyXi.$X7XlXlXlX%X%XbXbX*X* F F F F ! ~.=.Q W.a l w W l l lXz.jXz.tXz.[.[.[XnX,.D.D.D.GX3 P.1.n B.BX-.8 e.-.c.i",
+".i.AXVXVXVXV h h.d JX8 <.$.CX*X%X* F !.R ~ q.7 0 0 q.RX: c.K... Xm.t lXzXz lXz.[.aXm.a.*.[.[Xn tX;X;X,.DX1X3 P.1.4 9 EX- e e.h.i",
+".i yXVXCXCXC h h : .9 w <.C.CXb F 0 MX: M q q 0 q q M.yXe.u.(X9./ WXz. Xz l.a.[.[. .[X; t.S.S.S.S.*X;Xn.DX1X3 4.n B.BX-.8 e.h.i",
+".i.i 8 8 8 8 h hXk.P RX8.tXA.`X* ~ M.{ =.Q.=X: ~ ~ ~.y.{.K uX9 D. ./.a. ./ WXz.[.[.[Xn.0.SX=X=X=X=.S.SX;Xn.,XM P.1.4 9X-.8.-.i.i",
+".i.i y 8 8 8 h h 8 b J RXi.$XAX* M.y =X8Xe.Q.=.R.R.R.=.Q j.(X- E.B BX#X#./ WXz.z.,.0.S.SX=X=X=X=X=X=.S.SX;.D.,X3.1.n 9X-X-.b.i.i",
+".i.i.i 8 8 8 8.5.M A.P JXi.{.$.`.y.=Xe.uX8Xi =XAXAXA = _.9 / e.e EX- BX.. Xz.j.[X,.0.SX=X= S C C C SX=.%X;Xn.,XM 4.n B.BX-.i.i.i",
+".i.i.iX&.5.M.M.M.M.M ] JX8 <.{.$.= p j R R 3XX.{.{.{ _.(XS e O E E ' Y dXM.[.[X, t.SX=X= S C C C C CX=X=.SXn.DXM 4.n B.B 1.i.i.i",
+".i.i.i y.M.M h h.M , ] JX8 w =XX =.{ j R RX2 _.{.{.{ _X9XsXw O E E T Y Y.1 4XM.D t.SX=X= C C C C C C SX=.SXn.DXM 4.n B.BXs.i.i.i",
+".i.i.i.i.#.M h h A , ] J.9 cXi.uXi c j R RXy _ < < <Xm 1.cXw O E E ' Y d PX3.DX, t.SX=X= C C CX5 C C SX=.SXn.DXM 4.n BX-.i.i.i.i",
+".i.i.i.i.iX& A A A A ].F.9XeX8 3Xi cX8 RXyXyX8.Q.Q <Xm 1.cXw O.e E ' T d dX3X1.DX;.SX=X= C C C C C CX=.z.*Xn.,XM 4.n D.i.i.i.i.i",
+".i.i.i.i.i y A A A A ].F.u.K.9 RX8 =.9XuXyXyX8 c.Q <Xm 1.cXw O.e E 9 T Y dX3.G.DX;.*.SX= S C C C C SX=.%X;Xn.,X3 4.nXs.i.i.i.i.i",
+".i.i.i.i.i.i , AXvXv ].P R.u 3Xx.9Xe.9.h.h 7.u j =.QXm 1.c ) O.e E E T Y d PX1.DX,X;.S.SX=X= S SX=X=.z.*Xn.DXMX..1 D.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.#X&X&.#.+.P J J.u.KX0.hXZ QXy.u j c.. 1.c )Xw O E E 9 T.1 dX3.G.DXnX;.S.%X=X=X=.z.%.*XnXn.,X3 4 B.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.iX ,X&X&.#Xv.k.P R.uX2XZ.E nXx u j =.. 1.H )Xw e.e E E T.4 d PX3X1.DXnX;X;.S.S.S.*X;XnXn.,XM 4.nXs.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.iX ,.#.#Xv.+ :.d.F.T @ @ @ nXZ RX8Xe./.-.H a ) e O.8 E 9 T Y.1 PX3X1.,.DXnXnXnXnXnXn.D.,XMX..nXs.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.iX ,.#.#.+XkXh.d.~ } $ [ n.TXx.u.9.(.c.q x )Xw O.8 E E 9.4.n.1 PX3XM.,.,.D.D.D.,.,XMX3 4.nXs.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.iX ,.#XvXkXh.d.p } $ { +.T.Y.h.b.b.q.q x a )Xw e.8 E E 9.4.n.1 4 PX3XMXMXMXMXMX3X. 4.nXs.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.iX ,Xv.+ :XO.| }Xa { [.E n.Y.Y.I f.q.q x a ) e e.8 E E 9 B.4.n.1.1 4 4 4 4 4 4.1 BXs.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.].+ :Xh.d.p } $ @ + n.Y o.I f.L.q.H a aXw e e.8 E E.B 9 B.4.n.n.n.n.n.n.n D.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i y ] :XO.d }Xa { @.E Q o.I X f.L.q.H a aXw e e.8X-X- E.B 9 9 B B B B DXs.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i ]Xh.d.p } $ @ +.T.Y o.I X f.L.q.H a aXw e e e.8X-X-X-X-.B.B.BX-.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.A :.d.~Xa $ @.E Q.Y o.I X f.L.q.H a a a.- e e e.8.8X-X- 1Xs.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.A.~ $ { @.E Q.Y o.I X f.q.qX4.H a a a.- e e.-.b.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.P.P $ @.T Q.Y o.I X f.L.q.q.H.H a.c.h.h.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.F +.T Q.Y o.I X f f.L.L.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i"
+};
diff --git a/arts/builder/pics/Synth_PLAY_WAV.xpm b/arts/builder/pics/Synth_PLAY_WAV.xpm
new file mode 100644
index 00000000..a7cedce2
--- /dev/null
+++ b/arts/builder/pics/Synth_PLAY_WAV.xpm
@@ -0,0 +1,317 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 246 2",
+/* colors */
+" c #27326F",
+" . c #68D14E",
+" X c #303E7B",
+" o c #2E3A79",
+" O c #3B4889",
+" + c #2A3675",
+" @ c #293474",
+" # c #51FD0F",
+" $ c #273272",
+" % c #374285",
+" & c #4FFB0D",
+" * c #4EFB0C",
+" = c #44A73B",
+" - c #323E80",
+" ; c #434E94",
+" : c #202A6B",
+" > c #3E4A8F",
+" , c #1C2667",
+" < c #4BCA27",
+" 1 c #3D4B84",
+" 2 c #52F913",
+" 3 c #375074",
+" 4 c #45538F",
+" 5 c #1F2A6D",
+" 6 c #2F3A80",
+" 7 c #323D79",
+" 8 c #1E286C",
+" 9 c #414F8B",
+" 0 c #46ED07",
+" q c #46EB07",
+" w c #4CB935",
+" e c #3B4985",
+" r c #4C5999",
+" t c #4B5998",
+" y c #1A235E",
+" u c #3A5970",
+" i c #43DC0E",
+" p c #44CF19",
+" a c #384582",
+" s c #232E74",
+" d c #445191",
+" f c #323F7C",
+" g c #656FB8",
+" h c #6F76A4",
+" j c #408551",
+" k c #5CFE19",
+" l c #538967",
+" z c #56FE13",
+" x c #374384",
+" c c #46B332",
+" v c #303B7D",
+" b c #1D2767",
+" n c #2B3778",
+" m c #5BE22F",
+" M c #44E30B",
+" N c #4AF40A",
+" B c #42508B",
+" V c #1E296B",
+" C c #51629D",
+" Z c #48F208",
+" A c #1D276A",
+" S c #50609C",
+" D c #404E89",
+" F c #47EE07",
+" G c #2A357A",
+" H c #283378",
+" J c #29366F",
+" K c #263176",
+" L c #242F74",
+" P c #465492",
+" I c #222D72",
+" U c #202B70",
+" Y c #43508F",
+" T c #41508D",
+" R c #30496F",
+" E c #3E4C8A",
+" W c #52955B",
+" Q c #2D3876",
+" ! c #45EA08",
+" ~ c #45E808",
+" ^ c #5D68AF",
+" / c #3C4F7E",
+" ( c #4C569B",
+" ) c #394685",
+" _ c #4B845E",
+" ` c #4EEC14",
+" ' c #404E8F",
+" ] c #1E2867",
+" [ c #293475",
+" { c #283474",
+" } c #253071",
+" | c #4FF90E",
+". c #475E85",
+".. c #4A756A",
+".X c #4DF90C",
+".o c #4BF50A",
+".O c #4AF509",
+".+ c #1E286A",
+".@ c #49F108",
+".# c #1C2668",
+".$ c #4BD51E",
+".% c #4D5D98",
+".& c #293478",
+".* c #4C5B97",
+".= c #45D318",
+".- c #3B4783",
+".; c #273276",
+".: c #5B67A9",
+".> c #263075",
+"., c #485793",
+".< c #222C71",
+".1 c #44538F",
+".2 c #202A6F",
+".3 c #1F2A6E",
+".4 c #42518D",
+".5 c #1D286C",
+".6 c #699088",
+".7 c #45ED07",
+".8 c #3D4B88",
+".9 c #406B63",
+".0 c #4B5B99",
+".q c #34417F",
+".w c #505BA1",
+".e c #3C498A",
+".r c #6175A1",
+".t c #4EA645",
+".y c #45D814",
+".u c #3A5E6A",
+".i c None",
+".p c #242F6F",
+".a c #4A647D",
+".s c #4DF80B",
+".d c #232D6E",
+".f c #4CF80A",
+".g c #4CF60A",
+".h c #334077",
+".j c #556795",
+".k c #1E2969",
+".l c #2D397B",
+".z c #4E5E98",
+".x c #5DB950",
+".c c #38447F",
+".v c #242F72",
+".b c #34427B",
+".n c #43528D",
+".m c #1E296C",
+".M c #1D276B",
+".N c #60EB2E",
+".B c #404E8A",
+".V c #2C377D",
+".C c #47EE08",
+".Z c #5CF620",
+".A c #1D2661",
+".S c #4C5C99",
+".D c #485895",
+".F c #28346F",
+".G c #475694",
+".H c #364480",
+".J c #48598B",
+".K c #43954A",
+".L c #33407D",
+".P c #222C69",
+".I c #303C7A",
+".U c #808CAE",
+".Y c #2E3A78",
+".T c #2B3875",
+".R c #45E609",
+".E c #2B3675",
+".W c #53FD10",
+".Q c #44BF26",
+".! c #465296",
+".~ c #25306F",
+".^ c #757EA3",
+"./ c #496C71",
+".( c #42587E",
+".) c #2E3A7B",
+"._ c #2D387A",
+".` c #48E40F",
+".' c #3C468C",
+".] c #1B2465",
+".[ c #4A5B93",
+".{ c #46C821",
+".} c #273274",
+".| c #232E70",
+"X c #171F57",
+"X. c #46558F",
+"XX c #458D52",
+"Xo c #222C6F",
+"XO c #212C6E",
+"X+ c #52CE30",
+"X@ c #313C81",
+"X# c #43538C",
+"X$ c #6C9F7F",
+"X% c #48F108",
+"X& c #1C2669",
+"X* c #47EF07",
+"X= c #4F5F9B",
+"X- c #3F4D88",
+"X; c #4B5B97",
+"X: c #44DE0E",
+"X> c #273277",
+"X, c #495995",
+"X< c #253075",
+"X1 c #475793",
+"X2 c #384A77",
+"X3 c #465592",
+"X4 c #36417F",
+"X5 c #5663A5",
+"X6 c #212C71",
+"X7 c #4CE019",
+"X8 c #41765B",
+"X9 c #405282",
+"X0 c #41626F",
+"Xq c #45E708",
+"Xw c #394785",
+"Xe c #439D42",
+"Xr c #596D97",
+"Xt c #545FA6",
+"Xy c #334475",
+"Xu c #334275",
+"Xi c #427F55",
+"Xp c #394588",
+"Xa c #263172",
+"Xs c #38467D",
+"Xd c #354184",
+"Xf c #343F83",
+"Xg c #333F82",
+"Xh c #202B6C",
+"Xj c #49F408",
+"Xk c #1F296B",
+"Xl c #49F208",
+"Xz c #567E79",
+"Xx c #2F4074",
+"Xc c #51609C",
+"Xv c #1D2769",
+"Xb c #48F007",
+"Xn c #4A5A95",
+"Xm c #4C7D65",
+"XM c #475692",
+"XN c #232D72",
+"XB c #212B70",
+"XV c #1F296E",
+"XC c #1E296D",
+"XZ c #2D3A75",
+"XA c #48DD14",
+"XS c #3E517F",
+/* pixels */
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.iXa.; H H H K L s.<.2 V b.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.E fXpXdXf 6.V G HX>X< LXN.<X6 U.2XV.A y.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i O ; >.'XpXdXf 6.V G HX>X< LXN.<X6 U.2.2XVXV 8 y.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.iX4.w.w ( ; >.'XpXdX@ 6.V G HX>X< LXN.<X6 U.2.2XVXC 8 8 8X& y.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.iX5X5.w (.! ; >.'XpXfX@ 6.V G HX>X< LXN.<XB U.2.3XVXC 8 8 8.5.M.#.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i r ^ ^Xt.w (.! ; >.'XpXfX@ 6.V G H KX< LXN.<XB U.2XVXVXC 8 8 8.M.M.MX& y.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i g g ^.:Xt.w (.! ; >.' %XfX@ 6.V G H KX< LXN.<XB.2.2XVXVXC 8 8 8.M.M.M A A ,.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i B g g g ^X5Xt.w (.! ; >Xp %XfX@ 6.V G H.>X< s IX6XB.2.2XVXV 8 8 8.5.M.M A A A A.#X .i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.[ g g g ^.:Xt.w (.! ; >.'XpXd - 6.V G HX>.> L s IX6XB.2.3XVXC 8 8 8.M.M.M A A AXvX& ,X .i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.* g g g g ^X5Xt.w (.! ; >.'Xp a.-.q.V G HX>X< LXN.<XB U.2.3XVXC 8 8 8.M.M.M A A AXvX&X& ,X .i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.[ g g g g ^.:Xt.w (.! ; >.'Xp 1X0...( f.& H KX< LXN.<XB.2.2XVXVXC 8 8.M.M.M A A AXvX&X&X&.# ,X .i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i B g g g g ^.:XtXt.w C r ; >.' a / _.x..Xs nX>.>X< s IX6XB.2.3XVXV 8 8 8 8 8.M.M A A AXvXvX&.#.# ,X .i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i g g g g ^.:X5X5X5.r.6Xr P.'Xp.H 3 _.x...b [X>X< LXN.<X6 U.2.3XVXVXCXC 8.m.m.m 8 8 8 8.+ AXvXv.#.# ,.i.i.i.i.i.i.i",
+".i.i.i.i.i.i g g g g ^ ^.:.:.:X5.6X$.6., OXp.q 3XXX+Xm.b @ KX<.vXN.<XB U.2.2.2.2.2.2.2.2.2 5 5 5 : 5.mXk 8.+.+XvXv.].i.i.i.i.i.i",
+".i.i.i.i.i r g g ^ ^.:.: h.6.rXr.6 ..6X. OXdXs uXXX+Xm.b {.> L sXN.<XBXBXBXBXBXBXBXBXoXoXoXoXoXOXOXOXhXh : :XkXk.+.+ y.i.i.i.i.i",
+".i.i.i.i.i ^ ^ ^.:X5Xt.:.^X$.6XrX$ ..6.J.8Xd /.u.KX+Xm.h $X< L sXNXN.<.<.<XNXN.|.|.|.|.|.|.|.|.|.|.dXo.dXoXOXhXh : : ].i.i.i.i.i",
+".i.i.i.iX5 ^.U.UXtXt.w.:.6 .X$XrX$ . lX9 1 x.a.K.tX+Xm.h $ L L.v.v.v.v.v.v.v.v.v.v.v.v.v.v } }.v.v.v.v.p.|.|.d.dXOXh : ].i.i.i.i",
+".i.i.iX4X5Xt.U.U.w.w (X5.6 .X$XrX$ . W.( /.-XzX+X+ mXm.h $X< L LX<X<X<X<X<.>.>.>.>.>.>.>.}.}.}XaXaXaXa } } }.p.p.|.dXOXh.A.i.i.i",
+".i.i.i.w.w.w.w.w ( (.GXc.6 . .X$ . . W 3 /X9 l m m m _Xy J.>.>.>.>.>.>.}.} {.} [.;.;.;.;.; [ [ [ [ {.}.}.}XaXa } }.p.d.d :.i.i.i",
+".i.i.i.w ( ( ( (.!.! d.z.6 . ..N.N mXX 3 3.( l m m mXi RXx {.}.;X>X>.;.&.Y 7.Y n.&.&.&.&.&.&.&.& [ [ [ [ { {.} $Xa } }.p.d.i.i.i",
+".i.i O ( %.!.U.U ; ; d.zX$ ..N.N.N mXe.uX8 l.x.Z.Z ` =Xi.u R J H [ + Q.IX2X0 3.I n n n n n n n n n n n n + [ [ { { $Xa }.~.A.i.i",
+".i.i ; ;Xf ;.U.U > >XM.jX$.N.N k.Z.N.tX8.tX+ m 2 2 2X7 < j RXx n.Y f.h.bX0.K./.b Q.l.l.l.l.l.l.l.l._._ n n n n + [ @ { $Xa.~.i.i",
+".i.E > >X@ >.U.U.' '.j.6.x.N.Z k.Z.ZX+ =X+ m `.W.W | `X7 c j.u.h 3./.(X2./ _X0Xs.h.Y o.) v v v v.).) o.l o._ n n.E + @ @ $ $.P.i",
+".i f.'.'.).'.U.UXp BXz . m.Z k k k k.Z ` 2 2.W.W # #.X.g.$ w _ /.. W..XS./XmX0XsX2Xy.b X v v v v v v v v.) o o o n n.E + @ {.P.i",
+".iXpXpXpXpXp % % )X#Xz ..N k k k k k 2 2 2.W # # # &.X.gX7 < _.(Xm.t _./..Xm./XSX0X8 u.H.b f f - - - - v v v.).I o.Y Q.T.E @ $.i",
+".iXdXdXdXfXfXfXf 1. l m.Z k k k z z z z.W.W # # & &.X.gX7.$ WX0 _ w WXmXmXm./.(...t.. /.-.-.HXg.q.q - - - f X v.) o o.Y Q.E @.i",
+"XaXfXfX@.;X@.^.U.a l.x.N.Z k k z z z z.W.W # & &.X.X.g.o `X7 w W.t w W.. _ W...(Xm = _X0X0./.( a.q.H.q.q.q -.L f X.I.I o.Y Q.T.F",
+".; 6 6 6.} 6.^.UXz . m k k z z z z.W.W.W # # &.X.s.g.o.o.@.@X7.$.$ < W.a _ w _.( _ w.KX8XX.t.. /.H x xXd.H.q.q.q.L f X.I o.Y Q +",
+" H.V.V.V.v.V.^.U lX+ m z z z z.W.W.W # # & &.X.s.g.o.o NXl.@.`.`XAX7 w W.t <XX./.K.{ c = c wXX uX2XsXsXs.bXs.b.b.h f f X.I o.Y.T",
+" H G G.v.| G.^.U l m.Z z.W.W.W.W # # # & *.X.s.g.o.o N NXlXlX%X%.C qXA.$.=.= =X8 =.=.y.y.y.=Xe.9X0 u u uXSXS / 3 /XsXs f X.I o Q",
+" H H H H [XZ.u _.x.Z 2.W.W # # # # & *.X.s.s.g.o.o N NXl.@X%XbX* 0 q.`.`XAX:.Q =.QX:X:X:X: i.QXeXe.K.K.KXX _XXXXXi..X0Xs f X.I.Y",
+" KX>X>.^.^ R jX+X7 2.W # # # & & * *.X.s.g.g.o.o N NXlXlX%X%X*X* F F 0 0 q ~ MX7.`XqXq ~.R.RX:X7X7.= p.$.$ <.$ p.QX+X$.^.^ f X o",
+" LX<X<.^ h R jX+X7 2 | # & & * *.X.s.g.g.o.o N NXlXl.@X%XbX*X* F F 0 0 q q ~ MX7.`XqXq ~.R.R.`X7X7.= p.$.$ <.$ p.QX+X$.^.^.q f.I",
+" s L L L.~ R j <X7 | | & * *.X.X.f.g.o.o.O NXlXlXlXlX%X%X*X* F F 0 0 q q ~ ~ M.yX:.RXq ~.R.R i.y.=.= p p p.{.{ p.Q c j 3.b.q.L X",
+".<XNXNXN.| J.6X$.t ` `.X.X.s.f.g.o.o.O.O NXlXl ZX%X%XbX*X* F F 0 q ~.`XAX:X:.Q =.Q i iX: i i.QXeXe.K.K.K jXi j.K _X8.uXx.TX4.q f",
+".2.<.<.<.<XN.^.^Xi.$ `.f.g.g.o.o.O.O N NXlXlX%X%X%X%X*X* F F 0 0 ~.RXA.$.=.= =Xm =.=.=.y.= pXe././.a.a.(. . .(.(.(X9 1.- a.H.q f",
+" VX6X6X6XBXB h.^X8 <X7.o.o.o.O.O NXjXlXlXlX%X%XbX*X*X* F q !.`XAXA.y w W.t < W./ W.{ c = c w _. . X# B B D DX9 1 1 1 e.- a a.H.L",
+" b U U U U U h.^.9 w.$ N N.O N NXlXlXlXlX%X%XbXbX*X* F F ! ~XA.$.$ < W.a l w l.a l w.KXm W.tXz.[ 4X3 P d d Y.4 9 E E.8 e.- a.H.L",
+".i.2.2.2.2.2Xh } 3X8.tX7 `XjXlXlXl ZX%X%XbX*X*X* F F.7 qXA.= w W.t w WXz l WXz.a l.t l.aXzXz.j.[X3.GX1X3 P.1.n.4 9 EX- e e a a.i",
+".iXV.2.2.3XVXV.2 JXyXi.$X7XlXlXlX%X%XbXbX*X* F F F F ! ~.=.Q W.a l w W l l lXz.jXz.tXz.[.[.[XnX,.D.D.D.GX3 P.1.n B.BX-.8 e.-.c.i",
+".i.AXVXVXVXV h h.d JX8 <.$.CX*X%X* F !.R ~ q.7 0 0 q.RX: c.K... Xm.t lXzXz lXz.[.aXm.a.*.[.[Xn tX;X;X,.DX1X3 P.1.4 9 EX- e e.h.i",
+".i yXVXCXCXC h h : .9 w <.C.CXb F 0 MX: M q q 0 q q M.yXe.u.(X9./ WXz. Xz l.a.[.[. .[X; t.S.S.S.S.*X;Xn.DX1X3 4.n B.BX-.8 e.h.i",
+".i.i 8 8 8 8 h hXk.P RX8.tXA.`X* ~ M.{ =.Q.=X: ~ ~ ~.y.{.K uX9 D. ./.a. ./ WXz.[.[.[Xn.0.SX=X=X=X=.S.SX;Xn.,XM P.1.4 9X-.8.-.i.i",
+".i.i y 8 8 8 h h 8 b J RXi.$XAX* M.y =X8Xe.Q.=.R.R.R.=.Q j.(X- E.B BX#X#./ WXz.z.,.0.S.SX=X=X=X=X=X=.S.SX;.D.,X3.1.n 9X-X-.b.i.i",
+".i.i.i 8 8 8 8.5.M A.P JXi.{.$.`.y.=Xe.uX8Xi =XAXAXA = _.9 / e.e EX- BX.. Xz.j.[X,.0.SX=X= S C C C SX=.%X;Xn.,XM 4.n B.BX-.i.i.i",
+".i.i.iX&.5.M.M.M.M.M ] JX8 <.{.$.= p j R R 3XX.{.{.{ _.(XS e O E E ' Y dXM.[.[X, t.SX=X= S C C C C CX=X=.SXn.DXM 4.n B.B 1.i.i.i",
+".i.i.i y.M.M h h.M , ] JX8 w =XX =.{ j R RX2 _.{.{.{ _X9XsXw O E E T Y Y.1 4XM.D t.SX=X= C C C C C C SX=.SXn.DXM 4.n B.BXs.i.i.i",
+".i.i.i.i.#.M h h A , ] J.9 cXi.uXi c j R RXy _ < < <Xm 1.cXw O E E ' Y d PX3.DX, t.SX=X= C C CX5 C C SX=.SXn.DXM 4.n BX-.i.i.i.i",
+".i.i.i.i.iX& A A A A ].F.9XeX8 3Xi cX8 RXyXyX8.Q.Q <Xm 1.cXw O.e E ' T d dX3X1.DX;.SX=X= C C C C C CX=.z.*Xn.,XM 4.n D.i.i.i.i.i",
+".i.i.i.i.i y A A A A ].F.u.K.9 RX8 =.9XuXyXyX8 c.Q <Xm 1.cXw O.e E 9 T Y dX3.G.DX;.*.SX= S C C C C SX=.%X;Xn.,X3 4.nXs.i.i.i.i.i",
+".i.i.i.i.i.i , AXvXv ].P R.u 3Xx.9Xe.9.h.h 7.u j =.QXm 1.c ) O.e E E T Y d PX1.DX,X;.S.SX=X= S SX=X=.z.*Xn.DXMX..1 D.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.#X&X&.#.+.P J J.u.KX0.hXZ QXy.u j c.. 1.c )Xw O E E 9 T.1 dX3.G.DXnX;.S.%X=X=X=.z.%.*XnXn.,X3 4 B.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.iX ,X&X&.#Xv.k.P R.uX2XZ.E nXx u j =.. 1.H )Xw e.e E E T.4 d PX3X1.DXnX;X;.S.S.S.*X;XnXn.,XM 4.nXs.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.iX ,.#.#Xv.+ :.d.F.T @ @ @ nXZ RX8Xe./.-.H a ) e O.8 E 9 T Y.1 PX3X1.,.DXnXnXnXnXnXn.D.,XMX..nXs.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.iX ,.#.#.+XkXh.d.~ } $ [ n.TXx.u.9.(.c.q x )Xw O.8 E E 9.4.n.1 PX3XM.,.,.D.D.D.,.,XMX3 4.nXs.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.iX ,.#XvXkXh.d.p } $ { +.T.Y.h.b.b.q.q x a )Xw e.8 E E 9.4.n.1 4 PX3XMXMXMXMXMX3X. 4.nXs.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.iX ,Xv.+ :XO.| }Xa { [.E n.Y.Y.I f.q.q x a ) e e.8 E E 9 B.4.n.1.1 4 4 4 4 4 4.1 BXs.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.].+ :Xh.d.p } $ @ + n.Y o.I f.L.q.H a aXw e e.8 E E.B 9 B.4.n.n.n.n.n.n.n D.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i y ] :XO.d }Xa { @.E Q o.I X f.L.q.H a aXw e e.8X-X- E.B 9 9 B B B B DXs.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i ]Xh.d.p } $ @ +.T.Y o.I X f.L.q.H a aXw e e e.8X-X-X-X-.B.B.BX-.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.A :.d.~Xa $ @.E Q.Y o.I X f.L.q.H a a a.- e e e.8.8X-X- 1Xs.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.A.~ $ { @.E Q.Y o.I X f.q.qX4.H a a a.- e e.-.b.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.P.P $ @.T Q.Y o.I X f.L.q.q.H.H a.c.h.h.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i",
+".i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.F +.T Q.Y o.I X f f.L.L.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i.i"
+};
diff --git a/arts/builder/pics/Synth_PSCALE.xpm b/arts/builder/pics/Synth_PSCALE.xpm
new file mode 100644
index 00000000..b40b95d5
--- /dev/null
+++ b/arts/builder/pics/Synth_PSCALE.xpm
@@ -0,0 +1,299 @@
+/* XPM */
+static char * PSCALE_xpm[] = {
+"64 64 232 2",
+" c None",
+". c #161E54",
+"+ c #469224",
+"@ c #4A5A94",
+"# c #56CA0C",
+"$ c #2E3E7C",
+"% c #66E614",
+"& c #4EAE1C",
+"* c #428A34",
+"= c #3E4E84",
+"- c #5EDA0C",
+"; c #8692B4",
+"> c #222E64",
+", c #364684",
+"' c #66CE24",
+") c #6E769C",
+"! c #3A7244",
+"~ c #4AA21C",
+"{ c #6EF614",
+"] c #7E86AC",
+"^ c #52629C",
+"/ c #52BE0C",
+"( c #4A529C",
+"_ c #2A3674",
+": c #5AD214",
+"< c #7AFA1C",
+"[ c #469A24",
+"} c #363E84",
+"| c #46568C",
+"1 c #3E4684",
+"2 c #6EDA2C",
+"3 c #969ECC",
+"4 c #767EA4",
+"5 c #1A2664",
+"6 c #424E94",
+"7 c #525A94",
+"8 c #62E20C",
+"9 c #222E74",
+"0 c #5ECA1C",
+"a c #52B61C",
+"b c #8E9ABC",
+"c c #62BE34",
+"d c #66D624",
+"e c #6A76BC",
+"f c #4EAA1C",
+"g c #5A62AC",
+"h c #56C60C",
+"i c #323A84",
+"j c #5ED21C",
+"k c #6AEE14",
+"l c #3A4A7C",
+"m c #72FE14",
+"n c #868EB4",
+"o c #2E3A74",
+"p c #82FA24",
+"q c #4E9A34",
+"r c #36427C",
+"s c #222A64",
+"t c #569254",
+"u c #4E5E94",
+"v c #32427C",
+"w c #528E54",
+"x c #464E8C",
+"y c #66DA1C",
+"z c #8E92C4",
+"A c #5E6AB4",
+"B c #52A62C",
+"C c #3E4A84",
+"D c #2A3274",
+"E c #36428C",
+"F c #4A962C",
+"G c #428E34",
+"H c #62DE0C",
+"I c #767AA4",
+"J c #4EA61C",
+"K c #52669C",
+"L c #5AC21C",
+"M c #4A5694",
+"N c #5ED60C",
+"O c #425294",
+"P c #5ECE1C",
+"Q c #52BA0C",
+"R c #6672BC",
+"S c #162254",
+"T c #469234",
+"U c #4E5AA4",
+"V c #5ACE0C",
+"W c #323E84",
+"X c #66EA14",
+"Y c #4EB21C",
+"Z c #42528C",
+"` c #62DA1C",
+" . c #26326C",
+".. c #3A468C",
+"+. c #6ED22C",
+"@. c #727AA4",
+"#. c #76FA1C",
+"$. c #7E8AB4",
+"%. c #56C20C",
+"&. c #2E3674",
+"*. c #7AFE1C",
+"=. c #4A9E24",
+"-. c #7E82B4",
+";. c #1E2A6C",
+">. c #525EA4",
+",. c #66E21C",
+"'. c #263274",
+"). c #6ED62C",
+"!. c #3A427C",
+"~. c #666EB4",
+"{. c #3E4A94",
+"]. c #4E5694",
+"^. c #4A922C",
+"/. c #4E5A9C",
+"(. c #5ACA1C",
+"_. c #323E74",
+":. c #424E8C",
+"<. c #62DA0C",
+"[. c #8A96BC",
+"}. c #262E6C",
+"|. c #3A467C",
+"1. c #66D224",
+"2. c #7276A4",
+"3. c #4AA22C",
+"4. c #6EFA14",
+"5. c #5662AC",
+"6. c #5ED20C",
+"7. c #9AA2CC",
+"8. c #7A82AC",
+"9. c #56AA34",
+"0. c #6E7ABC",
+"a. c #4E9E2C",
+"b. c #5A66AC",
+"c. c #6AF214",
+"d. c #626EB4",
+"e. c #82FE1C",
+"f. c #8E96BC",
+"g. c #46528C",
+"h. c #6AE624",
+"i. c #56BE1C",
+"j. c #5AC61C",
+"k. c #428E3C",
+"l. c #52BA1C",
+"m. c #1A2264",
+"n. c #525AA4",
+"o. c #3A4A8C",
+"p. c #2E3A84",
+"q. c #222A74",
+"r. c #4EA62C",
+"s. c #56C21C",
+"t. c #468A2C",
+"u. c #8A92BC",
+"v. c #5662A4",
+"w. c #7EFA24",
+"x. c #4A9A2C",
+"y. c #1E2664",
+"z. c #66E214",
+"A. c #62CA24",
+"B. c #929AC4",
+"C. c #6AD624",
+"D. c #62D21C",
+"E. c #76FE14",
+"F. c #8A8EBC",
+"G. c #468E2C",
+"H. c #465294",
+"I. c #62CE24",
+"J. c #1A225C",
+"K. c #529E34",
+"L. c #5ACA0C",
+"M. c #52AE1C",
+"N. c #72F614",
+"O. c #72DA2C",
+"P. c #9A9ECC",
+"Q. c #464E94",
+"R. c #262E74",
+"S. c #56B61C",
+"T. c #626AB4",
+"U. c #3A428C",
+"V. c #6AEA14",
+"W. c #52B21C",
+"X. c #828AB4",
+"Y. c #7EFE1C",
+"Z. c #565EA4",
+"`. c #424A94",
+" + c #4EA22C",
+".+ c #5E66AC",
+"++ c #6EF214",
+"@+ c #56BA1C",
+"#+ c #46922C",
+"$+ c #4A5A9C",
+"%+ c #3E4E8C",
+"&+ c #222E6C",
+"*+ c #6E76A4",
+"=+ c #7E86B4",
+"-+ c #2A367C",
+";+ c #465694",
+">+ c #3E468C",
+",+ c #767EAC",
+"'+ c #62E214",
+")+ c #5ECA24",
+"!+ c #8E9AC4",
+"~+ c #56C614",
+"{+ c #3A4A84",
+"]+ c #868EBC",
+"^+ c #2E3A7C",
+"/+ c #364284",
+"(+ c #222A6C",
+"_+ c #4E5E9C",
+":+ c #324284",
+"<+ c #3E4A8C",
+"[+ c #2A327C",
+"}+ c #5266A4",
+"|+ c #4A569C",
+"1+ c #5ED614",
+"2+ c #2E367C",
+"3+ c #4A9E2C",
+"4+ c #26327C",
+"5+ c #3A4284",
+"6+ c #4E569C",
+"7+ c #323E7C",
+"8+ c #62DA14",
+"9+ c #3A4684",
+"0+ c #66D22C",
+"a+ c #5ED214",
+"b+ c #6E7AC4",
+"c+ c #82FE24",
+"d+ c #8E96C4",
+"e+ c #1E266C",
+"f+ c #6AD62C",
+"g+ c #62D224",
+"h+ c #76FE1C",
+"i+ c #46529C",
+" '.D D [+[+'.R.9 q.(+;.y. ",
+" s o /+/+i p.^+-+4+R.'.R.9 9 (+9 m.. . . ",
+" &.C `.>+U./+W p.2+2+-+4+'.R.q.9 ;.;.;.e+m.m.. . ",
+" o /.6+M Q.`...E } i p.^+-+4+R.9 9 9 q.9 9 q.;.;.5 m.. . . . ",
+" 7 Z.>.6+( 6 {...E :+i 2+-+-+-+[+'.R.9 q.;.;.;.;.q.;.;.e+e+m.. . ",
+" ].T..+5.n.6+H.6 `.>+E } W p.2+[+'.'.R.9 &+9 q.q.q.e+;.;.e+;.e+;.m.. . . ",
+" d.d.A g Z.U |+Q.`.>+..E W i p.2+[+4+4+R.R.q.&+;.;.q.e+;.;.e+;.e+;.e+5 m.. . ",
+" x e R T.b.5.>.U |+i+{.o.U.} i $ ^+-+-+D '.'.9 9 q.9 q.;.q.e+e+;.e+;.e+e+e+e+m.. . . ",
+" !.*+R R T.b.v.n.|+( Q.`.>+../+i p.^+-+4+4+R.9 R.9 q.&+q.;.;.;.e+;.e+e+5 e+e+5 e+m.. . . ",
+" ].0.R R T.b.g >./.|+H.6 <+..E } W 2+-+[+[+R.4+R.9 (+q.;.;.;.;.;.;.e+;.;.;.e+;.;.e+;.m.. . . ",
+" !.*+e ~.d.A b.Z.n.6+i+6 {.>+U.E W W p.2+_ [+R.R.9 9 &+q.9 q.;.;.e+q.e+e+e+;.5 e+;.5 e+5 m.. . . ",
+" x e R R ~.A b.Z.>.U |+i+6 {.../+W W ^+2+-+[+'.'.'.R.9 ;.q.;.;.e+e+;.e+;.;.e+e+e+5 e+e+;.e+e+m.. . . ",
+" R e ~.d..+b.5.>.U |+H.Q.`.<+..E W i ^+^+-+-+4+9 9 9 9 9 ;.;.;.q.;.;.e+e+;.;.;.;.e+;.e+5 e+5 5 m.. . ",
+" R R ~.7.P.b.g >.U |+( Q.%+<+U.E } i p.p.-+-+'.R.R.R.q.q.;.q.q.q.;.q.;.;.;.;.;.;.;.;.;.;.;.;.e+e+;.m.. . ",
+" C ~.~.T.3 3 Z.>.n.6+i+Q.`.>+..U./+} i 2+-+[+[+'.'.9 R.}.9 9 9 9 9 ;.9 9 9 9 ;.q.q.9 q.9 9 q.9 ;.;.;.;.5 m.. ",
+" T.T.b.b.5.>.>.n.|+( i+6 `.o.../+} W ^+^+-+-+'.4+R.R.9 9 q.q.;.&+q.9 9 9 9 9 9 9 9 9 &+(+(+&+(+9 (+q.(+;.. . ",
+" ].b.g 5.5.Z.U U 6+;+Q.6 {.>+..U.W W i 2+2+-+[+'.4+'.9 9 R.9 '.9 '.R.9 9 9 R.'.'.'.}.'.'.'.9 '.&+9 &+&+q.&+;.5 . ",
+" } g Z.^ >+n.d+d+|+i+Q.6 {.{...U.W W w t ^+-+'.'.'.R.9 '.R.'.'.R.R.9 '.'.'.'.'.R.'.'.'.'.'.R.'.R.'. .R.9 }.9 (+(+J.. ",
+" x >.n.U ..|+z u.i+6 `.{...U.E E } $ +.).-+-+[+4+'.'.R.'.'.'.'.'.D '.D '.D '._ '.'.-+'.'._ '._ '.'.'. .'.}.'. .&+(+5 ",
+" U 6+6+6+5+( ; ]+6 `.{.>+U.E } W p.i +.w.).B '.D 4+D '.'.'.'.4+4+'.'.4+_ _ -+4+-+_ D -+_ '._ '.D D _ D '.'.R.R.&+ .J. ",
+" &.( i+i+Q.} Q.]+X.{.>+U...5+} i W ^+^++.e.c+C.'.'.4+-+D [+[+_ _ -+-+_ -+-+_ ^+&.-+^+_ -+^+-+o -+-+_ -+_ _ _ '.D }.D &+5 ",
+" Q.O 6 6 6 %+{.>+>+.., U.} W W W ^+2+-+2 c+e.< 1.B '.'.-+'._ [+-+_ 2+2+2+-+2+-+^+^+-+^+^+-+^+-+o ^+_ _ _ _ _ _ _ _ .> . ",
+" y.`.`.{.{.>+>+>+>+U.U./+} W W i 2+p.c C.w.Y.Y.Y.Y.d -+'.-+[+-+_ -+^+^+^+^+^+^+^+^+$ ^+^+7+^+$ ^+^+^+^+^+2+-+_ _ _ _ D _ .y. ",
+" o ....>+U...p...=+=+} W W W ^+2+^+-++.e.e.w.C.d #.N.D. +-+o ^+-+^+^+-+^+^+^+^+^+^+i $ $ ^+$ i $ ^+$ ^+^+^+o ^+_ -+_ _ D > . ",
+" } 5+E U.E } -+:+=+=+W i i 2+p.2+-+_ 0+Y.Y.d [+4+1.h+h+D.-+-+^+^+^+$ ^+$ $ $ W 7+$ W 7+v 7+7+7+7+7+7+7+$ 7+^+i o &._ _ &.D . ",
+" } E } :+} W [+i -.8.p.^+-+^+-+[+D 4+' Y.*.A._ -+r.D.#.{ P ~ ^+^+^+^+$ 7+W W 7+W /+} } W } :+W :+7+W 7+7+$ 7+$ ^+$ ^+o _ _ D ",
+"'.W W i W W i D ^+,+8.p.2+-+-+-+4+D '.I.*.*.)+_ -+-+-+j m m P p.^+W i W 7+} :+r W v :+/+/+/+r /+/+r :+/+} 7+7+7+^+7+^+o o o o _ ",
+"'.^+p.p.2+p.^+^+p.^+2+-+-+[+D '.D '.[+1.#.1.B [+_ -+-+r.h.{ c.(.3+7+v W W :+/+/+, /+, , , /+, /+/+/+/+r :+r /+r v 7+7+7+^+o _ _ ",
+"[+2+2+p.2+-+-+-+[+[+[+-+4+4+4+'.R. +d N.D.-+_ -+2+^+^+^+p.,.{ { j.W :+/+/+/+/+/+9+5+5+, 9+9+9+9+, 9+, 9+/+/+:+} 7+7+7+$ ^+o o &.",
+"'.-+-+[+-+-+[+&+-+4 4 '.'.'.R.9 9 A.E.h+P '.-+2+-+-+2+p.W +0 k k j.x./+/+/+, 9+, , o.9+9+...., 9+9+.., , , !., /+/+7+7+7+7+^+^+",
+"D [+-+'.[+-+[+q.4+I I 4+R.'.R.R.9 )+h+h+)+[+D ^+o ^+^+^+i $ :+j.c.k j., , , , ..o.9+>+o.{+{+<+o.o.9+9+9+9+, /+, r /+r v 7+$ ^+o ",
+"R.'.R.4+'.R.'.(+4+@.@.R.9 R.9 9 R.0 m m )+_ -+-+-+^+^+i $ W W =.y k % L x.....o.<+o.o.<+<+<+o.<+C o.<+o.{+o.{+9+, , /+} v 7+7+^+",
+"R.4+R.R.4+9 '.(+'.@.@.R.q.9 9 9 9 P { P 3+-+_ ^+^+^+$ W 7+/+/+/+/+d X X i.C o.o.<+%+%+%+%+:.%+%+%+%+= <+C 1 {+9+9+, , r r v v 7+",
+"9 9 9 9 9 R.9 9 9 R.9 9 9 &+9 =.0 { 0 '._ _ 2+-+p.^+$ 7+/+W /+:+, =.%.z.z.i.F <+%+<+<+%+%+%+:.%+:.%+`.%+<+%+<+o.9+9+9+5+r } } ^+",
+"q.R.R.9 9 q.q.q.9 q.9 (+q.(+9 L { { L 4+-+-+^+^+^+i W 7+r :+/+/+, ....i.8 8 @+%+:.Z 6 6 Z Z 6 :.:.Z %+%+<+<+= <+C 9+{+, , r r 7+",
+"(+9 9 (+q.}.9 ;.;.@.*+9 q.q.;.s.{ { s.D _ -+-+-+$ $ 7+W :+/+9+9+....{+x.D.z.<.a F 6 Z Z O O g.Z O :.Z Z Z = `.= o.{+9+9+9+r r 7+",
+"e+;.9 &+;.q.(+;.(+@.*+;.;.q.9 j.{ { s.4+_ o ^+^+i W :+W /+/+, 9+{+o.o.%+o.j 8 H l.O H.H.H.;+;+H.;+O O Z O Z %+:.<+o.{+9+9+, , r ",
+";.q.q.;.q.;.;.e+;.2.2.;.;.;.q.` X L [ _ -+-+^+^+$ $ 7+/+/+, E o...<+<+%+:.F @+1+6.W.#+| ;+H.H.;+H.;+H.O g.Z Z %+:.= <+{+{+9+!.7+",
+" ;.q.;.q.q.(+e+;.@.@.q.(+[ d k ~+R.4+_ -+-+^+^+i W 7+/+/+9+, o.9+<+<+%+%+6 Z a <.- W.;+@ @ ;+@ ;+;+M ;+H.H.g.Z :.%+<+{+9+, 9+ ",
+" ;.;.q.;.;.;.;.;.e+e+;.;.l.k V.@+'.D 4+_ ^+^+i 7+7+/+:+/+, ..1 o.%+%+O O Z O F a a+V Y G ;+@ ;+M @ ;+;+| O Z :.:.:.%+C C 9+, ",
+" . y.;.;.e+q.e+;.;.e+e+;.Q k X @+'._ -+_ -+^+$ W W r , /+9+o.<+o.<+%+:.O H.O ;+;+a N 6.W.$+/.@ @ @ @ ;+M ;+;+g.Z :.%+%+C 9+_. ",
+" m.;.;.;.;.e+e+;.2.*+;.;.l.% X l.'.'.D -+^+^+i 7+v /+/+.., 9+o.<+%+:.O O Z ;+;+M G.M.V L.& G._+/./.@ $+@ ;+| ;+Z Z :.C C |.> ",
+" m.e+;.;.;.5 ;.2.*+e+e+j H l.+ '.-+_ _ ^+^+$ W W /+/+..o.{+<+%+%+:.:.H.H.;+;+@ @ $+& V V f _+u /.u @ @ ;+;+H.Z :.:.%+{+1 ",
+" m.;.e+e+e+e+e+) 2.! a+% l.&+9 R.'.-+-+o $ p.7+v :+, /+9+..%+<+%+O O | ;+;+@ $+_+_+G.M.h h f G _+$+$+$+M | ;+g.Z Z = = . ",
+" m.;.;.e+5 ;.) ) k.8 % W.}.'.'.'.-+-+2+7+i W } r 9+, {+9+<+<+%+Z O ;+H.;+;+@ @ _+_+^ & # L.f ^ u /.u @ ;+;+;+Z :.:.:. ",
+" e+5 e+e+e+e+e+e+G.8 H Y 9 R.'._ _ -+o ^+$ 7+v :+/+9+..o.%+%+:.:.Z H.;+;+@ $+_+_+_+_+G.i.h %.J t._+$+@ @ ;+Z Z Z = !. ",
+" . 5 ;.;.5 5 e+5 * '+8 Y &+R.'.D _ -+^+^+7+W } /+/+9+9+..<+<+:.6 Z ;+;+|+;+@ /.u _+^ ^ ^ l.%.%.J u /.@ @ M H.g.:.= 1 ",
+" e+5 5 e+e+*+*+* H H & &+'.'._ -+o -+7+^+7+v :+, /+{+{+%+%+%+Z O H.;+;+@ $+u _+^ ^ }+}+G.J / Q ~ x./.M ;+| Z Z l ",
+" m.e+e+e+2.2.* 8+<.~+(+&+R.'.'.o _ ^+i 7+r /+, /+..9+<+%+:.Z Z g.;+;+M $+$+_+_+>.^ K K ^ 3+%./ / @ @ ;+g.g.:. ",
+" m.;.5 5 *+) *+*+;.&+@.@.4 4 _ -+8.8.] 8.W :+=+X.X.X.o.<+n n ]+; ;+M [.[.f.[._+^ B.B.!+!+^ _+f.[.[.u.g.| Z &. ",
+" S e+e+*+) ) 2.;.(+@.@.I ,+D _ 8.4 ] ] 7+r ] $.X.X.<+<+n n ]+u.;+;+u.[.f.[.u _+b B.b d+_+_+f.f.[.[.g.Z :. ",
+" e+5 e+5 e+;.e+&+q.9 '.'._ _ _ ^+^+$ 7+W /+r , 9+{+o.<+:.Z Z Z H.M @ @ /.$+$+u _+_+u u u @ @ ;+g.| Z ",
+" . . e+5 m.y.e+(+;.;.;.(+_ -+ .'.D D 7+v o &.o ^+C o.7+7+7+v Z | v r , |./.@ 9+9+{+9+$+/.r !.;+Z x |. ",
+" J.5 e+5 5 ;.;.(+&+}.'.'._ -+_ ^+$ 7+W W , /+9+{+C {+<+:.:.O O H.;+;+;+@ @ @ /.@ @ @ @ @ ;+| g._ ",
+" . J.e+5 ;.;.(+9 &+'.'.D 2+_ o $ 7+v 7+/+, /+, <+C <+%+:.Z Z Z g.;+| ;+;+@ M @ ;+;+| ;+g.Z |. ",
+" . 5 e+y.(+(+&+R.}.'._ _ 2+o i ^+7+:+v /+, 9+9+o.= <+%+:.Z g.O g.H.;+| ;+;+| | | H.| Z &. ",
+" . S 5 ;.(+&+9 }. .'._ -+_ o ^+i 7+7+/+, , , ..C C <+`.%+Z Z Z g.H.g.| H.;+H.| Z Z |. ",
+" y.;.;.;.&+9 R.'._ _ ^+o o 7+7+r r r /+9+, {+o.= = :.:.%+Z :.Z Z O Z Z Z Z = ",
+" . ;.;.&+&+ .}.D '.-+o o $ ^+7+W r r 9+5+9+9+o.{+C %+%+%+:.:.:.Z :.Z :.C ",
+" ;.(+&+9 '. ._ _ _ ^+^+7+$ 7+v /+r , 9+, 9+1 o.C C :.%+%+= :.:.C ",
+" y.s &+R. .D D _ &.o i _.7+7+v r r 9+, , {+{+<+{+C C %+C C |. ",
+" s R. ._ D _ _ o ^+^+$ W 7+:+r !.9+9+9+9+9+{+l r ",
+" s > D _ _ o ^+o ^+7+7+7+:+r r r , 9+_.v ",
+" D _ &.^+o o 7+7+7+7+} r "};
diff --git a/arts/builder/pics/Synth_RC.xpm b/arts/builder/pics/Synth_RC.xpm
new file mode 100644
index 00000000..a906535e
--- /dev/null
+++ b/arts/builder/pics/Synth_RC.xpm
@@ -0,0 +1,323 @@
+/* XPM */
+static char * Synth_RC_xpm[] = {
+"64 64 256 2",
+" c None",
+". c #161E54",
+"+ c #42862C",
+"@ c #2E524C",
+"# c #366E34",
+"$ c #56BA24",
+"% c #263A54",
+"& c #4EA22C",
+"* c #4A529C",
+"= c #2A4654",
+"- c #768694",
+"; c #626E84",
+"> c #62D61C",
+", c #365E4C",
+"' c #1E2E54",
+") c #3A467C",
+"! c #323A84",
+"~ c #52629C",
+"{ c #46962C",
+"] c #467A4C",
+"^ c #425284",
+"/ c #2A3274",
+"( c #8A96BC",
+"_ c #3E4E84",
+": c #5ECA24",
+"< c #9AA2CC",
+"[ c #52AE2C",
+"} c #4A5A8C",
+"| c #727AA4",
+"1 c #66E21C",
+"2 c #4A765C",
+"3 c #66866C",
+"4 c #2A3A6C",
+"5 c #263664",
+"6 c #1A2664",
+"7 c #364674",
+"8 c #868EAC",
+"9 c #425E64",
+"0 c #3A468C",
+"a c #32427C",
+"b c #468E34",
+"c c #426E54",
+"d c #5EAA3C",
+"e c #222E6C",
+"f c #465A7C",
+"g c #5AC224",
+"h c #66DE1C",
+"i c #525A94",
+"j c #3A526C",
+"k c #52AA2C",
+"l c #2E4E51",
+"m c #425294",
+"n c #626EB4",
+"o c #5662AB",
+"p c #4A9E2C",
+"q c #1E266C",
+"r c #3E5E5C",
+"s c #5ED21C",
+"t c #7A82AC",
+"u c #3A427F",
+"v c #62C62C",
+"w c #3E7644",
+"x c #2A425A",
+"y c #56A634",
+"z c #2E465C",
+"A c #6AD624",
+"B c #3A4A84",
+"C c #567A5C",
+"D c #2A3674",
+"E c #969ECC",
+"F c #464E93",
+"G c #4A5A9C",
+"H c #2E3A7D",
+"I c #868EBC",
+"J c #263273",
+"K c #5AC61C",
+"L c #5E6AB4",
+"M c #4A8644",
+"N c #3A6E44",
+"O c #4EA62C",
+"P c #4A5694",
+"Q c #7E86B1",
+"R c #366640",
+"S c #4E963C",
+"T c #425680",
+"U c #6E7AC0",
+"V c #72EA24",
+"W c #424A94",
+"X c #4E8E44",
+"Y c #6E76A4",
+"Z c #325A4C",
+"` c #263A5C",
+" . c #2A4A4C",
+".. c #62DA1C",
+"+. c #263264",
+"@. c #323E7C",
+"#. c #4A824C",
+"$. c #8E9ABE",
+"%. c #424E94",
+"&. c #66CA2C",
+"*. c #56B62C",
+"=. c #6EE624",
+"-. c #222A64",
+";. c #426664",
+">. c #3A4A8C",
+",. c #36428C",
+"'. c #4A9236",
+"). c #42764C",
+"!. c #3E5A64",
+"~. c #5E66AC",
+"{. c #2A367C",
+"]. c #4A569C",
+"^. c #162254",
+"/. c #428A34",
+"(. c #32623C",
+"_. c #223254",
+":. c #4A9A30",
+"<. c #4A7A4C",
+"[. c #424E8C",
+"}. c #767EA9",
+"|. c #6AE61C",
+"1. c #5A6E74",
+"2. c #2E3E6C",
+"3. c #1E2A64",
+"4. c #364282",
+"5. c #262E73",
+"6. c #5EC228",
+"7. c #6EDE24",
+"8. c #525EA4",
+"9. c #626A84",
+"0. c #6A76BC",
+"a. c #567664",
+"b. c #6E8684",
+"c. c #42665C",
+"d. c #6A7299",
+"e. c #465E7C",
+"f. c #364E64",
+"g. c #8E92C4",
+"h. c #427E3C",
+"i. c #42724C",
+"j. c #3A5664",
+"k. c #529E38",
+"l. c #66D22C",
+"m. c #32564C",
+"n. c #3A723C",
+"o. c #5ABE27",
+"p. c #223E4C",
+"q. c #56B22C",
+"r. c #4E5E94",
+"s. c #465694",
+"t. c #6672BC",
+"u. c #5A66AC",
+"v. c #1E2A6C",
+"w. c #324A64",
+"x. c #4E5E9C",
+"y. c #3A7244",
+"z. c #7E8AB4",
+"A. c #2A3E5C",
+"B. c #5ECE24",
+"C. c #628A6C",
+"D. c #5A7E5C",
+"E. c #8A92BC",
+"F. c #768A8C",
+"G. c #8692B4",
+"H. c #2E3E7C",
+"I. c #4E9A34",
+"J. c #5A726C",
+"K. c #426264",
+"L. c #6ADA24",
+"M. c #66CE2C",
+"N. c #4A7E4C",
+"O. c #222E64",
+"P. c #5EC62C",
+"Q. c #46568C",
+"R. c #323E84",
+"S. c #1A2264",
+"T. c #36624C",
+"U. c #3E5674",
+"V. c #364684",
+"W. c #465A8C",
+"X. c #525AA4",
+"Y. c #3A428C",
+"Z. c #26327C",
+"`. c #223264",
+" + c #325254",
+".+ c #52A234",
+"++ c #66D624",
+"@+ c #3E4684",
+"#+ c #4A9634",
+"$+ c #46528C",
+"%+ c #8E96BE",
+"&+ c #56AE34",
+"*+ c #6AE222",
+"=+ c #2E3A73",
+"-+ c #1E2664",
+";+ c #4A8E3C",
+">+ c #466E5C",
+",+ c #62AA44",
+"'+ c #6ADE24",
+")+ c #3E5274",
+"!+ c #56AA34",
+"~+ c #465296",
+"{+ c #5A62AC",
+"]+ c #62D224",
+"^+ c #7E82B4",
+"/+ c #3E4A84",
+"(+ c #2E3674",
+"_+ c #4E5AA2",
+":+ c #5EC624",
+"<+ c #4E864C",
+"[+ c #3E6E4C",
+"}+ c #52A631",
+"|+ c #4E5694",
+"1+ c #365A54",
+"2+ c #2A3A64",
+"3+ c #2E4A50",
+"4+ c #46666C",
+"5+ c #3E4A8E",
+"6+ c #467654",
+"7+ c #1A225C",
+"8+ c #468A37",
+"9+ c #222A6F",
+"0+ c #2E4654",
+"a+ c #767AA4",
+"b+ c #3E468C",
+"c+ c #666EB4",
+"d+ c #9A9ECC",
+"e+ c #8A8EBC",
+"f+ c #626AB4",
+"g+ c #7276A4",
+"h+ c #66DA1C",
+"i+ c #5AB62C",
+"j+ c #2E367C",
+"k+ c #4E569C",
+"l+ c #36623C",
+"m+ c #565EA4",
+"n+ c #3E7244",
+"o+ c #828AB4",
+"p+ c #62CE24",
+"q+ c #363E84",
+"r+ c #4EA234",
+"s+ c #62D624",
+"t+ c #3A4684",
+"u+ c #42528C",
+"v+ c #2A327C",
+"w+ c #3E4E8C",
+"x+ c #4A5A94",
+"y+ c #26366C",
+"z+ c #36467C",
+"A+ c #868EB4",
+"B+ c #324284",
+"C+ c #468E3C",
+"D+ c #222E74",
+"E+ c #5AC22C",
+"F+ c #66DE24",
+"G+ c #52AA34",
+" J / / v+v+J 5.D+9+9+v.-+ ",
+" -.=+4.4.! H H {.Z.5.Z.5.D+D+9+D+S.. . . ",
+" (+/+W b+Y.4.R.H j+j+{.J Z.5.9+D+v.v.v.q S.S.. . ",
+" =+i k+P F W 0 ,.q+! H H {.Z.5.D+D+D+9+D+D+9+v.v.6 S.. . . . ",
+" i m+8.k+* %.5+0 ,.B+! j+{.{.{.v+Z.5.D+9+v.v.v.v.9+v.v.q q S.. . ",
+" |+f+~.o X.k+~+%.W b+,.q+R.H j+v+J J 5.D+D+D+9+9+9+q v.v.q v.q v.S.. . . ",
+" n n L {+8._+].F W b+0 ,.R.! H j+v+Z.J 5.5.9+D+v.v.9+q v.v.q v.q v.q 6 S.. . ",
+" [.0.t.f+u.o m+_+].~+W >.Y.q+! R.H {.{.v+Z.Z.D+D+9+D+9+v.v.q q v.q v.q q q q S.. . . ",
+" u Y t.t.L u.o _+].* %.W b+0 ,.! H H {.Z.J 5.D+5.D+9+D+9+v.v.v.q v.q q 6 q q 6 q S.. . . ",
+" |+U t.t.f+~.o 8.X.].~+%.5+0 ,.R.R.j+{.v+v+5.Z.5.D+9+9+v.v.9+v.v.v.q v.v.v.q v.v.q v.S.. . . ",
+" u d.0.c+n L u.m+_+k+* %.W 0 Y.,.R.H.! {.{.v+5.5.D+D+D+9+D+v.v.v.q v.q q q v.6 q v.6 q 6 S.. . . ",
+" [.U 0.t.c+L u.m+8._+].~+%.5+b+,.q+R.! {.j+/ J Z.Z.5.D+v.9+v.v.q q v.q v.v.q q q 6 q q v.q q S.. . . ",
+" c+t.c+n ~.u.o 8.X.].~+%.W >.0 ,.R.H H H {.{.J D+D+D+D+D+9+9+9+v.v.v.q q v.v.v.v.q v.q 6 q 6 6 S.. . ",
+" t.t.t.< d+u.o m+_+].* F %.5+Y.,.q+! ! H {.{.Z.5.5.5.9+9+v.9+v.v.9+v.v.v.v.v.v.v.v.v.v.v.v.v.q q v.S.. . ",
+" /+c+f+f+E E m+8.X.].* %.W b+b+Y.,.R.! j+{.v+v+J Z.D+5.5.D+D+D+D+D+9+D+D+D+D+v.9+9+D+9+D+D+9+D+v.v.v.v.6 S.. ",
+" f+f+~.u.{+m+8._+].* * %.W >.0 ,.R.R.H H {.{.J Z.D+D+D+v.9+v.9+D+9+D+D+D+D+D+D+D+D+D+D+9+9+D+9+D+9+9+9+v.. . ",
+" |+u.u.o o 8.X._+k+].%.%.W 0 0 Y.q+R.H j+j+{.v+J 5.+.@ R R 3+`.D+D+5.5.D+5.5.J J J 5.J J J e `.5.D+e e 9+e v.6 . ",
+" q+{+o 8.b+_+%+%+].* %.%.W >.0 ,.R.R.! H H {.Z.J D+3+[ ++]+B.]+:.5 D+J Z.J J Z.5.J J J J J 5.Z.5.J J 5.D+5.D+9+9+7+. ",
+" F i X.X.b+].g.E.m %.W 5+b+Y.Y.4.R.! ! {.{.{.v+J x v *+b 3+@ p |.[ 5 5./ Z.J D Z.Z.y+Z.J y+/ y+J J J J J 5.J J e 9+6 ",
+" _+k+k+].4.* E.I %.W 5+0 Y.,.q+R.! H {.j+v+/ J +.}+V '.+.J D+` k |./.J J D {.Z.D {.v+D D v+{./ v+/ y+/ J J 5.5.5.`.7+ ",
+" (+s.s.* F R.%.I o+W 0 Y.0 ,.R.! R.H H {.{.v+Z.J m.'+P.` J {.v+J = p+]+3+D D =+j+(+4 {.{.4 {.H D D {.D D D y+J J 5./ e 6 ",
+" F F %.%.%.%.W b+b+0 0 Y.q+q+R.R.H H j+{.v+J / J !+=.n+J Z./ {.D J /.|.+ y+j+{.H H j+H H j+H D H H (+{.D D D D D D J O.. ",
+" -+5+W W 5+b+0 b+0 Y.,.,.R.R.R.! j+j+{.{.v+{.J / A.A ++A./ {.{.{.j+D l F+6.4 H H H H.H H H.H H.H H H =+H j+(+(+D D D / D J -+ ",
+" ! b+0 0 Y.0 H 0 Q Q q+R.R.R.! j+H {.v+v+y+J {.J R *+k J {.D {.D H H y+E+..3+H H H H @.@.H H.! H.H H.H H =+H H D (+D D / O.. ",
+" @.,.,.Y.,.q+{.,.Q Q R.! H j+H j+{.{.v+v+v+v+/ J :.*+N D H H H H H H (+8+F+y.=+R.R.R.R.a @.@.@.@.@.@.@.H.H.H ! =+(+(+D (+/ +. ",
+" ,.q+q+,.q+q+v+! t t H H j+H {.v+{.v+J J Z.J v++.v h+0+D {.{.H H H R.2., h O 2.@.a R.@.q+q+a R.a R.R.@.@.@.@.H.H H.H =+D D / ",
+"5.R.R.! R.R.! v+! }.^+H {.{.{.{./ J Z.Z./ v+y+{.A.A p+2+H H H H H H.! H z s+:+2.q+4.4.B+4.4.4.4.4.4.B+4.@.@.@.@.H H.H =+=+4 4 D ",
+"/ H H ! j+H H H H H {.{.{.v+Z.Z.Z.Z./ v+y+{.v+/ m.h q.D {.H H H R.R.a R.2.: s+w.B+4.V.V.V.4.V.4.4.4.4.4.4.a 4.a a @.@.@.H H (+D ",
+"v+{.{.H {.{.{.{.v+v+v+{.Z./ J 5.5.5.5.Z.J {.{.J y.1 #+=+H H @.@.R.R.4.B+@.$ h+1+4.4.u V.0 t+0 V.V.t+V.V.4.4.4.q+@.@.@.@.! =+=+(+",
+"{.j+{.v+{.{.v+D+{.}.}.Z.J Z.5.J J J J J v+J D D '.*+R =+@.R.R.R.@.B+B+4.a 8+h w z+0 >.0 t+0 t+t+t+t+t+t+t+V.4.z+4.4.@.@.@.@.H H ",
+"Z.v+{.Z.v+{.v+9+Z.a+a+Z.5.J D+D+D+D+5.J v+Z.D D & F+Z H H.H.B+4.q+4.4.t+z+w h+C+z+t+@+>.B >.>.>.>.0 0 0 t+t+4.V.4.4.a a @.@.=+H ",
+"J Z.5.Z.Z.5.J 9+Z.| a+5.D+5.D+D+5.Z.J Z.y+D {.5 :+h+z H @.R.R.R.4.4.0 4.4.1+..&+z+>.>.5+5+5+5+/+5+B B B B >.B t+V.V.4.q+a @.@.=+",
+"5.Z.5.5.Z.D+J 9+J | | D+9+5.9+D+5.J J v+v+{.{.x ++p+A.! @.B+4.B+4.V.0 V.t+f.> : 7 5+w+w+w+w+w+w+w+w+w+5+B b+B t+t+t+V.4.a B+a @.",
+"D+D+D+D+D+5.D+D+D+D+5.D+D+9+5.9+D+5.J J {.D D , h [ =+R.4.q+B+V.V.0 B >.0 7 P.h+j._ 5+w+w+[.[.w+[.[.5+w+5+_ 5+B t+V.V.4.4.q+q+H ",
+"9+5.D+D+D+9+9+9+D+9+D+9+D+v.D+9+D+5.Z.J Z.D D '.F+N 2.R.B+4.4.0 V.0 t+>.>.z+#+h i._ [.[.u+m [.%.w+u+w+[.5+5+w+5+/+@+B ) V.4.a @.",
+"9+D+D+9+9+5.5.v.9+| g+D+v.9+9+D+J J J v+D {.y+o.h+ +H @.4.4.u 4.0 t+5+>.w+B [+..r+B [.m m u+~+u+~+[.u+u+u+[.W _ 5+B t+t+) 4.4.q+",
+"q 9+D+D+v.v.9+v.v.| Y 9+v.v.D+9+D+5.J D D D = ..: 2.R.R.4.V.V.0 >.B 5+5+5+5+j.s+B.j m u+~+s.s.u+s.~+u+u+u+u+w+_ 5+/+B t+t+) z+4.",
+"3.9+9+v.9+9+v.q 9+Y g+v.v.9+9+D+5.J J v+{.D h.1 8+=+@.B+V.,.0 V.t+>.5+w+[.[.B G+h+c u+s.Q.~+~+s.~+s.~+m m u+u+[.w+w+5+B B t+4.@.",
+" v.9+v.v.9+v.q 9+| Y 9+v.v.D+D+D+J J / Z.4 o... +H.q+B+4.V.0 >.5+B w+w+w+[.[.i.h+y [.s.W.W.P W.s.s.P Q.~+$+u+u+w+_ 5+B t+t+) ",
+" v.v.9+9+v.v.v.v.q 9+v.v.9+v.D+5.J {.D D , F+*.4 @.B+4.V.u t+t+>.w+5+u+m ~+u+U.: ]+r s.].].G P P x+s.s.s.m u+F [.w+_ /+B t+z+ ",
+" . q v.v.q v.q v.v.v.q v.9+9+D+5.5.J J 5 q...T.=+R.q+4.V.V.>.0 5+w+w+[.u+m m u+M h k.^ x+x+G G x+x+x+s.P s.s.$+u+[.w+_ B t+@. ",
+" S.v.v.v.9+q q v.Y Y v.v.v.D+e D+J Z.y+R 1 q.=+H.4.B+,.V.0 t+/+5+w+%.m m $+s.u+U.P.]+;.s.G x.r.i _+G x+W.s.s.Q.$+u+[.W /+) O. ",
+" S.q v.v.v.6 q g+g+q v.v.D+5.J J / ` o.> Z =+@.4.4.4.t+>.>.>.5+w+w+[.m ~+s.s.T #...!+T x+x.x.x.x+x.G x+s.s.m m [._ w+B @+ ",
+" S.v.q q q q v.Y Y v.q 9+9+e D+5.`.b 1 :.2+! R.@.B+4.V.t+B w+w+w+u+m ~+s.P x+].)+&+..N.W.x.x.~ x.G x+i P s.Q.$+u+u+_ [.+. ",
+" S.v.v.q q q Y d.9+v.v.D+5.`.e n...*.A.=+H R.4.4.,.V.0 t+5+5+[.u+u+$+s.s.W.G x+4+:+p+6+} x.~ ~ x.G r.x+P s.s.u+[.w+[. ",
+" q q 6 q 6 -+q v.6 q 9+9+e O.n.> g l =+H @.@.R.4.t+0 t+5+>.[.w+%.m s.~+s.P _+x+Q.>+p+: 6+} ~ x.~ x.G x+x+s.$+$+^ _ u ",
+" . q v.q v.q q q v.v.v.3.% { ..$ .J {.H H.@.B+a 4.t+t+/+>.5+[.u+m s.s.G W.G x.x.W.2 P.s X e.x+~ r.G x+x+s.m ~+F _ ) ",
+" 6 6 q S.6 d.d.6 6 _.R g s+p p.J D H 2.! R.@.4.V.V.B >.w+[.w+%.u+m s.s.x+G i x.x.x+4+&+]+i+2 f Q.} s.$+Q.$+u+^ /+ ",
+" S.q 6 3.J.C # & K B.$ (.+./ D D j+H.@.R.R.4.4.,.t+t+>.w+[.[.$+~+s.s.P G x.x.x.x.r.f <+K : g I.] c !.)+u+u+_ ",
+" 6 3.-++ p+d p+p+:.(.; d.| }.J H t }.t Q 4.4.Q o+z.o+/+5+A+G.I G.~+P ( ( ( ( x.~ $.$.G.- N.y &.v ,+v ;+[.$+5 ",
+" . 6 % C a.J.; 6 3.| | | }.J D t t t t @.4.Q Q o+o+B w+o+G.I E.u+s.( g.%+$.r.x.$.%+( E.W.Q.- b.3 3 !._ [. ",
+" 6 6 6 6 6 6 3.3.9+5.J J D D (+=+H @.@.a 4.t+t+t+5+>.[.w+u+u+s.$+s.W.x+x+G x.x.x.x.x.x.i x+Q.^ ^ ^ _ ",
+" . 7+-+-+S.6 v.9+3.-.-.9+y+{.D+J J J @.a D D 4 H /+>.! @.@.@.m $+4.4.4.t+x+x+B B B ) G x+V.V.s.$+$+@+ ",
+" . 6 6 q q q v.e D+5.J v+y+(+=+H @.@.R.4.V.u V.t+/+_ w+[.u+$+~+Q.s.P s.P x+x+x+x+x+x+x+P P Q.$+5 ",
+" . 7+-+-+v.q 9+e 5.J / y+{.=+=+H @.@.q+B+t+V.V.t+B w+5+w+u+%.u+Q.s.s.P s.P P W.P P s.$+$+u+) ",
+" . 6 6 q 3.v.e e 5.J v+/ {.H =+H @.a 4.4.V.t+0 b+B _ w+w+u+$+m $+s.s.s.s.s.P s.Q.Q.Q.u+5 ",
+" . 7+q v.9+e e 5.J D D D H =+H ! @.@.4.4.t+V.B 5+/+_ w+w+[.u+u+u+$+s.s.u+s.m ~+u+u+@+ ",
+" 6 -+v.9+D+`.J J / D (+H 2.H.@.a 4.4.z+t+t+t+/+5+5+[.[.w+[.[.u+u+u+$+u+$+u+[. ",
+" . -+v.9+e 5.J J y+{.{.H H.! @.a R.4.4.V.V.t+/+B _ w+w+[.[.[.[.u+[.u+[./+ ",
+" 3.e 9+e J / / D (+=+=+@.H @.4.4.V.u t+B t+@+B /+/+w+w+w+[.w+_ /+ ",
+" -+O.e e J / y+{.D 4 @.@.2.@.q+a 4.4.V.V.t+B /+B /+/+_ 5+/+) ",
+" -.5.J / / j+(+(+=+! H.@.4.4.4.4.t+t+t+t+@+B t+4. ",
+" O.O.J D 4 j+=+=+2.@.@.4.4.4.4.4.V.V.@.a ",
+" / {.4 H H H 2.=+@.@.a 4. "};
diff --git a/arts/builder/pics/Synth_SEQUENCE.xpm b/arts/builder/pics/Synth_SEQUENCE.xpm
new file mode 100644
index 00000000..23caeb2f
--- /dev/null
+++ b/arts/builder/pics/Synth_SEQUENCE.xpm
@@ -0,0 +1,319 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 248 2",
+/* colors */
+" c #354280",
+" . c #303C7B",
+" X c #3F4C8D",
+" o c #695B5D",
+" O c #313972",
+" + c #3A4688",
+" @ c #313468",
+" # c #263071",
+" $ c #354283",
+" % c #838594",
+" & c #334081",
+" * c #323E80",
+" = c #1E2869",
+" - c #F4BE22",
+" ; c #EEE45E",
+" : c #1C2667",
+" > c #293477",
+" , c #283276",
+" < c #8C93B7",
+" 1 c #4D588D",
+" 2 c #212C6F",
+" 3 c #1E286C",
+" 4 c #515B9E",
+" 5 c #4E599B",
+" 6 c #3C4986",
+" 7 c #1A235E",
+" 8 c #4B5598",
+" 9 c #374581",
+" 0 c #364380",
+" q c #4E4A66",
+" w c #DCD48E",
+" e c #47548A",
+" r c #6772B0",
+" t c #212B68",
+" y c #404D8D",
+" u c #7A7D91",
+" i c #2D3977",
+" p c #535D8F",
+" a c #3A4787",
+" s c #293373",
+" d c #FBE73F",
+" f c #273171",
+" g c #A2A7C2",
+" h c #252F6F",
+" j c #38427B",
+" k c #8C653C",
+" l c #4D5C96",
+" z c #7B83AC",
+" x c #252F72",
+" c c #38447E",
+" v c #5F6A97",
+" b c #CAC07F",
+" n c #737BA4",
+" m c #313B81",
+" M c #333E79",
+" N c #1F296C",
+" B c #42508B",
+" V c #3C406E",
+" C c #1E296B",
+" Z c #1D276A",
+" A c #1C2769",
+" S c #303A76",
+" D c #C99732",
+" F c #293379",
+" G c #2C3672",
+" H c #283378",
+" J c #273177",
+" K c #242F74",
+" L c #374480",
+" P c #232D73",
+" I c #747DA8",
+" U c #212B71",
+" Y c #202B70",
+" T c #1E296E",
+" R c #A27D47",
+" E c #465188",
+" W c #404E8C",
+" Q c #303C79",
+" ! c #576292",
+" ~ c #3E4C8A",
+" ^ c #474E7F",
+" / c #A7ACC6",
+" ( c #2B3674",
+" ) c #9B9182",
+" _ c #7B82A8",
+" ` c #283271",
+" ' c #252E6E",
+" ] c #303C7C",
+" [ c #868BAC",
+" { c #2B3677",
+" } c #1B2464",
+" | c #606BAB",
+". c #C1A851",
+".. c #9097B9",
+".X c #666F9D",
+".o c #283474",
+".O c #3C4781",
+".+ c #374486",
+".@ c #656A92",
+".# c #212C6D",
+".$ c #202A6C",
+".% c #384073",
+".& c #1E286A",
+".* c #6B75A5",
+".= c #2D387C",
+".- c #1C2668",
+".; c #947449",
+".: c #4A5995",
+".> c #3A4782",
+"., c #263275",
+".< c #666E96",
+".1 c #485793",
+".2 c #475592",
+".3 c #465591",
+".4 c #222C71",
+".5 c #202A6F",
+".6 c #5A4B52",
+".7 c #333F7B",
+".8 c #1F2A6E",
+".9 c #1E286D",
+".0 c #1D286C",
+".q c #434E84",
+".w c #3F498A",
+".e c #31386F",
+".r c #5C67AD",
+".t c #384583",
+".y c #3A447B",
+".u c #333F7E",
+".i c #2E3B79",
+".p c #333C74",
+".a c #434B7D",
+".s c #F7B618",
+".d c #3A4588",
+".f c None",
+".g c #263171",
+".h c #364184",
+".j c #252F70",
+".k c #242F6F",
+".l c #484664",
+".z c #212B6C",
+".x c #5D6693",
+".c c #303B7E",
+".v c #1F296A",
+".b c #2D397B",
+".n c #1D2768",
+".m c #404C87",
+".M c #989AAF",
+".N c #4E5B8E",
+".B c #252F73",
+".V c #29306D",
+".C c #45548F",
+".Z c #35407C",
+".A c #212B6F",
+".S c #44528E",
+".D c #2F3980",
+".F c #E9A317",
+".G c #1D276B",
+".H c #404E8A",
+".J c #3E4C88",
+".K c #5A515E",
+".L c #9BA1C2",
+".P c #33407D",
+".I c #323E7C",
+".U c #313E7B",
+".Y c #424264",
+".T c #F5D836",
+".R c #656FAE",
+".E c #1D2664",
+".W c #3C4A89",
+".Q c #2C3876",
+".! c #2B3675",
+".~ c #384685",
+".^ c #465296",
+"./ c #5863A1",
+".( c #434E93",
+".) c #323C7F",
+"._ c #303A7D",
+".` c #9C9FB2",
+".' c #8E8E97",
+".] c #3C4982",
+".[ c #374287",
+".{ c #364286",
+".} c #354085",
+".| c #232E70",
+"X c #171F57",
+"X. c #46558F",
+"XX c #43518C",
+"Xo c #1E286B",
+"XO c #1C2669",
+"X+ c #2B367B",
+"X@ c #6A554F",
+"X# c #263076",
+"X$ c #9096B3",
+"X% c #253075",
+"X& c #242E74",
+"X* c #232E73",
+"X= c #36417F",
+"X- c #212C71",
+"X; c #202A70",
+"X: c #43518F",
+"X> c #B6AD96",
+"X, c #8289AF",
+"X< c #3D4B89",
+"X1 c #414C83",
+"X2 c #2A3573",
+"X3 c #414979",
+"X4 c #283371",
+"X5 c #B8BCD0",
+"X6 c #BD8933",
+"X7 c #575B7E",
+"X8 c #5B6799",
+"X9 c #7F87AF",
+"X0 c #3C478B",
+"Xq c #7D85AD",
+"Xw c #283374",
+"Xe c #39467E",
+"Xr c #F8AF10",
+"Xt c #343F83",
+"Xy c #232D6F",
+"Xu c #222D6E",
+"Xi c #333D82",
+"Xp c #212B6D",
+"Xa c #303D7F",
+"Xs c #54609F",
+"Xd c #2E3B7D",
+"Xf c #775F51",
+"Xg c #424E8A",
+"Xh c #1D2769",
+"Xj c #515E9C",
+"Xk c #58556E",
+"Xl c #2C377B",
+"Xz c #2A3579",
+"Xx c #293578",
+"Xc c #40477E",
+"Xv c #757487",
+"Xb c #222D71",
+"Xn c #8890B4",
+"Xm c #455490",
+"XM c #878EB3",
+"XN c #6E78AB",
+"XB c #4D5684",
+"XV c #1F296E",
+"XC c #1E296D",
+"XZ c #41508C",
+"XA c #4A5281",
+"XS c #69719C",
+"XD c #3B4886",
+"XF c #5B6081",
+/* pixels */
+".f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f # , > F HX# KX&.4.8 C.n.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f G.I.[.}Xi.D.=X+ F JX% K P.4X- YX;XV } 7.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f 6.(.(X0.[.}Xi.D.=X+ F JX% K P.4X- Y.5.8XV TXo 7.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.fX= 4 5 8.(.(X0.[.}Xi.D.=X+ H JX%X& P.4X- Y.5.8XVXC.9.9 3XO 7.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f./.r 4 5 8.( XX0.[.} m.D.=X+ H JX%X& P.4 U Y.5.8XVXC.9 3 3.0.G.-.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f.f.f.f.f 5 |.r./ 4 5.^.( XX0.[.} m.D.=X+ H JX%X& P.4 U Y.5XVXVXC.9 3 3.G.G.GXO 7.f.f.f.f.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f.f.f.f r r.r.rXs 4 8.^.( XX0.[Xi._.bX+ F H JX%X& P.4 YX;.5XVXVXC.9 3 3.G.G.G Z Z :.f.f.f.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f.f E r r.R.r.rXs 4 8.^.(X0.d.[.) M.i { H HX#X%X*XbX- Y.5.8XVXV.9 3 3.0.G.G Z Z Z Z.-X .f.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f 1 r r.R.r.rXs 4 8.^.( XX0.[.}.%Xk V OXw JX# KX*XbX- Y.5.8XVXC.9 3 3.G.G.G Z Z ZXhXO :X .f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f l r r r.R.r./Xs 4 8.^.( XX0.{XtXk R o VX4 JX%X& P.4 U Y.5.8XVXC.9 3 3.G.G.G Z Z ZXhXOXO :X .f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f 1 r r r.R.R r.R |./Xs.2 XX0.d.h LXF. o.p.Q JX%X& P.4.A.8XVXoXo.GXo 3.G.G.G Z Z ZXh AXOXO.- :X .f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f E r r r.R |XN < <XnX9XN l.w.d.[.h.]Xv. o O.bX#X%X*XbX- YXV.v.v.v Z N 3 3Xo.G.G Z Z ZXhXhXO.-.- :X .f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f r r r.R.R z < / g.L..X,.X.N.w.{.t e u bXk ( {X% K P.4X- x f O.%.e.V h N 3 3 3XoXoXoXo.& ZXhXh.-.- :.f.f.f.f.f.f.f",
+".f.f.f.f.f.f r r r | | z /X5X5X5X5 /.LXM I 1.h.m ! % bXk.! >X%X& P.4.5 `Xc ! _.x.q G.$.A.8.$.$.$.$.$ N.vXo.&.&Xh.n }.f.f.f.f.f.f",
+".f.f.f.f.f 5 r |.r |XN < /.. _ nXS I z z z 1Xt.q.< % )Xk ,., KX* PXy.#.p v n < n p.p.#Xu 2 2 2.#.#.#XpXp.$.$.v.v.v = 7.f.f.f.f.f",
+".f.f.f.f.f |.r.r.r.*.L /X5 I l.2X: l.XXNX9 1 *XAXS % )Xk.,.BX&X* PXu '.a [.. gX,XS.y.kXy.|.|.|.|XyXyXyXuXu.#Xp.z.$.$ =.f.f.f.f.f",
+".f.f.f.f./.r.r./Xs.*.L.L.L.X.2 y.w.wXg E E c.c.a u % ) ^., x x.|Xb f M p [.. / [.X.y.g x.B x x x x x x.k.|XyXyXu.#.z.$ =.f.f.f.f",
+".f.f.fX=.r./Xs 4 4.* /.L <X8.( XX0.d.[Xt.)._.=X3XvXv uX3 f.B x x x.p pXSXM.L /XM.X.y f #.,.,.,.,.g.g.g x # x.k.kXyXu.#.#.E.f.f.f",
+".f.f.f 4 4 4 4 5 8.X /.LXMXs XX0X0.[XtXi.c.).uXF ).'.'XF.y j.p G `X3XS nXqX$ g [XSXcXw., , >.oXwXwXw.,.,Xw.g.g #.j.kXyXu.$.f.f.f",
+".f.f.f 5 5 5 8.^.^.X /..X9XjX0.d.[.}Xi m._X=Xg _X5 gX$ _.X v.x.a OXBX$Xq nXM.LX,XSXc.! >XzXxXxXx > > >.o.oXwXw f.g #.j.kXy.f.f.f",
+".f.f 6 8 8.^.^.(.(X8 g..XM p.d.h.} m.c.Z.] E p [X5 /.`Xn _ I n.xXAXS.LXM _X$ /X$ _ ^.Q.Q ( (X2X2 (.!.! >.!.o.o.oXw f f.g h.E.f.f",
+".f.f.(.(.(.(.( X.w !.L.. < p L & m.c .X1 v.X.X.`X5X5 g.`..X$ <Xq n < /.. _.LX5.LXMXB Q Q.p O G G G (.Q { { { {.!.o.oXw f.g h.f.f",
+".f G.(.( X X XX0X0 1X9.. g.* e.O.I j.q.xXqXS p.'X> %X7XB ^XAXA p !.*XMXq I..X5 gXM.x.aXk o.K.6.6.6.6.Y @ @ G.Q.!.!.!X2 sX4 f t.f",
+".f.IX0X0X0X0X0.[.[Xg.X <X5.. n 1.Z 1 IXM gXSXA uX>Xk.e G s (.Q.Z E p.XXS n..X5 g < n.@Xv RX6X6X6X6 k kX@.l @.Q.Q i.Q.!.!.oXw t.f",
+".f.[.[.[.[.[.[.}.}X=.q vXMX,XqXS p.< _ n n.xXB uX>XF S.!.!.Q S Q.I cX1.q.q.@ <XM [.' ). D D.F.F.F DX6 kXf.l @ G i.Q.Q.Q.!X2X4.f",
+".f.}.}.}.}.}.}XiXi m.cX1X8 I <XnXMX,Xq v e 1XF uX>XFXlXlXl.=.bXd.b._ ].U M.qXS n _ ). - -.s.s.sXrXrXr DX6X@.Y.e.i.i.i i.Q.!X2.f",
+" #XiXiXi m m m m.D.=.= Q cXc ^ ^.a.aXc j S.aXFXv )X7XlXl.b.=Xd.cXd ].c.I.I j.qXF % ) - - -.s.s.sXrXrXr.F.F k.6.Y Q.i.i.i i.Q.!X4",
+" ,.D.D.D.D.D.D.D.=.=XlXzXz , s f # # # f., VXvXv )XAXl.bXd.c.cXaXa * & & & & XA %. - -.s.s.sXrXrXrXrXrXrX6 k.Y.U ].U Q.i i iX2",
+" >.=.=.=.=.=XlX+X+X+Xz H J.,.g x x # s , ,X3XvXvXvXk.bXd.cXaXa * * &Xt $ $ $ 0Xk.;. - -.s.s.sXrXrXrXrXr.FX6Xf.Y.P.I.I.I Q.i.i.Q",
+" FX+X+X+X+X+Xz F F H H J JX#X#X%.BX%X# , ,Xk )XvXF q.=.cXaXa * & & $ $ $.{.t.t q.;X6 - -.s.s.sXrXrXrXrXr.F RX@.Y .P.P.U Q.i.Q",
+" H F F H H H H H J JX% x.V.V @.V.V @.e G.!Xk )XvXk.lXd.cXa * & & $ $.{.+.+.~.t.K RX6 D D D.F.F.F.F.F.FX6X6Xf.l V $ 0 .P.P.I Q.i",
+"X# J J J J J JX#X# K.B.V V.l q q.l V.p O GXk. oX3 V.cXa * & & $ $.{.+.~ +XD.>.KX6 R R R RX6.F.F.F.F D RXf.K V j.t 9 0X=.P.P.U.i",
+" KX%X%X%X%X%X%X&X&.V @ q oXf.;.;.;.; o oXk.; bXv ^.y ].).u & $ $.{.+.~ + +.].O.KX6Xf.K.K.K oX@XfXfXfXf.K q V.y L.~.t 9 0 .P.I Q",
+"X& K KX&X&X&X& PX* @.K.;. . ; ; ; ; ;. ). b % E c.I.u.u $ $.{.+ + + +.WX1Xc oX6 oX3.a.mXcX3X3X3X3 qX3.O.] 6 6XD.~.t 9 0X=.P.U",
+".4 P P P P P P 2 '.Y.;. . .T d d d ; ; ;. b w.'.x 1.qX1X1.].~.~.~ + +.W.W.qX3 oX6 o.aX1.H.mX1X1X3.a.a.] 6.J ~X< 6XD.~.t 9 0.P.I",
+".8.4.4.4.4.4.4.z t.6. . .T d d d d d d ; ; w w.` I n.*.XX8.q L L.~ +.W.W X ^X3 oX6 o.qXgX:XZ.H.H.m.m.H.H W W.H.JX< 6XD.~.t L .7",
+" CX-X-X- U U Y.$ t.6. -.T d d d d d d ; ; w w /XMXMX,X,XM v E.O.~ a.W X X ^ q o R.K B.SX..N p p p.N 1.q.H.H W.H.JX< 6XD.t.t 0.Z",
+".n Y Y Y Y YX; t.VX@ D -.T.T d d d d d ; ; wX5X5.L.L.L /X5.. n e.>XD X X yX3XkXf.;Xk.S 1X8 nXnXnXnX, _ p B.HXZXZ.H.J.W 6.>.> L.P",
+".fX;.5.5.5.5.5.v t.Y.;X6.T.T.T.T.T.T.T ; w wX5 % p p.NXSXM <...< E 6 ~ W yX3.KXf kXk.C pXNXqXn n.< nX$XS.NXXXZXZ.H.H.J 6XD.t 9.f",
+".fXV.8.8.8XVXV 3.v @.6.; D -.T.T.T.T.T ; wX> /XF.p M.Z.q v <X5XnX8 E ~ WX:X3 oXfXfXk.2X8XMXMXM.< 1XS gX,.X 1XXXZXZ.H.J.J 6.> L.f",
+".f }XVXVXVXVXV 3.G t @.6 k RX6 D D. . bX>.`.`X7 SX=.t.m EXSX5Xn.X e ~.HXZ qXfXfX@X7.2 ! I I I v.NXS /Xn.*.N.SXXXXXZ.H.J 6XD.p.f",
+".f 7 TXCXCXCXC.9.9.n t @.Y.6Xf.; R R R )X$X$X$XA S 0 $XD c p.LXn I.N.H.HXZ q kXf.KXA.1 !.*.*.*X8.NXS /.. I.N.S.S.SXZ.H.J 6 6 M.f",
+".f.fXo.9.9.9.9 3 3 Z.n.V.% V.Y.Y.l qXk.@ _ [X$XA Q 0 $XD L p.L <Xq v 1.N.NXv RXvXv.x lXjX8X8.*.*XS [X5.. I p.C.S.SXXXZ.H.J.>.f.f",
+".f.f 7.9 3 3 3 3 3 3.G 3 3.8.AXy # s SXAXSXq..XA Q 0 $XD 9 p.L..X, I.* I z.M b ).' _.*X8 lX8.*Xq.. /X5.L z pX..S.SX:XZ.H.J j.f.f",
+".f.f.f 3 3 3 3.0.G.G.GXo 3.8 2Xb x f (X1XS zX$XA Q.u $.t c ! g..X9 z IX, <.` bX>.MX, IX8 lXjX8X8.<Xq /..Xn !X..CXm.SXZ.H.J.f.f.f",
+".f.f.fXO.0.G.G.G.G.G.G.G 3.$ 2.| x.g.oXcXS zX$XA S.I &X= c.x /..XqXqX9...LX5 wX5 /.. zX8 l l l l p.X <...L ! e.SXm.SXZ.H 6.f.f.f",
+".f.f.f 7.G.G.G.G.G.G Z.GXo.$ 2.| x.g sXcXSXq..XB.p M.ZXeXB n / n p p p v u ) b.' n.<X8X8 v v v ! pXS.L.... ! e.SXm.SXZ.HXe.f.f.f",
+".f.f.f.f.-.G.G Z Z Z Z ZXo.$.#.| x.g sXc.XXq..XB.p M jXB _X$ /.xX1.m B eXFXv. Xv p.N.NX8X,X9X9.X !XS g.L.. ! e.SXm.SXZ.m.f.f.f.f",
+".f.f.f.f.fXO Z Z Z Z Z ZXo.$.#Xy x #Xw j.x nX$.<XBXBXB.@Xq _XqXB.].J.H ^X7Xf R o 1.: lX8 IX9Xn _XSXq.LXn I pX..C.CXX.H.f.f.f.f.f",
+".f.f.f.f.f 7 Z Z Z ZXh ZXo.$.#Xy x xX4 M 1XSX$ [ [ [ [X,X,.* !.q.W.HXZX3 qX@ k.K.1.: lXj.X z....X$.... _.X.N.2.C.CXX.O.f.f.f.f.f",
+".f.f.f.f.f.f : ZXhXh AXh.& NXpXy x.gXw S.p.y ^ ^ ^ ^ ^XAXA.q.m.m ~ ~ WX3.KX@ k q.1.: lXjXjX8 v v v v v ! l.1.3.C.S.H.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.-XOXOXOXh Z.vXpXu.k x.,.!X2 ( G.Q S Q M.7.Z L.~.WX< ~.H V.6X@ k q.1.:.: l l l l l l.:.:.:.1.2.2.C B.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.fX :XOXOXOXhXo.$Xu.| #Xw.o.! i Q.I.PX= 0 L.t.~ a 6.W.J ~.lX@X@X@ q.2.1.:.: l l l l l l l.:.2.3XmXX.y.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.fX :.-.-Xh.&.$.#Xy x.gXw.o { i.i ].I.u $.t.~XD.WX<.J.l kX@.6X3Xm.1.1.:.:.:.:.:.:.:.:.1.2XmXX.y.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.fX :.-.-.&.vXpXy.k.gXw.o { i.i ..I.u & .t.t.~XD 6 6 q kX@.6X3Xm.3.2.1.1.:.:.:.1.1.2.2XmXX.y.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.fX :.-Xh.v.zXu.k # f.o.!.Q i.i ].I.u $.t.~ a.>.>.6 kX@.lX3.SXmXm.3.2.2.2.2.2.3.3.CXX.y.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f.fX :.n.v.$.#Xy.j.gXw.o.! i.i ..I.u.u $.t.~.t.>.l k.6 VXcXX.S.S.SXmXmXmXm.C.C.S B.y.f.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f.f.f.f } =.$.zXu.k # f.o.!.Q i.i ..I.u 0 9.t 9 c.YX@.l.y.]XZXZXXX:.S.S.S.SXXXX.H.f.f.f.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f.f.f.f.f 7 =.$.#Xy.j fXwX2.!.Q.i.i.U.I.P 0 9 L L.%.Y VXe.].H.HXZXZXZXZXZXZ.H.O.f.f.f.f.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f =.#Xu.k.g f s.!.Q i.i Q.I.P.PX= 0 0 L 9.>.>.] 6.J.J.H.H.H.H.H.m.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.E.$Xy h.gX4.o.!.Q i.i Q.U.P.P 0 L 9.>.> 6 6 6.J.J.J 6Xe.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.E h fXwX2.!.Q i.i Q.I.P.PX= 0 L.t.>.t.>XD 6.> j.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f t tX4X2.! i.i.i Q.U.I.P.P 0 L 9 L.p M.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f",
+".f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.fX4X2.Q.Q.i.i Q.U.I.7.Z.P.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f.f"
+};
diff --git a/arts/builder/pics/Synth_SEQUENCE_FREQ.png b/arts/builder/pics/Synth_SEQUENCE_FREQ.png
new file mode 100644
index 00000000..ebd9d829
--- /dev/null
+++ b/arts/builder/pics/Synth_SEQUENCE_FREQ.png
Binary files differ
diff --git a/arts/builder/pics/Synth_SHELVE_CUTOFF.xpm b/arts/builder/pics/Synth_SHELVE_CUTOFF.xpm
new file mode 100644
index 00000000..bbee7585
--- /dev/null
+++ b/arts/builder/pics/Synth_SHELVE_CUTOFF.xpm
@@ -0,0 +1,247 @@
+/* XPM */
+static char * Synth_SHELF_CUTOFF_xpm[] = {
+"64 64 180 2",
+" c None",
+". c #161E54",
+"+ c #4A9A2C",
+"@ c #4A5A94",
+"# c #2E3E7C",
+"$ c #62CA2C",
+"% c #4A8644",
+"& c #3E4E84",
+"* c #66E614",
+"= c #52AE2C",
+"- c #222E64",
+"; c #364684",
+"> c #46725C",
+", c #8692B4",
+"' c #6E769C",
+") c #52629C",
+"! c #4A529C",
+"~ c #6EF614",
+"{ c #2A3674",
+"] c #7E86AC",
+"^ c #363E84",
+"/ c #62DA14",
+"( c #46568C",
+"_ c #3E4684",
+": c #969ECC",
+"< c #1A2664",
+"[ c #52A62C",
+"} c #424E94",
+"| c #767EA4",
+"1 c #525A94",
+"2 c #222E74",
+"3 c #62D224",
+"4 c #6AEE14",
+"5 c #8E9ABC",
+"6 c #5A62AC",
+"7 c #7EFE1C",
+"8 c #323A84",
+"9 c #56BE1C",
+"0 c #3A4A7C",
+"a c #6E7ABC",
+"b c #2E3A74",
+"c c #868EB4",
+"d c #36427C",
+"e c #222A64",
+"f c #5A9E44",
+"g c #4E5E94",
+"h c #32427C",
+"i c #464E8C",
+"j c #6EE624",
+"k c #5E6AB4",
+"l c #8E92C4",
+"m c #52669C",
+"n c #72FE14",
+"o c #3E4A84",
+"p c #2A3274",
+"q c #36428C",
+"r c #767AA4",
+"s c #4A5694",
+"t c #56A644",
+"u c #425294",
+"v c #66D224",
+"w c #6672BC",
+"x c #162254",
+"y c #4E5AA4",
+"z c #323E84",
+"A c #62CE24",
+"B c #42528C",
+"C c #6AEA14",
+"D c #56BA1C",
+"E c #26326C",
+"F c #3A468C",
+"G c #727AA4",
+"H c #2E3674",
+"I c #7E8AB4",
+"J c #62E214",
+"K c #1E2A6C",
+"L c #7E82B4",
+"M c #525EA4",
+"N c #263274",
+"O c #3A427C",
+"P c #666EB4",
+"Q c #7AFE14",
+"R c #3E4A94",
+"S c #4E5694",
+"T c #52A22C",
+"U c #4E5A9C",
+"V c #323E74",
+"W c #424E8C",
+"X c #262E6C",
+"Y c #3A467C",
+"Z c #8A96BC",
+"` c #7276A4",
+" . c #5662AC",
+".. c #9AA2CC",
+"+. c #1E2664",
+"@. c #7A82AC",
+"#. c #6AF214",
+"$. c #929AC4",
+"%. c #5A66AC",
+"&. c #86FE1C",
+"*. c #6EC644",
+"=. c #3A4A8C",
+"-. c #2E3A84",
+";. c #8A8EBC",
+">. c #222A74",
+",. c #56A24C",
+"'. c #626EB4",
+"). c #8E96BC",
+"!. c #5666A4",
+"~. c #56AA44",
+"{. c #465294",
+"]. c #66D62C",
+"^. c #1A2264",
+"/. c #4E9E2C",
+"(. c #4A5A9C",
+"_. c #62CA34",
+":. c #6A76BC",
+"<. c #3E4E8C",
+"[. c #6AE624",
+"}. c #56AE34",
+"|. c #222E6C",
+"1. c #8A92BC",
+"2. c #6E76A4",
+"3. c #5662A4",
+"4. c #72FA14",
+"5. c #2A367C",
+"6. c #7E86B4",
+"7. c #62DE14",
+"8. c #465694",
+"9. c #5EC22C",
+"0. c #5ED614",
+"a. c #52AA2C",
+"b. c #46528C",
+"c. c #6EEA24",
+"d. c #5ABA2C",
+"e. c #525AA4",
+"f. c #6AEA24",
+"g. c #1A225C",
+"h. c #5AA244",
+"i. c #9A9ECC",
+"j. c #464E94",
+"k. c #262E74",
+"l. c #82FE1C",
+"m. c #626AB4",
+"n. c #76FE14",
+"o. c #3A428C",
+"p. c #5AA644",
+"q. c #6AD224",
+"r. c #66CE24",
+"s. c #828AB4",
+"t. c #66E214",
+"u. c #565EA4",
+"v. c #424A94",
+"w. c #6EF214",
+"x. c #5E66AC",
+"y. c #3E468C",
+"z. c #767EAC",
+"A. c #8E9AC4",
+"B. c #3A4A84",
+"C. c #6E7AC4",
+"D. c #2E3A7C",
+"E. c #868EBC",
+"F. c #364284",
+"G. c #222A6C",
+"H. c #4E5E9C",
+"I. c #324284",
+"J. c #5266A4",
+"K. c #3E4A8C",
+"L. c #2A327C",
+"M. c #4A569C",
+"N. c #2E367C",
+"O. c #26327C",
+"P. c #3A4284",
+"Q. c #7AFE1C",
+"R. c #4E569C",
+"S. c #323E7C",
+"T. c #3A4684",
+"U. c #1E266C",
+"V. c #8E96C4",
+"W. c #46529C",
+" N p p L.L.N k.2 >.G.K +. ",
+" e b F.F.8 -.D.5.O.k.N k.2 2 G.2 ^.. . . ",
+" H o v.y.o.F.z -.N.N.5.O.N k.>.2 K K K U.^.^.. . ",
+" b U R.s j.v.F q ^ 8 -.D.5.O.k.2 2 2 >.2 2 >.K K < ^.. . . . ",
+" 1 u.M R.! } R F q I.8 N.5.5.5.L.N k.2 >.K K K K >.K K U.U.^.. . ",
+" S m.x. .e.R.{.} v.y.q ^ z -.N.L.N N k.2 |.2 >.>.>.U.K K U.K U.K ^.. . . ",
+" '.'.k 6 u.y M.j.v.y.F q z 8 -.N.L.O.O.k.k.>.|.K K >.U.K K U.K U.K U.< ^.. . ",
+" i :.w m.%. .M y M.W.R =.o.^ 8 # D.5.5.p N N 2 2 >.2 >.K >.U.U.K U.K U.U.U.U.^.. . . ",
+" O 2.w w m.%.3.e.M.! j.v.y.F F.8 -.D.5.O.O.k.2 k.2 >.|.>.K K K U.K U.U.< U.U.< U.^.. . . ",
+" S a w w m.%.6 M U M.{.} K.F q ^ z N.5.L.L.k.O.k.2 G.>.K K K K K K U.K K K U.K K U.K ^.. . . ",
+" O 2.:.P '.k %.u.e.R.W.} R y.o.q z z -.N.{ L.k.k.2 2 |.>.2 >.K K U.>.U.U.U.K < U.K < U.< ^.. . . ",
+" i :.w w P k %.u.M y M.W.} R F F.z z D.N.5.L.N N N k.2 K >.K K U.U.K U.K K U.U.U.< U.U.K U.U.^.. . . ",
+" w :.P '.x.%. .M y M.{.j.v.K.F q z 8 D.D.5.5.O.2 2 2 2 2 K K K >.K K U.U.K K K K U.K U.< U.< < ^.. . ",
+" w w P ..i.%.6 M y M.! j.<.K.o.q ^ 8 -.-.5.5.N k.k.k.>.>.K >.>.>.K >.K K K K K K K K K K K K U.U.K ^.. . ",
+" o P P m.: : u.M e.R.W.j.v.y.F o.F.^ 8 N.5.L.L.N N 2 k.X 2 2 2 2 2 K 2 2 2 2 K >.>.2 >.2 2 >.2 K K K K < ^.. ",
+" m.m.%.%. .M M e.M.! W.} v.=.F F.^ z D.D.5.5.N O.k.k.2 2 >.>.K |.>.2 2 2 2 2 2 2 2 2 |.G.G.|.G.2 G.>.G.K . . ",
+" S %.6 . .u.y y R.8.j.} R y.F o.z z 8 N.N.5.L.N O.N 2 2 k.2 N 2 N k.2 2 2 k.N N N X N N N 2 N |.2 |.|.>.|.K < . ",
+" ^ 6 u.) y.e.V.V.M.W.j.} R R F o.z ^ D.D.D.5.N N N k.2 N k.N N k.k.2 N N N N N k.N N N N N k.N k.N E k.2 X 2 G.G.g.. ",
+" i M e.y F M.l 1.W.} v.R F o.q q z 8 -.5.5.5.L.O.N N k.N N N N N p N p N p N { N N 5.N N { N { N N N E N X N E |.G.< ",
+" y R.R.R.P.! , E.} v.R y.o.q ^ z 8 -.N.N.L.L.N p O.p N N N N O.O.N N O.{ { 5.O.5.{ p 5.{ N { N p p { p N N k.k.|.E g. ",
+" H ! W.W.j.^ j.E.s.R y.o.F P.^ 8 # 8 D.5.5.p L.N N O.5.p L.L.{ { 5.5.{ 5.5.{ D.H 5.D.{ 5.D.5.b 5.5.{ 5.{ { { N p X p |.< ",
+" j.u } } } <.R y.y.F ; o.^ z z S.-.D.5.5.p O.{ L.L.N N 5.N { L.5.{ N.N.N.5.N.5.D.D.5.D.D.5.D.5.b D.{ { { { { { { { E - . ",
+" +.v.v.R R y.y.y.y.o.o.F.^ z z 8 N.5.N.5.L.{ O.N p 5.5.N 5.L.5.{ 5.D.D.D.D.D.D.D.D.# D.D.S.D.# D.D.D.D.D.N.5.{ { { { p { E +. ",
+" b F F y.o.F -.F 6.6.^ z z z -.N.D.N.L.p { O.p L.5.5.p 5.5.b D.5.D.D.5.D.D.D.D.D.D.8 # # D.# 8 # D.# D.D.D.b D.{ 5.{ { p - . ",
+" ^ P.q o.q ^ 5.I.6.6.z 8 8 N.-.N.5.5.O.O.N L.{ N L.5.5.5.5.5.D.D.D.# D.# # # z S.# z S.h S.S.S.S.S.S.S.# S.D.8 b H { { H p E ",
+" ^ q ^ I.^ z L.8 L @.-.D.5.D.5.L.5.N p p L.{ O.5.5.{ N.D.5.D.D.D.D.D.# S.z z S.z F.^ ^ z ^ I.z I.S.z S.S.# S.# D.# D.b { { p ",
+"N z z 8 z z 8 p D.z.@.-.N.5.5.5.N L.O.N N O.{ { 5.5.5.{ D.D.D.-.D.z 8 z S.^ I.d z h I.F.F.F.d F.F.d I.F.^ S.S.S.D.S.D.b b b b { ",
+"N D.-.-.N.-.D.D.-.D.N.5.5.L.p N L.N N O.5.p L.5.5.5.D.D.D.D.D.D.z S.h z z I.F.F.; F.; ; ; F.; F.F.F.F.d I.d F.d h S.S.S.D.b { { ",
+"L.N.N.-.N.5.5.5.L.L.p 5.O.O.N k.k.k.k.N O.{ p 5.b 5.D.D.-.# z S.z z I.d F.F.F.F.T.P.P.; T.T.T.T.; T.; T.F.F.I.^ S.S.S.# D.b b H ",
+"N 5.5.L.5.5.L.|.5.| z.N N N k.N N N N N { O.5.5.5.D.D.D.8 8 # z z F.F.F.F.F.; T.; ; =.T.T.F F ; T.T.F ; ; ; O ; F.F.S.S.S.S.D.D.",
+"p L.5.N L.5.L.>.O.r r > h.p.,.,.,.h.,.h.p.t p.t t t ~.~.~.~.~.}.~.~.,.; ; ; ; F =.T.y.=.B.B.K.=.=.T.T.T.T.; F.; d F.d h S.# D.b ",
+"k.N k.O.N k.N G.N G G f &.&.&.l.l.7 7 7 Q Q Q Q Q n.Q n.n.n.n n.n n n [.= F F =.K.=.=.K.K.K.=.K.o =.K.=.B.=.B.T.; ; F.^ h S.S.D.",
+"k.O.k.k.O.2 N G.N G G % v v v v v v 3 r.r.A A A A $ A A 3 j [.c.n n n 4.w.= B.=.K.<.<.<.<.W <.<.<.<.& K.o _ B.T.T.; ; d d h h S.",
+"2 2 2 2 2 k.2 2 2 2 2 2 G.G.G.G.X |.k.N N 5.b D.D.# # S.^ I.F.F.].[.C 4.n w.a.K.<.K.K.<.<.<.W <.W <.v.<.K.<.K.=.T.T.T.P.d ^ ^ D.",
+">.k.k.2 2 >.>.>.2 >.2 2 |.G.|.G.k.N N 5.{ 5.5.D.D.8 # S.^ F.; F.; F =.3 f.~ #.a.W B } } B B } W W B <.<.K.K.& K.o T.B.; ; d d S.",
+"G.2 2 G.>.k.2 K >.G 2.>.K 2 >.2 N k.p N L.5.b D.D.# z I.I.F.F.F F F F K.=.].w.4 = } B B u u b.B u W B B B & v.& =.B.T.T.T.d d S.",
+"U.K 2 |.K >.G.K G.G 2.G.K K |.K N N N { { 5.5.D.D.8 S.z I.F.; T.B.=.=.<.<.<.].#.4 a.{.{.{.8.8.{.8.u u B u B <.W K.=.B.T.T.; ; d ",
+"K >.>.K >.K K U.K ` G K K >.K 2 2 k.N O.5.5.D.D.S.z S.F.; ; q ; F K.<.K.W W u v 4 C a.( 8.{.{.8.{.8.{.u b.B B <.W & K.B.B.T.O S.",
+" K >.K >.>.G.U.K ` 2.U.K >.|.2 N N { N { D.D.D.# z h F.F.T.F B.=.K.<.<.u W u 8.3 4 * a.@ @ 8.@ 8.8.s 8.{.{.b.B W <.K.B.T.; T. ",
+" K K >.K K K K K K G.>.K K >.|.2 k.N { 5.5.D.D.z h ^ F.; ; T.F =.K.<.<.<.u {.u 8.9 C * [ 8.@ 8.s @ 8.8.( u B W W W <.o o T.; ",
+" . +.K K U.K >.U.K K U.K K >.2 N N L.{ { D.D.8 S.z S.F.F.; =.o <.K.} u B B 8.8.M.8.a.* * [ (.@ @ @ @ 8.s 8.8.b.B W <.<.o T.V ",
+" g.K K K K U.< K 2.2.K K G.|.X k.k.N 5.D.5.D.# z h F.F.F F T.=.=.<.B W u 8.{.8.@ (.@ [ * J [ H.U U @ (.@ 8.( 8.B B W o o Y - ",
+" ^.U.K K U.< U.` ` U.K K K 2 N N N p D.D.D.D.z I.F.F.T.=.F o K.K.} B u 8.8.8.8.(.g @ a.* J [ g U g @ @ 8.8.{.B W W <.B._ ",
+" ^.K U.U.K U.K ' ' K U.>.|.2 k.N p 5.{ D.D.S.S.S.F.; ; T.o K.<.<.B } b.8.s M.@ @ (.H.g [ 7.7.[ H.(.(.(.s ( 8.b.B B & & E ",
+" ^.K U.U.+.U.2.` K U.>.G.|.k.N N 5.{ D.D.z z I.F.F.; F =.K.<.<.B u {.{.@ @ (.(.H.H.H.) [ 7.7.[ g U g @ 8.8.8.B W W W ",
+" U.U.K K < K U.< U.K K |.2 N N { p 5.D.D.D.S.^ I.T.F T.B.K.W W } B 8.8.8.8.@ g (.H.H.) ) [ 7./ 9 /.(.@ @ 8.B B B & O ",
+" . ^.< U.U.U.U.< < U.G.|.|.N N { { 5.D.# S.S.^ h F.; F =.=.<.B } B 8.8.@ (.(.g H.) ) m m m d.7.J / D + @ s {.b.W & _ ",
+" U.U.U.< K 2.` K K K G.2 2 N N 5.{ b 8 D.S.I.F.; T.T.B.K.K.<.B u u {.8.8.@ U H.H.H.) ) J.J.A 7.7.7.0.}.8.( B B 0 ",
+" ^.U.^.U.' 2.U.U.K G.X 2 N N { 5.b # # S.S.F.F.; T.B.K.K.<.W b.8.8.@ M.@ (.H.) ) ) ) ) ) M $ A 3 0./ 8.b.b.W ",
+" < U.K U.' ` 2.` K |.` G r | 5.{ z.z.@.@.F.d 6.6.s.s.=.<.c c E.c {.8.Z Z ).Z H.H.A.A.: A.) g 5 Z *.7.b.( B H ",
+" . U.U.' ' ' ` K |.G G r r { H @.L ] @.z d s.I s.s.o K.c c , 1.{.8.Z Z ).Z H.H.$.).5 5 H.g ).5 1.Z b.B W ",
+" < < ^.U.+.K U.K |.N N N p { H { D.S.S.h d F.T.T.F <.<.<.W B B 8.s @ @ U (.g H.g H.H.g (.@ s ( b.( B ",
+" . ^.< < ^.+.U.G.+.K |.|.{ { N E E N z z { { b b T.=.S.S.S.h b.B F.F.; Y (.@ B.T.T.T.@ U ; Y 8.B i Y ",
+" . U.U.< < K K |.|.|.N N { { N.D.S.S.S.d F.; F B.o K.<.W W } 8.b.( 8.8.s @ @ @ @ @ @ @ s 8.( b.{ ",
+" . g.U.U.U.K G.2 2 N N { { D.b D.S.S.d F.; T.; B.=.<.<.B W u u b.8.8.8.8.s s @ @ 8.( ( b.B Y ",
+" . < < U.U.G.G.X k.N N { { D.D.# S.z S.F.F.T.T.o B.<.K.<.B B u b.( 8.s 8.8.8.( ( 8.b.B H ",
+" . g.K K G.K |.X N N { { b D.# S.h d d F.; ; B._ & & K.W B B u b.B ( ( b.{.{.b.B B Y ",
+" ^.K K |.|.N k.p N { 5.H D.# z S.I.F.P.T.F B.F K.<.& W W W B B u B u B B B B ",
+" . U.K G.X E N N { 5.H b D.S.S.h h F.F.T.B.B.B.K.o <.<.<.W W W B B B & Y ",
+" K |.|.2 E p p { b N.b D.S.S.h ^ ; F.F.T.T.B.B.o & v.<.& <.W & o ",
+" g.G.X |.E N N { N.b D.8 V h ^ d ; d T.T.T.B._ B.o o & o o _ ",
+" e E p p { { { b # 8 # V h ^ d F.P.T.T.B.B.B.B.d ",
+" - - { { { H b b # 8 h d d h ; d F.T.V V ",
+" { { { H b # 8 # S.d ^ h "};
diff --git a/arts/builder/pics/Synth_WAVE_SAW.xpm b/arts/builder/pics/Synth_WAVE_SAW.xpm
new file mode 100644
index 00000000..2f515dc4
--- /dev/null
+++ b/arts/builder/pics/Synth_WAVE_SAW.xpm
@@ -0,0 +1,323 @@
+/* XPM */
+static char * WAVE_SAW_xpm[] = {
+"64 64 256 2",
+" c None",
+". c #161E54",
+"+ c #329224",
+"@ c #2A563C",
+"# c #223A54",
+"$ c #36763C",
+"% c #264E44",
+"& c #3EC60C",
+"* c #4A568C",
+"= c #36AE14",
+"- c #323E6C",
+"; c #5E727C",
+"> c #3A4A74",
+", c #36664C",
+"' c #222E64",
+") c #46E20C",
+"! c #5A66AC",
+"~ c #3A566C",
+"{ c #828EB4",
+"] c #3A4A8C",
+"^ c #324274",
+"/ c #7A82A4",
+"( c #369E1C",
+"_ c #4A5E8C",
+": c #42D60C",
+"< c #6E769C",
+"[ c #263664",
+"} c #3ABA14",
+"| c #2E5E44",
+"1 c #32427C",
+"2 c #2A4254",
+"3 c #464E8C",
+"4 c #3ECE0C",
+"5 c #527A5C",
+"6 c #3A427C",
+"7 c #469244",
+"8 c #324A64",
+"9 c #222E74",
+"0 c #2A3A74",
+"a c #4A569C",
+"b c #46AE2C",
+"c c #42A22C",
+"d c #1A2664",
+"e c #32822C",
+"f c #3A526C",
+"g c #565EA4",
+"h c #727E9C",
+"i c #6672BC",
+"j c #52EE14",
+"k c #42528D",
+"l c #3A5E54",
+"m c #32961C",
+"n c #365664",
+"o c #465693",
+"p c #3AA622",
+"q c #4ACE23",
+"r c #3AB214",
+"s c #6A7A94",
+"t c #424A93",
+"u c #2A3678",
+"v c #4EBA34",
+"w c #365264",
+"x c #2A3A66",
+"y c #323A84",
+"z c #66728C",
+"A c #3A4E74",
+"B c #223269",
+"C c #4E5E9C",
+"D c #52D62C",
+"E c #365E54",
+"F c #364683",
+"G c #3A4683",
+"H c #324E64",
+"I c #222A6C",
+"J c #3A8634",
+"K c #3A8E34",
+"L c #2A5A44",
+"M c #46C61C",
+"N c #525A94",
+"O c #3E6E54",
+"P c #626EB4",
+"Q c #425679",
+"R c #3E9E2C",
+"S c #6E7AC0",
+"T c #2A465C",
+"U c #465290",
+"V c #2A3276",
+"W c #525AA4",
+"X c #32862C",
+"Y c #52D226",
+"Z c #26523C",
+"` c #4A5A94",
+" . c #3A6654",
+".. c #52E61C",
+"+. c #3A4674",
+"@. c #7E8AAC",
+"#. c #36A21C",
+"$. c #3EC214",
+"%. c #32624C",
+"&. c #36428C",
+"*. c #2E3E7C",
+"=. c #4A5A9C",
+"-. c #7A7EAC",
+";. c #5AF624",
+">. c #323E7E",
+",. c #4E629C",
+"'. c #3A468C",
+"). c #162254",
+"!. c #2E7E24",
+"~. c #42AA2C",
+"{. c #5E767C",
+"]. c #3A4A84",
+"^. c #626AB4",
+"/. c #3E4E8C",
+"(. c #324664",
+"_. c #767AA4",
+":. c #2A366B",
+"<. c #325E4B",
+"[. c #364282",
+"}. c #469A44",
+"|. c #364A74",
+"1. c #263274",
+"2. c #2E3A84",
+"3. c #4AB62C",
+"4. c #1E2A6C",
+"5. c #425284",
+"6. c #5662AB",
+"7. c #767EAC",
+"8. c #5AF21C",
+"9. c #4EEA14",
+"0. c #56DE24",
+"a. c #46DE0C",
+"b. c #4EC234",
+"c. c #42B624",
+"d. c #3A625C",
+"e. c #465A84",
+"f. c #263E56",
+"g. c #326A44",
+"h. c #5E6AB4",
+"i. c #7E86AC",
+"j. c #727AA3",
+"k. c #527E5C",
+"l. c #42963C",
+"m. c #52F21C",
+"n. c #369A24",
+"o. c #4ED224",
+"p. c #2E3E6C",
+"q. c #6A768C",
+"r. c #52DA24",
+"s. c #3E923C",
+"t. c #46CA1E",
+"u. c #3EAE24",
+"v. c #4AE60C",
+"w. c #3E5A6C",
+"x. c #3EBE14",
+"y. c #3ED20C",
+"z. c #6A76BC",
+"A. c #3A5A64",
+"B. c #3AB614",
+"C. c #424E8E",
+"D. c #36624C",
+"E. c #425A74",
+"F. c #367A3C",
+"G. c #42DA0C",
+"H. c #46B22C",
+"I. c #3A6A54",
+"J. c #2E564C",
+"K. c #42C61C",
+"L. c #3E527C",
+"M. c #3EA62C",
+"N. c #3E4E84",
+"O. c #46529C",
+"P. c #2A524C",
+"Q. c #1A2264",
+"R. c #364674",
+"S. c #2A4264",
+"T. c #3A428C",
+"U. c #222A74",
+"V. c #36922C",
+"W. c #2A4E4C",
+"X. c #4E5694",
+"Y. c #262E6C",
+"Z. c #3E4A8F",
+"`. c #3A9E24",
+" + c #4E5E94",
+".+ c #364A68",
+"++ c #2E3A7B",
+"@+ c #46A22C",
+"#+ c #1E266B",
+"$+ c #368232",
+"%+ c #767E9F",
+"&+ c #369624",
+"*+ c #4ECE24",
+"=+ c #2E3679",
+"-+ c #2E3A6C",
+";+ c #6A7294",
+">+ c #26326B",
+",+ c #525EA3",
+"'+ c #3E4684",
+")+ c #364E66",
+"!+ c #3E8E38",
+"~+ c #2E5A46",
+"{+ c #2E4660",
+"]+ c #368630",
+"^+ c #2A5244",
+"/+ c #56E624",
+"(+ c #828AB4",
+"_+ c #3AA224",
+":+ c #4E5AA3",
+"<+ c #363E83",
+"[+ c #1A225C",
+"}+ c #327E2C",
+"|+ c #627684",
+"1+ c #36466C",
+"2+ c #4A9A3C",
+"3+ c #4EB634",
+"4+ c #5A62AC",
+"5+ c #3E6264",
+"6+ c #567E64",
+"7+ c #4ACA1C",
+"8+ c #42AE2C",
+"9+ c #5E66AC",
+"0+ c #3E566C",
+"a+ c #868EB4",
+"b+ c #3EBA14",
+"c+ c #262E74",
+"d+ c #4E569C",
+"e+ c #3A5664",
+"f+ c #52BA34",
+"g+ c #3E4E74",
+"h+ c #56D62C",
+"i+ c #666EB4",
+"j+ c #42C214",
+"k+ c #52629C",
+"l+ c #3E468C",
+"m+ c #3E4A84",
+"n+ c #465284",
+"o+ c #366A44",
+"p+ c #56F21C",
+"q+ c #42D20C",
+"r+ c #3EB614",
+"s+ c #4A529C",
+"t+ c #2A5644",
+"u+ c #4A5694",
+"v+ c #323E74",
+"w+ c #5E7284",
+"x+ c #3A4A7C",
+"y+ c #222E6C",
+"z+ c #7A82AC",
+"A+ c #369E24",
+"B+ c #26366C",
+"C+ c #2E5E4C",
+"D+ c #324284",
+"E+ c #2A425C",
+"F+ c #464E94",
+"G+ c #42A234",
+" 1.V V V V 1.c+9 U.I 4.#+ ",
+" I ++[.[.y 2.2.u 1.c+1.c+9 9 I y+[+. . . ",
+" =+m+t '+T.[.>.2.=+c+u S %+c+U.9 4.4.4.#+Q.Q.. . ",
+" ++N d+u+F+t '.&.<+y 2.2.c+V 7.j.9 9 U.9 9 U.4.4.d Q.. . . . ",
+" N g g d+s+C.Z.'.&.D+y =+0 9 V _.7.c+9 U.4.4.4.4.U.4.4.#+#+Q.. . ",
+" X.^.9+6.:+d+O.F+t l+&.<+>.2.=+c+1.7.j.9 9 9 U.U.U.#+4.4.#+4.#+4.Q.. . . ",
+" i+P h.4+g :+a F+t l+'.&.>.y 2.u u 1.1.c+c+U.9 4.4.U.#+4.U.#+4.#+4.#+d Q.. . ",
+" 3 z.i ^.! 6.,+:+a O.Z.] T.<+y *.=+u V V c+1.9 y+U.9 U.4.4.#+#+4.#+4.#+#+#+#+Q.. . . ",
+" 6 < i i ^.! 6.W a O.F+t l+'.&.y 2.=+u 9 V S _.c+9 U.9 U.4.4.U.#+4.#+#+d #+#+#+#+Q.. . . ",
+" X.S i i h.! 6.,+:+a O.F+Z.'.&.<+>.2.2.u U.1._.j.9 I U.4.4.4.4.4.4.#+4.4.4.d 4.4.#+4.Q.. . . ",
+" 6 ;+z.i+i+h.! g W d+O.C.Z.'.T.&.>.y =+=+u U.1.j.j.9 y+U.9 4.4.U.#+4.#+d #+4.#+#+4.d #+d Q.. . . ",
+" 3 S z.i i+h.! g ,+:+a O.F+Z.l+&.<+>.2.2.u V 9 c+_.j.9 4.U.4.U.#+#+4.#+4.4.#+d #+d #+#+4.#+#+Q.. . . ",
+" i+i i+P 9+! 6.,+:+a O.F+Z.] '.&.>.2.2.=+u V 1.c+c+9 9 9 U.4.4.U.4.4.#+#+4.4.4.4.#+4.#+#+#+d d Q.. . ",
+" i i i P h.! 4+g W a O.t Z.'.T.&.<+y y u u u 1.1.1.9 U.U.4.4.U.4.U.U.4.U.4.U.4.U.4.4.4.4.4.4.#+#+4.Q.. . ",
+" m+i+^.^.9+! ,+,+:+d+s+U Z.l+'.&.>.<+>.2.u V V 1.U.c+_._.9 9 9 9 9 4.9 9 9 9 4.U.4.9 4.9 9 4.9 4.4.4.4.d Q.. ",
+" ^.^.9+! 6.,+,+:+d+O.C.m+N.l R.<+>.*.2.=+=+u V 1.4.9 j.j.U.U.4.9 U.9 9 9 9 9 9 9 c+9 c+U.I 9 I 9 I U.I 4.. . ",
+" X.! ! 6.g g W :+a s+C.Z.> d.2+E v+y 2.2.u u u c+c+U.c+j._.9 1.9 1.9 9 9 9 c+1.1.1.9 B 1.1.y+1.y+9 y+y+U.y+4.d . ",
+" <+4+6.,+W ,+:+:+a O.C.t f I.7 b.!+, T =+V u 1.1.1.1.9 1.j.7.1.9 c+9 1.1.1.1.1.c+1.1.1.1.1.c+1.c+1.>+c+9 Y.9 I I [+. ",
+" 3 W W :+d+a s+s+F+C.m+m+O v Y 8.*+H.C+x V V 1.V 1.c+c+1.c+1.1.1.V 1.1.1.V 1.B+1.1.u V 1.B+V B+1.1.1.1.1.Y.1.>+y+I d ",
+" :+d+d+a a s+O.C./.'+f O 2+Y 0./+0.*+K C+f.1.c+1.V 1.1.V 1.1.V 1.1.V V u u u V u u V u u V u V V V B+V 1.1.c+c+Y.B [+ ",
+" :.a o s+O.O.C.F+Z.] R.I.3+h+;./+D ..m.t.u.L >+1.9 1.u U.u _.7.u u u u u u u 0 u u 0 u u 0 u 0 u u u u u u B+1.1.c+V y+d ",
+" F+F+F+F+t Z.Z.'.6 )+I.l.D Y *+G+F.R 7+7+t.X L # 1.1.1.9 1.7.7.u u u u u u =+=+2.2.=+++2.=+++=+++++=+u u u u u u :.>+' . ",
+" d Z.Z.Z.Z.l+'.'.F R.I.3+Y 8.Y b g.E+g.u.M j K.p t+[ >+u 9 u 7.7.u 2.++2.2.2.2.++++*.2.++*.++*.++++++++++=+=+=+u u u V :.>+d ",
+" y l+'.'.'.'.&.<+.+ .s.o.Y o.K C+T B+E+L X K.K.K.X t+# >+Y.u z+z+2.0 u ++++++++++y ++*.>.2.*.y *.++*.++++++++0 u =+:.u V Y.. ",
+" <+T.&.&.&.[.1 ^ , 3.Y p+*+b C+:.>+1.B [ L p j+v.$.p t+[ :.u u 0 2.*.2.*.*.*.>.*.>.>.>.1 >.>.>.>.>.>.>.*.*.++++++=+=+u :.V >+ ",
+" D+<+<+<+y y (.%.s.o.o.*+K | 2 B+1.V c+>+# t+X $.$.x.e @ f.:.=+=+y y >.>.>.>.>.<+D+<+>.<+<+D+<+D+>.>.>.>.v+>.v+++*.++++=+:.V ",
+"c+>.>.2.*.++x %.H.*+m.q 8+| [ >+V 1.1.c+1.B B @ _+$.) x.#.Z x j./ *.y >.>.<+D+D+<+D+[.D+[.[.D+[.[.[.1 [.>.<+>.>.++*.++++++x 0 :.",
+"V 2.2.=+=+E+<.K q q 7+K | f.1.c+1.1.V 1.1.>+>+# t+e x.x.x.!.@ ; < ++*.>.>.D+[.[.F [.F F F [.G [.[.[.[.[.[.1 [.1 ^ >.v+*.++++=+u ",
+"V =+2.u V P.M.t.j t.~.L B >+1.c+c+1.1.1.V u u >+[ t+#.x.a.x.( k.w+v+>.&.[.&.[.[.'.&.6 F F F '.F F G F F [.[.[.<+>.>.>.v+y ++++=+",
+"u u c+I ' % M.c.K.X @ # >+y+U.4.U.4.1.1.9 9 U.y+1.f.Z !.x.} } 2+k.E+v+>.&.[.F F F '.] '.'.'.G '.G '.G G F 1 >.1 1 ^ >.>.v+v+++0 ",
+"V 1.V 1.>+W.`._+p t+B ' 9 9 1.9 c+c+1.1.1.u u u 0 0 [ t+#.x.G.} A+L ^ ^ F &.'.'.].'.'+m+].] ].] ].'.'.G G F ^ ^ v+v+1 >.>.>.++++",
+"1.V 7.< < ; t+^+k.; z ;+c+c+j.j.j.j.c+V 7.7.7.7.u u s ; 5 l.} b+} e 5 ; h i.G ] (+{ { (+Z.Z.a+a+{ { ].G %+|+6+5 J.{+-./ i.i.v+++",
+"9 c+7.j.< < B y+z ;+_.j.9 U._.j.j.7.1.V %+7.z+7.2.u z+s q.k.( b+G.} 8+k.q.%+G ] (+(+{ a+/.Z.(+(+(+(+].F s 5 @+c K t+h / i.i.[.v+",
+"9 1.c+c+c+U.9 9 9 c+U.9 U.9 9 U.c+c+c+1.V u u ++++*.*.++++2 L e } } r+e | 8 F G Z./.C./././.k C.C.m+> H ~+e r #.+ J.^ v+[.[.>.++",
+"U.9 U.9 9 U.y+U.9 9 U.9 U.4.9 9 9 1.1.u u u u 2.++2.>.*.>.v+S.k.b } : B.n.@ (.].>.*.>.>.k C.1 >.>.++1+<.m r 4 = m ~+x :.u =+[.>.",
+"4.U.9 U.9 c+U.9 4.4.4.4.y+U.U.9 1.9 1.1.u u ++u 2.>.>.<+D+1 v+{.k.e B.} } X %.8 x+Z.k U U k C.N.N.)+<.e r r r }+~+(.F F G F [.>.",
+"4.U.9 I 4.I I U.U.9 U.4.4.I I U.1.9 1.1.u u ++++++y 1 >.[.[.[.h q.| n.} : B.( <.> m+k k o o U m+.+%.n.r 4 r n.~+(.F G G G F F ^ ",
+"d y+4.4.U.9 4.I I 4.4.4.U.4.9 9 9 1.V u u =+++++>.>.>.[.D+G F / h 8 @ $+B.b+b+]+%.H N.k U C.L.w D.e r+B.r e | )+x+G m+x+G G 6 <+",
+" U.U.4.4.U.4.4.U.U.#+4.4.4.y+c+c+1.1.V u u 2.2.*.>.D+[.[.&.'.].G R.(.<.( B.y.B.`.%.> N.o N.A %.`.r 4 B.n.<..+x+C.m+Z.].G F G ",
+" 4.4.U.4.4.4.4.#+4.U.4.4.U.4.9 9 c+V u u ++++++>.>.<+&.[.G G '.] ].].H <.X b+r+} $+%.n L.e+D.$+r B.B.e <.w m+m+C./.N.m+m+G F ",
+" . 4.#+4.U.4.4.4.4.#+#+#+U.I c+1.1.1.u u 0 2.2.>.>.D+F F F ] (+(+Z.v+].> <.( r+q+b+`.g.f g.A+B.4 r n.D.> L.o k k C./.N.m+G v+ ",
+" [+#+U.#+4.4.4.#+#+4.4.4.4.9 9 9 1.u u u =+++>.*.D+<+&.T.'.G { { /.*.N.].)+%.$+} B.B.V.$ V.r+B.B.J , e+5.U U U k k C.Z.Z.+.' ",
+" ).4.#+#+#+4.4.#+#+4.4.4.y+9 9 c+1.u 2.++++>.>.D+D+F G ] '.(+(+t >.k k N.A D.`.B.q+& x.$.4 r+A+D.L.n+o o o o k k C.N.].'+ ",
+" d #+4.4.4.#+#+4.4.#+#+U.4.c+1.1.1.u u 0 ++2.>.<+[.[.F G Z.a+a+/.<+k k 5.k w D.]+B.x.& x.r+$+D.0+o ` ` ` ` U U C.k N.N.>+ ",
+" Q.#+#+4.4.#+#+d 4.#+I U.9 1.1.V u =+++>.>.1 >.D+[.F G ] Z././.C.k o k o k N.D.A+r+y.r+`. .Q o ` N ` o ` o o k C.C.C. ",
+" #+4.4.#+#+4.4.4.#+4.4.y+Y.9 1.u V u ++++++>.[.[.G '.] G /./.C.k U U o o Q * 0+ .}+p }+I.w.` + +C =.` o o k k 5.N.6 ",
+" . Q.#+#+#+#+#+#+d 4.4.4.c+1.1.B+u u ++*.2.>.D+D+[.[.] G (+{ C.>.k O.O.o o ` 5.Q l J d.e._ k+k+,. +C N ` o U U C.N.'+ ",
+" d 4.4.d #+d 4.4.#+U.y+9 9 1.1.u u u y >.>.<+[.F G G ] a+a+/.D+k o o a ` =.` o Q 5+E._ +k+,.,+C ` ` o o o k k > ",
+" . #+#+#+#+#+4.#+I y+c+9 1.1.u ++0 ++++>.>.[.[.F G ] (+a+C.>.C.U o o o ` N _ ` ` +k+k+k+,.,.C _ ` ` o U n+C. ",
+" d 4.4.4.#+d #+4.4.4.y+Y.1.V u u =+++>.*.[.[.F 6 ] G a+(+/.[.k o o o ` =.=.=.=._ C k+,.k+k+,+ +:+` * U o 5.:. ",
+" . #+d #+d d #+I U.9 c+1.1.V u u ++>.*.>.>.F &.'.'.Z.m+Z.C.C.k o o o ` N _ :+C C k+k+C +C ` N ` o k U C. ",
+" #+d #+#+#+#+4.4.y+y+1.1.B+u ++++++y >.[.D+F G G ].Z././.k k U U o =.=.:+_ C C C C +C ` ` ` o o o 5. ",
+" . Q.d #+d #+4.4.y+y+c+V u u u ++*.*.>.<+[.[.F G { { N.*.C.k k U U o o ` ` _ C =.:+` _ =.u+u+o U C.+. ",
+" ).#+d #+d #+I I 9 1.>+1.1.u u ++y *.>.1 F F F (+(+Z.>.C./.k o o o o a a u+` ` ` ` u+` ` o o 5.:. ",
+" . ).#+#+#+4.I I 9 1.:.u =+=+++y v+>.>.[.G [.(+(+m+*.C.C.C.k k o o o ` o ` ` ` ` o o o U 5.+. ",
+" . d d d 4.I y+Y.c+1.>+u :.++*.*.>.1 [.[.F (+(+].++Z././.C.k U U o U o o o o o o U U 5.:. ",
+" . [+#+4.4.4.y+Y.1.1.u u u ++y y >.1 [.[.F G m+].m+/./.C.C.k k k U U U U U U o Q k '+ ",
+" Q.#+I y+y+9 c+>+u :.=+=+++v+*.>.[.[.[.[.F ].] m+m+/.N./.C.k k k k k k k k C. ",
+" ).#+I y+Y.1.Y.1.u :.0 ++y v+>.>.[.i.i.6 ++].].m+/.N.C.C.C.C.k k k k N.'+ ",
+" 4.I y+Y.1.V B+u u 0 ++y *.1 1 i.(+F ++G ].'.m+m+m+N.N.N.C.C.C.m+ ",
+" d 4.y+B c+V u :.0 0 ++++>.[.z+i.[.u 6 G G G ].Z.m+m+m+m+m+> ",
+" I >+>+V V =+:.++++++*.i.i.[.++F G F G G G ].].^ ",
+" I ' >+=+=+-+++++v+y v+>.>.1 [.F G F >.[. ",
+" V :.=+:.++*.++>.v+<+^ [. "};
diff --git a/arts/builder/pics/Synth_WAVE_SIN.xpm b/arts/builder/pics/Synth_WAVE_SIN.xpm
new file mode 100644
index 00000000..66500375
--- /dev/null
+++ b/arts/builder/pics/Synth_WAVE_SIN.xpm
@@ -0,0 +1,320 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 249 2",
+/* colors */
+" c #6B798A",
+" . c #445292",
+" X c #323E7D",
+" o c #303C7B",
+" O c #3E4C8C",
+" + c #2E3A79",
+" @ c #60C225",
+" # c #2C3877",
+" $ c #2A3675",
+" % c #283473",
+" & c #384486",
+" * c #5B637A",
+" = c #364484",
+" - c #263071",
+" ; c #354283",
+" : c #404B70",
+" > c #334081",
+" , c #838CB5",
+" < c #303C7E",
+" 1 c #4FAD1E",
+" 2 c #818AB3",
+" 3 c #6EE32F",
+" 4 c #72DB33",
+" 5 c #1E2869",
+" 6 c #1C2667",
+" 7 c #66B02E",
+" 8 c #689044",
+" 9 c #374288",
+" 0 c #253073",
+" q c #232E71",
+" w c #343E85",
+" e c #222C70",
+" r c #4FBA17",
+" t c #202A6E",
+" y c #1F2A6D",
+" u c #1E286C",
+" i c #1D286B",
+" p c #2E387F",
+" a c #1A235E",
+" s c #384582",
+" d c #5E8347",
+" f c #435190",
+" g c #333F7D",
+" h c #2F3B79",
+" j c #3E4B8B",
+" k c #606BB3",
+" l c #2E3978",
+" z c #58744B",
+" x c #4E599E",
+" c c #3B4988",
+" v c #2B3775",
+" b c #5C67AF",
+" n c #394786",
+" m c #527245",
+" M c #3A487D",
+" N c #273171",
+" B c #333F80",
+" V c #323F7F",
+" C c #485384",
+" Z c #2F3B7C",
+" A c #2D397A",
+" S c #404C86",
+" D c #2A3577",
+" F c #7A81AB",
+" G c #495892",
+" H c #38447E",
+" J c #202B6D",
+" K c #313B81",
+" L c #1E296B",
+" P c #1D276A",
+" I c #1C2769",
+" U c #2C377C",
+" Y c #293379",
+" T c #283378",
+" R c #4A5A96",
+" E c #263176",
+" W c #242F74",
+" Q c #475693",
+" ! c #232D73",
+" ~ c #455491",
+" ^ c #394378",
+" / c #212B71",
+" ( c #202B70",
+" ) c #42508E",
+" _ c #323C7B",
+" ` c #404E8C",
+" ' c #58D01B",
+" ] c #3A4686",
+" [ c #53C616",
+" { c #364282",
+" } c #25306E",
+" | c #344080",
+". c #242E6D",
+".. c #222C6B",
+".X c #313E7D",
+".o c #424E91",
+".O c #303C7C",
+".+ c #202A69",
+".@ c #2C3878",
+".# c #1B2464",
+".$ c #5BBA21",
+".% c #354284",
+".& c #253071",
+".* c #242E70",
+".= c #334082",
+".- c #232E6F",
+".; c #232C6F",
+".: c #343F79",
+".> c #202A6C",
+"., c #1F2A6B",
+".< c #2C387B",
+".1 c #1C2668",
+".2 c #798881",
+".3 c #688459",
+".4 c #293478",
+".5 c #283477",
+".6 c #2C3571",
+".7 c #283277",
+".8 c #757CA8",
+".9 c #222C71",
+".0 c #212C70",
+".q c #202A6F",
+".w c #1E286D",
+".e c #505B9E",
+".r c #6FD334",
+".t c #475595",
+".y c #364381",
+".u c #509F26",
+".i c #2D3978",
+".p c #3A4788",
+".a c #273372",
+".s c None",
+".d c #344182",
+".f c #48548F",
+".g c #222D6D",
+".h c #2E3B7C",
+".j c #2D397B",
+".k c #3E498F",
+".l c #1D2768",
+".z c #2B3779",
+".x c #4B5374",
+".c c #2F3569",
+".v c #263174",
+".b c #486253",
+".n c #242F72",
+".m c #475691",
+".M c #313D82",
+".N c #43528D",
+".B c #1F296D",
+".V c #42508C",
+".C c #1E296C",
+".Z c #1D276B",
+".A c #404E8A",
+".S c #2C377D",
+".D c #4B5698",
+".F c #495896",
+".G c #6872BB",
+".H c #525C77",
+".J c #41508E",
+".K c #535EA3",
+".L c #303C7A",
+".P c #1D2664",
+".I c #3B4888",
+".U c #2A3474",
+".Y c #48546D",
+".T c #394686",
+".R c #5964AC",
+".E c #526B45",
+".W c #364083",
+".Q c #323E7F",
+".! c #747AA2",
+".~ c #838CB4",
+".^ c #2F3C7C",
+"./ c #2E3A7B",
+".( c #2B3678",
+".) c #3B468B",
+"._ c #283475",
+".` c #263273",
+".' c #47529A",
+".] c #4A6A4A",
+".[ c #242E71",
+".{ c #58B21F",
+".} c #171F57",
+".| c #7F8E88",
+"X c #212C6E",
+"X. c #2E3A7E",
+"XX c #1E286B",
+"Xo c #1C2669",
+"XO c #2B367B",
+"X+ c #2A347A",
+"X@ c #273277",
+"X# c #525B8A",
+"X$ c #253075",
+"X% c #242E74",
+"X& c #232E73",
+"X* c #222C72",
+"X= c #5761A6",
+"X- c #212C71",
+"X; c #445390",
+"X: c #51B41B",
+"X> c #1F2A6F",
+"X, c #434F8F",
+"X< c #313D7A",
+"X1 c #3E4D8A",
+"X2 c #529030",
+"X3 c #2B3574",
+"X4 c #384584",
+"X5 c #55BF18",
+"X6 c #364382",
+"X7 c #344180",
+"X8 c #3B4469",
+"X9 c #8089B0",
+"X0 c #547153",
+"Xq c #6C9946",
+"Xw c #283374",
+"Xe c #374586",
+"Xr c #364385",
+"Xt c #263172",
+"Xy c #464D6D",
+"Xu c #4A5988",
+"Xi c #303D7F",
+"Xp c #2F3B7E",
+"Xa c #1E296A",
+"Xs c #4F5579",
+"Xd c #2D397C",
+"Xf c #1D2769",
+"Xg c #587946",
+"Xh c #2B377A",
+"Xj c #2A3579",
+"Xk c #3D4A85",
+"Xl c #32396D",
+"Xz c #283377",
+"Xx c #273376",
+"Xc c #273176",
+"Xv c #677197",
+"Xb c #263175",
+"Xn c #252F74",
+"Xm c #7D819C",
+"XM c #465491",
+"XN c #222D71",
+"XB c #222B71",
+"XV c #212B70",
+"XC c #1F296E",
+"XZ c #1E296D",
+"XA c #3E4C89",
+"XS c #373E6B",
+"XD c #43527A",
+"XF c #3B4886",
+"XG c #2B3673",
+/* pixels */
+".s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.sXt.7Xz Y.7 E WX%XB t L.l.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.sXG _ 9 w.M K.SXO YX@X$ W !X*X- (.q.B.# a.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.sXF.o.o.k 9 w.M K.S.[ Y.8.8 W !X*X- (.qX>XCXCXX a.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s H x x.' ..k.) 9 w.M K.S.[ Y.8.8X% !X*X- (.qX>XCXZ.w.w uXo a.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.sX=.R.K x.'.o.k.) 9 w.M p.S.[ Y.8.8X% !X* / (.qXCXCXZ.w u u u.Z.1.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.s.s.s.s.D k bX=.K x.'.o.k.) 9 w.M p.S.[ Y.8.8X% !X* / (.qXCXCXZ.w u u i.Z.ZXo a.s.s.s.s.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.s.s.s.G.G k.RX= x x.'.o.k.) 9 w K p.SX+ Y EX$X% !.9XV.q.qXCXCXZ.w u u.Z.Z.Z P P 6.s.s.s.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.s.V.G.G k b.R.K x.'.'.o.k.) 9 w K pXOX+.7 EX$X&X*X-XV.qX>XC.B.w u u u.Z.Z P P P P.1.}.s.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s G.G.G.G k.RX=.K x.'.o.k.) 9 w.M K pXO.-X@.8.8X&X*X-XV.qXCXCXZ.w u u i.Z.Z P P PXfXo 6.}.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s R.G.G.G k b.R.K x.D.'.o.k.) 9 w.M p.SXO.-X@.8.8 !X* / (.qXCXCXZ.w u u i.Z.Z P P PXfXoXo 6.}.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s G.G.G.G k k.RX=.K x.' ..o.k.) 9 w K p UX+.; E.8.8 !.9XV.q.qXC.BXZ u u i.Z.Z P P PXf IXoXo.1 6.}.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.V.G.G.G k k.RX=.K x.D.'.o.k.) 9 w.MX. pXOX+ e E.8.8X*X-XV.qXCXC.B.w u u uXX.Z.Z P P PXfXfXo.1.1 6.}.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.G.G.G k k bX=.K x.D.fX,.AXFX4.W w K p.SXO YX@X$ W !X*X- (.qXCXC.BXZXZ u.C.C.CXXXXXXXXXX PXfXf.1.1 6.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.G.G.G k k.RX=.K.eX#X#X#X# C C M H.M p pXOX+.7 EX$X% !.9XV (.q.q t t t t t t t J J J.> y.B.,XXXXXXXf.l.#.s.s.s.s.s.s",
+".s.s.s.s.s.D.G k k b.RX=.K.e .2.3.3.3.3.3X0.Y.: l UXO YX@ J W.8.!.9.0.0.0.0.0.0.0.0.0.0 e e.0X X X J J.>.>.,XaXa 5 a.s.s.s.s.s",
+".s.s.s.s.s k k b.R.RX=.KXv .2.r 4 4 4 4.r.r zX8XlXO Y.7 E JX%.8.! !XNXNXN q q q q q q q q q.-.-.-.-.-.gX X J J.,., 5.s.s.s.s.s",
+".s.s.s.sX= b.R.RX=.K.eX# .2Xq 4 4 4 4 4.r.rXq zXyXl.6Xc E.>X%.8.8X%.n.n.n.n.n.n 0 0 0 0 0.&.&.n.[.[.[.*.-.-.g.gX J., 5.s.s.s.s",
+".s.s.s H.RX=X=.K.e xX# *.3 4 4 4 4 4.r 3 3 3.r @ mX8Xl.vXn JXn.8.8 0 0 0 0.v.v.v.v.v.v.v.v.v.v.`XtXtXt.&.&.&.*.-.-.g.g...P.s.s.s",
+".s.s.s x.K.K x x.DX# *.3Xq 4Xq.3.3X0 z d d d 7 @X2.EX8.c NX$XbXbXbXbXbX@X@X@XxXxXxXxXxXxXx.5._._._Xw.v.v.`XtXt.&.&.-.-.g.+.s.s.s",
+".s.s.s x x x.'.'.f *.3.r 4 4.3.x.x M ^ ^ :X8X2 ' ' @.EXS.c.vXcX@X@X@XzXz.5.4.4 D.4.4 D D D D D D D D.5._._Xw.a.aXt -.&.-.-.s.s.s",
+".s.sXF.'.'.' .X,.H.3Xq 4 4.r.3Xy ^ X _ hXlX8 m @ ' 'X2.EX8. Xw.8.8.4.4 D DXjXj.z.z.z.z.z.z.z.z.z.z.z.( D D._._._ %.a N N }.P.s.s",
+".s.s.o ..o.o.k SX0.r 4 3 4.rX0 ^ _ K p p vXl.].{ ' ' '.{.].c.U.8.8XjXjXhXhXh.<.<.<.j.j.j.j.j A A A.@.@.@.z #.( D._.U %.aXt }.s.s",
+".sXG.o.k.k.k.I SX0.r 3 3 7.3.Y gXp p p U D.6X8.]X2 ' [.$.E.cXl.8 FXh.<.<.jXdXd./././.h Z Z Z Z Z./././ A.i.@.@ # $ $.U %.a N.+.s",
+".s _.k.).).) ]XD.3 4 3 3 8.Y ^X. p.SXOX+.7Xx.cXS.].{.$ ' mX8Xl.8 F UXdXdX..hXpXp < < <XiXiXi.O.O.O.O.^ Z Z./ +.i.@ # $ $.U %.+.s",
+".s 9 9 9 9 9 H.x.3 3.r.r zX8 l.S UXOX+ Y.7X@.6.cX8.EX2 @X2.E.bXl lXd.hXpXp <XiXi.Q.Q.Q.Q V.Q.Q.Q.Q.X.X.X.O.O Z h +.i # v $.U.a.s",
+".s w w w w w ^.H 8 3.r 7.bXl.(XOXO.4 TX@.7 T.7.4XlX8.E.$.$.{.EX8Xl ZXpXiXi.Q.Q V B > > > > | > > | | V V.Q.X.O.O Z./ +.i # $.U.s",
+"Xt.M.M.M < g.Y.3 7 3 7 zX8 v DX+ Y.7X@X@X@ T.4.4X3Xl.b mX2X5X2.3.2X<.O.Q B B.=.d.d ; ; ; ; ; ; ; ;.yX7X7 | V V X.O o h +.i # v %",
+".7 K K K l.:X0 @ @ ' dXyXl.4.7.7X@ EXcX@X@ T.4XjXj.zXSX8 m [X5 7.3 ^X<.=.=.d ;.%XrXrXr = = = = =X6X6X6 ;.yX7 | | V.XX<.L h l #XG",
+"Xz.S.S.S #XS.E @ ' 'XgX8.6X@X@ E EX$ EX@Xz.4.4X+XOXhXlX8 mX5X5 @.3X8.:.= ;.%XrXrXr & & & &.T &X4X4X4X4 =X6X6.y | g.:X< o.L h l v",
+" YXO.[.[. .c m ' ' '.E.c N E J J.> J EX@.g.-.-.& U U }.c.] 1X5 'XqXy ^ {.%XrXe &.T.T n.p.p.p.p n n n.TX4X4 sX6.y ^ ^ ^ gX<.L h #",
+".7 Y Y Y.UXS.E @.$.$.].c }X$ WX%X%XnXbX@Xz.4XjXh.<Xd lX<X8.EX2 [X2.E.Y M s &.T.p.I.I.I c c c c c c.IXF.p nX4 H :.Y.bXy ^X<.X.L l",
+" EX@.8.8.!Xm.E.{ 7 7.3Xv. X%.8.8.8.8XbX@.8.8 F FXdX. F FXm.2 m [.$.{.3Xm F 2.I c.~.~.~ , j j.~.~.~.~ c cX9X9Xm.|.]X2.2Xm F FX< h",
+" WX$.8.8.!.!X8.E.3.3 .! e !.!.!.8.8XbX@.8.8 F FXdX. F F.!Xm.EX:X:.$.3XmXm 2 c j , , , , O ` , , , ,X1 jX9X9.2.3X2.u.3XmXmX9 g.L",
+"X% W WX% !.[ N.c.c.c. e /.9.9 !X% 0XbX@.4XjXh UX.XpXi.Q.: ^.] 1X: [Xg.YXD c j O O ` ` ` ` ` ` ` ` ` `X1XkXD.] 1 1 r m : ^X7 gX<",
+"XB ! ! ! !X*.-. . ..X (X-XV.0XN.n 0XbXz.4Xj.<Xd.hXiXi B g ^Xy.3XqX5X2.E.bXSXk O X g g g ) ) g g g g.JX1XlX8.E 1 1 1.]XS.6 vX7 X",
+" tX*X*X*X*X*.9X-X- /XVXV ( (.0XN.n 0X@Xz DXh.<XdXpXi.Q.=.= { ^Xm.3.{.{.{ m.xXD `.J f f f f f f f f f.J `XD.Y m r 1.u.] ^ H.yX7 g",
+" LX-X-X- / /XVXVXV (.q.q.q.q.0XN.n 0X@.5 DXh.jX.XpXi B.= ;.% HXm.2 mX2X5X2.E.Y.A ` f . . ~ ~ ~ ~X;X;.V S.Y.EX2X5X2.EXy M H s.y g",
+".l ( ( ( ( (.q.q.q.q.qXCXC.q.0 q.n.vX@.4XjXhXd.h <.Q B.d.%Xr &X9Xm.Y m [X: 1X0 C.V . ~ Q Q.t.t Q QXM.V C.].u 1X5Xg.Y :XF s s.y g",
+".s.q.q.q.q.q.qX>XCXCXCXCXC t.0 q.n.vXx.4Xj.<XdXpXi.Q.= ;XrXe.T.p M.xXgX5X:X: zXs C ~.t.t.t.F.F.F Q Q CXs m 1X: r m.x MXFXF s s.s",
+".s.BX>X>XCXCXCXCXCXC.B.B.B t.0 q.n.vXx D.z.<./XpXi V.d.%Xr &.p cXkXD z.{.{X5Xg.H C Q Q.F.F.F.F.F.F Q C.x m r r r mXDXkXkXF ] s.s",
+".s.#XCXCXCXCXC.BXZXZXZ.wXZ t.0 q 0.vXx.4.z.<./ <.Q B.dXrXr.T.I.~X9 SX8 zX2.$X2 z.HXu.f.F R R R R G G.Y mX2 [ r 1.]XDXkXAXkXF.:.s",
+".s aXCXZXZXZXZ.w.w.w u uXZ t.0 q 0.vXx.4.z.j./ <.Q > ;Xr &.T.I.~.~ jXS.x z.{.{.{ z.HXu R R R R R GXuX0.u r [ r.u.bXDXkXAXkXF.:.s",
+".s.sXX.w.w.w.w u u u u u u t.0 q 0.vXx D.z.j.h <.Q > ;Xr & n.I.~ , O.: C.Y zX2.$X2 z.HX# G x.e.eX#X# z 1X: rX2.].Y S SX1XkXF.s.s",
+".s.s a.w u u u u u u i u.C t.0 q 0.vXx D.z.j ZXi.Q > ; = &.p c , , ` g ) C.H dX5.$.{ z.HX#.e.e.eX#.HXgX5.{.{ z.xXD.V.AX1XA ^.s.s",
+".s.s.s u u u u u i i.ZXX.C t e q 0.vXx D.z.j ZXi V > ; = &.p c j O ` ) f CXs zX: rX5X2 z *X#X#X# * zX2X5X2 z.Y C.V.V.V.AXA.s.s.s",
+".s.s.sXo u i.Z.Z.Z.Z.Z.Z.C J e q.&.v.5 D.z.j ZXi.Q | ; =.T.p c j ` ` ) f.N CX0.u r [X5.{ d * * * d.{.{X5 d.HXu.mX;.N.V.AXk.s.s.s",
+".s.s.s a.Z.Z.Z.Z.Z.Z P.ZXX J.0.-.&.v._ D.z A Z.O.Q > ; = &.p c.~ , ` g f.N.f.Y.]X2 r r.$X2 d d dX2.{.{ 1 z.HXuXM ~.N.V.A M.s.s.s",
+".s.s.s.s.1.Z.Z P P P P PXX JX .-.n.`._ D.z A Z.O.Q > ; =X4 n c.~ , ` g f . ~ C.x.].u 1X5X5X5X5X5X5X5 1.uX0Xu.f.m ~.N.V S.s.s.s.s",
+".s.s.s.s.sXo P P P P P PXX.>X .-.[Xt._ D.z A./.O.Q | ;X6X4 n c.~ , ` g fX; ~.N C.YX0 zXgX2X: 1 1X2Xg zX0.HXu.f.mX;.N.A.s.s.s.s.s",
+".s.s.s.s.s a P P P PXf PXX yX .-.[XtXw D.z.@./.O.X |.yX6X4 n.I.~ , ` g fX;XM Q Q GXuX#.H z.u.u.u z *X#X# G G.mXMX;.N M.s.s.s.s.s",
+".s.s.s.s.s.s 6 PXfXf IXfXX.B J.-.[Xt.v.5.(.@./.^.X VX7X6X4.TXF cX1 `.J fX; ~ Q Q.m.mXuXu.H.b.b.b.HX#Xu G G Q.mXM.N.A.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.1XoXoXoXf P., J.g.*.&.v._ D.@ A Z.X VX7 ; =X4.p c jX1 `.J fX;XM Q.F R R R GXuXuXu G R R R R G.mX;.V.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.} 6XoXoXoXfXX.>X .-.&.`._ D.z.i Z.O.Q |.yX6X4 n 2.~X1X<.J ) f ~XM Q G R R G G G G G R R R Q.m ~.V M.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.} 6.1.1XfXX.>X .-.&XtXw._ #.@./.O.X VX7X6 s.T 2.~XAX< `.J fX; ~XM Q Q.F R R R R R R G G.mXM.N ^.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.} 6.1.1XX., J.g.*Xt.a._.(.@ + Z.O V |.y =X4X9 2 cX<X1 `.V.NX; ~XM.m Q Q G G G G Q.m.m ~.N ^.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.} 6.1XfXa J.g.-.&.a._ D #.i h.O X |X7X6 sX9 2 c.LXAX1 `.V.NX;X; ~XM.m.m.m.m.mXMXMX;.V ^.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.s.} 6.lXa.,X .-.&Xt %._ $.@ + Z.O V |X7X6 s.TXF cXAXAX1 `.V.V.NX;X; ~ ~ ~ ~X;X;.N.V M.s.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.s.s.s.# 5., J.g.- -.a.U $ #.i./ o.X gX7.y s s nXF cXAXAX1 ` `.V.V.N.N.N.N.N.N.N.A.s.s.s.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.s.s.s.s a 5.,.g.-.& N %.U $ # + hX< X gX7X9X9 s lXF c cXAX1X1 ` ` `.V.V.V.V.A M.s.s.s.s.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s 5...g.- N.a % $ v.i +.L.O g gX9X9 s # nXFXFXkXkXAXAX1X1.A.A.A S.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.P.+.- }Xt.a.U $ #.i h.LX< g FX9.y v s s ]XFXFXkXkXkXAXAXk M.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.P } N %.U $ # l h.L.X FX9X7 v.y s s s ]XFXFXF ^.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.+.+.a.U v # l h.LX< g gX7X7.y.y s s.:.:.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s",
+".s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s %XG v # l h.LX< X g g g.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s"
+};
diff --git a/arts/builder/pics/Synth_WAVE_SQUARE.xpm b/arts/builder/pics/Synth_WAVE_SQUARE.xpm
new file mode 100644
index 00000000..4f5a1671
--- /dev/null
+++ b/arts/builder/pics/Synth_WAVE_SQUARE.xpm
@@ -0,0 +1,323 @@
+/* XPM */
+static char * WAVE_SQUARE_xpm[] = {
+"64 64 256 2",
+" c None",
+". c #161E54",
+"+ c #429224",
+"@ c #465A84",
+"# c #56CA0C",
+"$ c #2E3E64",
+"% c #66E614",
+"& c #3A4E74",
+"* c #3E821C",
+"= c #96E64C",
+"- c #222E64",
+"; c #7AD63C",
+"> c #4EAE1C",
+", c #5A6A9C",
+"' c #324674",
+") c #5EDA0C",
+"! c #565EA4",
+"~ c #464E8C",
+"{ c #263664",
+"] c #52BE0C",
+"^ c #6ACE2C",
+"/ c #6EF614",
+"( c #6A7694",
+"_ c #52629C",
+": c #92FE2C",
+"< c #4E5A8C",
+"[ c #7E86AC",
+"} c #2E3E7C",
+"| c #3E4684",
+"1 c #82FE24",
+"2 c #1A265C",
+"3 c #5EBE24",
+"4 c #4AA21C",
+"5 c #5AD20C",
+"6 c #AAFE44",
+"7 c #425684",
+"8 c #222E74",
+"9 c #465684",
+"0 c #2E3674",
+"a c #767AA4",
+"b c #3E4E8C",
+"c c #82DE44",
+"d c #7AFE1C",
+"e c #52BA0C",
+"f c #364684",
+"g c #56C60C",
+"h c #4E5A9C",
+"i c #363E84",
+"j c #1E266C",
+"k c #62CA24",
+"l c #6A7294",
+"m c #56BE1C",
+"n c #6AD62C",
+"o c #72FE14",
+"p c #469A14",
+"q c #4A5A94",
+"r c #56669C",
+"s c #9EFE3C",
+"t c #42527C",
+"u c #22325C",
+"v c #5E6AB4",
+"w c #6A76BC",
+"x c #222A64",
+"y c #465694",
+"z c #2E367C",
+"A c #52B61C",
+"B c #4A5E84",
+"C c #5ECA1C",
+"D c #2E3E6C",
+"E c #6AEE14",
+"F c #A2E65C",
+"G c #96D26C",
+"H c #3A467C",
+"I c #62E20C",
+"J c #46528C",
+"K c #2A3674",
+"L c #3E4A84",
+"M c #1E2A5C",
+"N c #4EAA1C",
+"O c #B6FE4C",
+"P c #2A3274",
+"Q c #7A82AC",
+"R c #8EE24C",
+"S c #4E5E9C",
+"T c #36427C",
+"U c #56C21C",
+"V c #569E34",
+"W c #5AB624",
+"X c #3E527C",
+"Y c #82DA41",
+"Z c #72D234",
+"` c #6EFA14",
+" . c #9AFE38",
+".. c #4E5E94",
+"+. c #828EB4",
+"@. c #324283",
+"#. c #42528F",
+"$. c #3A4A88",
+"%. c #469E1C",
+"&. c #4E569A",
+"*. c #36428C",
+"=. c #162254",
+"-. c #4A5A8B",
+";. c #9EE65C",
+">. c #4EB21C",
+",. c #5662AA",
+"'. c #2A3A6C",
+"). c #6AD22C",
+"!. c #727E9C",
+"~. c #8AFE2C",
+"{. c #1E2663",
+"]. c #5EC61C",
+"^. c #4AA61C",
+"/. c #66D224",
+"(. c #263274",
+"_. c #767E9C",
+":. c #1E2A6C",
+"<. c #62CE24",
+"[. c #72D634",
+"}. c #76FE1A",
+"|. c #5E66AC",
+"1. c #26326C",
+"2. c #626EB3",
+"3. c #2E3A7D",
+"4. c #52BA1C",
+"5. c #324274",
+"6. c #46529C",
+"7. c #3E4A94",
+"8. c #5ACE0C",
+"9. c #666EB4",
+"0. c #727AA4",
+"a. c #626EA4",
+"b. c #6676AC",
+"c. c #32425C",
+"d. c #5E6EA4",
+"e. c #7E8AAC",
+"f. c #6E7AC0",
+"g. c #A6EA64",
+"h. c #66EA14",
+"i. c #7ADA3C",
+"j. c #62DE0C",
+"k. c #52C20C",
+"l. c #5ED60C",
+"m. c #6AF214",
+"n. c #B2FE4C",
+"o. c #A6FE44",
+"p. c #96E254",
+"q. c #3E8624",
+"r. c #2E3A72",
+"s. c #5ECE24",
+"t. c #3A4A7A",
+"u. c #6672BC",
+"v. c #8ADE44",
+"w. c #5EC224",
+"x. c #5ABA24",
+"y. c #3E4E84",
+"z. c #9AE65C",
+"A. c #5AC61C",
+"B. c #4A9A24",
+"C. c #5A66AC",
+"D. c #1A2264",
+"E. c #767EAC",
+"F. c #3E4E7C",
+"G. c #9AE654",
+"H. c #262E6C",
+"I. c #364677",
+"J. c #2A366C",
+"K. c #72F614",
+"L. c #96FE34",
+"M. c #525A94",
+"N. c #323E7E",
+"O. c #AEFE4C",
+"P. c #424E8E",
+"Q. c #7EFE20",
+"R. c #3A4685",
+"S. c #525AA4",
+"T. c #5ABE22",
+"U. c #263264",
+"V. c #4A5696",
+"W. c #323E74",
+"X. c #66E214",
+"Y. c #BAFE54",
+"Z. c #525EA3",
+"`. c #3A427C",
+" + c #5AC21D",
+".+ c #1A225C",
+"++ c #5A62AC",
+"@+ c #6ED22E",
+"#+ c #62C624",
+"$+ c #222A6E",
+"%+ c #66CE25",
+"&+ c #323A84",
+"*+ c #828AB4",
+"=+ c #469224",
+"-+ c #5ACA0C",
+";+ c #52AE1C",
+">+ c #62DA0C",
+",+ c #86FE24",
+"'+ c #4EA21C",
+")+ c #5ED20C",
+"!+ c #262E74",
+"~+ c #86DE44",
+"{+ c #6ED62C",
+"]+ c #5A669C",
+"^+ c #A2FE3C",
+"/+ c #626AB4",
+"(+ c #56B61C",
+"_+ c #52AA1C",
+":+ c #7E82AC",
+"<+ c #92E24C",
+"[+ c #72FA14",
+"}+ c #525E94",
+"|+ c #868EB4",
+"1+ c #4A9E1C",
+"2+ c #3A428C",
+"3+ c #52B21C",
+"4+ c #8EFE2C",
+"5+ c #4EA61C",
+"6+ c #76D634",
+"7+ c #56BA1C",
+"8+ c #4A529C",
+"9+ c #424A94",
+"0+ c #6AEA14",
+"a+ c #7EDA3C",
+"b+ c #56C20C",
+"c+ c #6EF214",
+"d+ c #7A7EAC",
+"e+ c #465A8C",
+"f+ c #3E8224",
+"g+ c #222E6C",
+"h+ c #464E94",
+"i+ c #26366C",
+"j+ c #6EF61C",
+"k+ c #92FE34",
+"l+ c #4E5A94",
+"m+ c #3E468C",
+"n+ c #1A2664",
+"o+ c #46568C",
+"p+ c #4E5AA4",
+"q+ c #72FE1C",
+"r+ c #469A1C",
+"s+ c #4A5A9C",
+"t+ c #425284",
+"u+ c #223264",
+"v+ c #4A5E8C",
+"w+ c #5ECA24",
+"x+ c #2E3E74",
+"y+ c #62E214",
+"z+ c #465294",
+"A+ c #2A367C",
+"B+ c #3E4A8C",
+"C+ c #1E2A64",
+"D+ c #B6FE54",
+"E+ c #2A327C",
+"F+ c #364284",
+"G+ c #3E5284",
+" (.P P E+E+(.!+8 $+$+:.{. ",
+" x r.F+F+&+3.3.A+(.!+(.!+8 8 $+8 D.. . . ",
+" 0 L 9+m+2+F+N.3.z !+A+0.E.!+$+8 :.:.:.j D.D.. . ",
+" r.h &.V.h+9+R.*.i &+3.3.!+(.E.0.8 8 $+8 8 $+:.:.n+D.. . . . ",
+" M.! ! &.8+P.7.m+*.@.&+z 3.!+E+a E.!+8 $+:.:.:.:.$+:.:.j j D.. . ",
+" &./+|.++S.&.6.h+7.m+*.i i 3.A+8 (.E.0.8 8 8 $+$+$+j :.:.j :.j :.D.. . . ",
+" a.2.v ,.Z.p+V.h+9+m+m+@.i &+3.A+A+(.(.!+!+$+8 :.:.$+j :.:.j :.j :.j n+D.. . ",
+" ~ w u./+C.++Z.p+V.6.7.7.*.i &+} z z E+E+!+(.8 8 $+8 $+:.:.j j :.j :.j j j j D.. . . ",
+" `.w u.u./+C.,.S.V.6.h+7.m+m+*.&+&+A+A+8 (.0.0.!+8 $+8 $+:.:.:.j :.j j n+j j n+j D.. . . ",
+" &.a u.u./+C.,.Z.p+V.6.h+7.f *.i } &+3.A+$+E+a 0.8 $+$+:.:.$+:.:.:.j :.:.:.j :.:.j :.D.. . . ",
+" `.u.w 9.2.v C.! S.&.6.h+7.m+*.*.i &+A+A+A+$+(.a 0.8 8 $+8 :.:.:.j :.j j j :.n+j :.n+j n+D.. . . ",
+" ~ f.w u.9.v C.! Z.p+V.6.b 7.m+*.i } &+3.z E+8 !+0.0.8 :.$+:.:.j j :.j :.:.j j j n+j j :.j j D.. . . ",
+" 9.u.9.2.|.C.,.Z.p+V.6.h+7.7.f *.i &+3.A+A+E+(.!+!+8 8 8 $+$+$+:.:.:.j j :.:.:.:.j :.j n+j n+n+D.. . ",
+" b.b.a.u., , ++_ Z.s+o+9+B+R.F+i N.} 3.A+i+1.(.i+g+g+8 $+:.:.:.:.$+:.:.:.:.:.:.:.:.:.:.:.:.:.j j :.D.. . ",
+" | G g.F F p.G.p.R v.v.c Y a+; 6+[.@+).^ ^ %+k w+w+A.%+%+B.8 8 8 8 $+8 8 8 8 :.$+$+8 $+8 8 $+8 :.:.:.:.n+D.. ",
+" a.F Y.O O n.6 o.o.o.s .L.: 4+4+~.,+,+Q.Q.d d }.}.}.[+j+ +g+$+8 $+8 8 8 8 8 8 8 8 8 8 $+$+8 $+8 $+$+$+:.. . ",
+" &., G.O O.G.<+<+v.v.Y Y a+a+i.6+Z [.).)./.%+<.k w+A.s.j+j+U u+!+(.8 !+8 !+!+(.(.(.!+(.(.(.g+(.g+8 8 g+$+g+:.n+. ",
+" W.++}+p.O.= B l+-.V.#.t+P.L $.T ' 5.x+r.r.0 '.i+i+1.- u /.` +1.8 8 (.(.(.(.(.!+(.(.(.(.(.!+(.!+(.1.H.8 H.- - x . . ",
+" ~ S.M.R o.R J 6.z+h+9+B+$.`.2+i N.&+&+z A+E+E+(.(.(.(.U. +/ U i+E+E+(.E+(.(.A+(.(.i+(.(.i+(.i+(.(.(.(.(.- f+^.q.M 2 ",
+" h h -.R o.v.#.h+P.b 7.R.2+*.@.i &+3.3.A+A+(.(.E+E+(.P i+ +/ T.U.(.(.E+i+A+A+(.A+A+E+A+K E+A+E+P E+i+P (.U.^.8.4 u+.+ ",
+" 0 8+6.P.~+s Y L 7.m+m+m+2+*.i N.N.&+A+z E+A+(.(.(.E+(.$+i+k / m i+A+A+A+A+A+3.0 z '.A+A+'.A+'.A+K A+K K i+{ ^.8.4 U.g+2 ",
+" h+P.h+L c .Y $.m+m+R.*.*.N.i &+3.3.z A+K E+E+E+(.i+A+8 J.<.m. +'.K A+0 A+z A+3.3.z 3.3.z 3.z 3.3.0 A+K z U.^.8.4 U.- . ",
+" 2 9+7.9+| a+L.; H f *.i i i &+3.z A+A+A+(.(.(.(.E+E+(.A+g+J.k m.m '.3.3.3.3.r.3.3.} 3.3.} 3.} 3.r.3.3.3.K '.J.^.8.4 U.J.1.{. ",
+" &+B+m+R.t.i.: i.i *.i i i } 3.&+3.z A+(.E+E+A+E+A+A+A+A+!+i+k c+m r.A+3.3.3.3.3.3.3.N.N.&+N.&+} 3.} 3.3.3.&+{ ^.8.4 J.P H.. ",
+" &+F+*.*.T i.~.[.T N.i &+&+3.A+A+A+E+E+(.A+E+K E+A+K A+A+z '.m E m D 3.} } } N.N.N.N.N.@.N.N.N.N.N.N.N.N.3.W.'.^.8.4 { J.P U. ",
+" F+F+F+N.W.Z ~.[.x+&+3.3.A+A+A+E+E+E+(.E+(.(.E+K E+A+K 3.3.r.m m.m '.} N.N.N.N.N.@.N.N.N.N.@.i @.N.N.N.N.N.r.'.4 8.4 '.K J.P ",
+"!+N.&+N.3.r.{+,+).'.3.A+z A+A+A+A+(.E+(.(.E+i+A+A+A+A+A+3.u+r.#+E m r.N.N.i @.*.i F+F+F+F+F+@.T F+T @.@.@.T i $ 4 8.4 '.r.'.'.K ",
+"P &+3.&+&+'.@+1 @+E+A+A+A+A+E+(.!+(.(.(.(.A+E+E+K z 3.3.3.!+x+].E 7+5.i N.@.F+@.f F+f f f F+R.F+F+F+T T T N.@.D ^.# 4 r.3.3.z K ",
+"(.3.A+A+A+'.).Q./.1.A+A+E+(.(.(.(.(.(.E+(.A+i+A+A+A+3.3.N.(.x+].E 4.x+F+F+F+F+F+f F+F+R.f f R.f f R.f F+f F+@.D ^.# 4 $ r.3.r.0 ",
+"E+E+!+!+!+x %+Q.k - $+:.E+(.$+$+$+$+(.(.8 8 !+!+K 3.!+!+(.P x+#+E 7+5.F+*.F+R.f R.R.$.R.R.R.R.R.R.f R.R.`.I.`.5.4 -+4 x+N.W.3.3.",
+"E+E+E+(.A+1.%+Q.k 1.(.!+(.!+8 8 8 !+(.P (.P K 3.A+3.3.3.} N.x+7+E 7+5.f f f R.f $.R.R.B+$.$.$.$.B+R.$.$.R.f R.5.^.# 4 D N.N.r.3.",
+"(.(.E.E.0.l <.d {+l a 0.8 8 0.a 0.0.(.(.E.E.E.E.3.3.Q :+Q [ x+7+h.7+!.[ *+*+R.B+*++.+.*+B+B+|+|+*+|+$.R.*+*+e._.4 -+5+!.[ [ N.r.",
+"8 8 a a a l w+}.n l 0.a !+!+0.a a 0.!+E+_.E.d+d+3.3.[ [ Q [ 5.4.h.m Q e.*+*+7.$.*+*++.|+b B+*+|+*+|+b B++.*+*+_.4 -+_+!.[ [ @.N.",
+"!+(.8 8 8 C+w+}.w+g+8 8 8 8 $+$+8 !+(.(.A+A+i+3.3.} 3.N.@.@.5.(+% A 5.m+R.$.$.b b P.P.b b b #.b P.b b b B+L t.I.4 # 1+5.T @.i 3.",
+"$+8 !+8 !+u+C }.C x $+:.:.$+8 $+(.(.(.(.A+A+A+3.3.} 3.N.i @.5.w.% 7+'.} N.&+B+9+N.N.N.N.#.P.N.@.i i P.P.N.N.N.'.4 # %.J.0 J.T N.",
+":.$+8 $+$+x A.[+A.:.:.$+$+8 :.8 8 8 (.E+K 3.3.A+3.N.N.N.@.F+' T.% A D $.$.b b G+#.#.#.z+z+#.z+#.#.#.#.#.P.P.y.t.4 g 1+' I.R.T N.",
+":.:.8 8 :.g+A.[+A.C+8 :.:.$+8 8 !+!+(.(.E+K 3.3.3.N.@.@.F+F+I. +% A r.b b b P.b P.z+#.#.y y J z+#.#.#.#.#.P.y.t.4 g 1+I.f f I.T ",
+"j $+$+:.$+C+A.` U :.:.:.:.:.$+$+(.(.(.A+K A+3.3.N.N.i i *.`.5.3 I A D b b P.P.6.#.#.z+y z+y y y y y z+o+#.#.#.t.4 g %.I.R.R.`.N.",
+" :.$+:.:.n+U j+U {.$+j :.:.8 $+8 (.(.A+A+A+3.3.} N.@.F+f f T (+X.3+H b #.#.#.y y y y y y y y V.y y y o+o+J J t.4 g 1+I.R.f R. ",
+" :.:.$+:.C+ +/ m :.:.$+$+$+$+8 !+(.E+i+K 3.3.3.N.N.i @.*.R.I.A I A $.P.b #.#.#.z+y V.q V.s+q q q q y y z+z+#.F.4 g %.t.L R.I. ",
+" . j :.j n+m c+U C+:.j :.:.8 8 !+(.E+A+A+3.3.&+} @.F+F+F+f I.x.j.A D #.P.6.y y y y y q q s+q s+q q s+e+y y J F.1+g 1+t.L R.N. ",
+" D.:.j :.- m m.m n+j :.:.$+$+8 !+(.(.A+K A+3.} N.N.F+f R.R.I.T.y+3+x+P.#.#.6.y V.s+s+s+s+l+h l+h h q s+e+y o+F.1+b+%.H $.H - ",
+" n+:.j 2 m E m n+j j :.:.8 8 8 (.(.A+r.3.3.N.N.N.@.F+f R.I.x.j.3+x+#.z+y y s+y q v+S S S S S ..h l+h q V.y X 1+b+%.t.t.| ",
+" D.j :.n+e E e n+:.:.:.$+$+g+(.(.P K A+3.3.3.N.@.F+f R.$.I.x.j.3+W.#.#.y y y s+S h s+S S _ _ S S S q h e+V.F.%.k.p t.y.U. ",
+" D.:.{.4.0+7+n+n+j :.:.8 g+!+(.(.A+A+3.} N.N.N.@.*.F+R.t.>.) >.F.z+z+y y q q s+S S S S S _ _ S S q h q q t 1+b+p t.P. ",
+" n+j M + 4.+ n+j n+:.$+$+!+(.(.K P K 3.&+} N.F+F+f f $.I.3+>+;+L #.y z+q V.s+..S S _ _ r _ _ _ _ S v+q V.t 1+k.1+t.`. ",
+" . n+j M M 2 j :.j :.$+:.g+(.(.i+A+K 3.3.&+N.N.F+R.`.R.I.W ) A $ & t+y.7 t+7 9 @ e+e+-.v+v+v+e+-.o+9 7 t t.1+] p t.H ",
+" n+n+j n+j n+j n+j :.8 8 8 (.P A+A+K 3.} N.F+F+*.f f I.(+l.5 > _+> ;+N N N N N N N N N ^.^.5+5+'+4 1+1+4 ] ] p c. ",
+" D.:.:.:.j :.:.:.$+$+H.8 (.(.K 3.r.3.3.N.N.@.F+R.f t.W l.l.l.5 5 5 )+8.8.8.-+-+# # -+A.g g g g b+k.k.] ] ] 1+c. ",
+" D.j j j n+j n+{.:.g+$+!+(.P K K 3.3.N.} @.F+f f $.T V (+> N _+N N N _+N N N ^.5+5+5+^.4 4 4 1+4 1+p %.1+p * ",
+" . j :.j j :.j j g+g+8 (.(.E+K r.3.&+N.@.i F+F+R.f H t.t.& y.y.y.t+#.t+7 e+e+o+o+-.-.-.@ @ 9 9 9 F.F.F.t. ",
+" n+j n+n+n+j :.:.8 H.8 (.i+K A+0 } r.N.@.F+R.f $.$.$.b b #.J o+o+y s+V.q h S ..S ....h q q q o+V.o+t ",
+" . D.j j n+j j :.g+H.!+P (.K 3.K N.N.N.@.@.f `.R.*+*+B+} b P.#.y J V.V.q q S q S s+..S q V.V.o+J P.| ",
+" . n+n+j C+:.$+:.8 H.(.P K K 3.3.3.W.i T F+f f *+*+b N.P.#.P.#.y y y y q V.q q q q V.q e+y o+J J. ",
+" . =.n+j j $+g+8 8 (.(.P K K r.3.} N.i F+`.R.*+*+L } b #.#.#.#.y y y e+q V.q y e+y y o+z+#.H ",
+" . D.n+{.:.:.g+H.(.(.i+K z 3.x+&+N.@.@.f f *+*+R.r.B+L P.P.#.#.J z+z+y y y V.V.y z+z+t J. ",
+" . =.j C+$+:.g+!+(.P K K z r.3.W.N.N.T F+T R.B+$.b L b P.P.#.#.J #.o+J 7 #.J o+o+#.| ",
+" D.j :.g+$+g+!+(.i+K A+r.3.3.N.N.N.T R.f f | R.b L y.P.P.#.#.J #.#.z+J #.t+P. ",
+" . j g+g+g+!+!+P K K r.3.r.N.N.@.@.[ *+f r.R.$.L y.y.L y.b P.#.P.#.#.P.H ",
+" {.$+!+u+P (.K K A+r.3.N.N.N.N.[ [ f r.R.$.$.$.$.b b P.y.P.b y.L ",
+" 2 $+g+1.!+(.K K r.K r.} N.i [ [ F+'.`.R.R.L L L $.L L y.L | ",
+" C+1.P (.K K 3.3.r.W.} Q :+F+0 f `.R.f R.R.| $.T ",
+" x x P K K z r.N.W.N.N.@.i @.T `.f H W.W. ",
+" J.K K K 3.r.x+r.N.T T @. "};
diff --git a/arts/builder/pics/Synth_WAVE_TRI.xpm b/arts/builder/pics/Synth_WAVE_TRI.xpm
new file mode 100644
index 00000000..1ff5cf52
--- /dev/null
+++ b/arts/builder/pics/Synth_WAVE_TRI.xpm
@@ -0,0 +1,305 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 234 2",
+/* colors */
+" c #394684",
+" . c #3AA021",
+" X c #33407E",
+" o c #313E7C",
+" O c #43B123",
+" + c #505AA1",
+" @ c #1D2865",
+" # c #2C3877",
+" $ c #283473",
+" % c #273272",
+" & c #38912C",
+" * c #253070",
+" = c #37457B",
+" - c #232E6E",
+" ; c #263F53",
+" : c #314175",
+" > c #2D3A7B",
+" , c #2C387A",
+" < c #3E4D85",
+" 1 c #3C468D",
+" 2 c #283276",
+" 3 c #374288",
+" 4 c #49BC25",
+" 5 c #232E71",
+" 6 c #343E85",
+" 7 c #465590",
+" 8 c #757CA7",
+" 9 c #202A6E",
+" 0 c #2F3A80",
+" q c #1E286C",
+" w c #1D286B",
+" e c #50619D",
+" r c #2D387E",
+" t c #3F4D89",
+" y c #3A4784",
+" u c #253076",
+" i c #384582",
+" p c #5661A6",
+" a c #323F7C",
+" s c #303D7A",
+" d c #4E599E",
+" f c #3A4787",
+" g c #293573",
+" h c #242F6E",
+" j c #285640",
+" k c #323F7F",
+" l c #44508A",
+" z c #2F3B7C",
+" x c #2E3B7B",
+" c c #2C3979",
+" v c #1B2565",
+" b c #293576",
+" n c #394589",
+" m c #263173",
+" M c #252F72",
+" N c #242F71",
+" B c #5864A4",
+" V c #34427A",
+" C c #212B6E",
+" Z c #2F3B7F",
+" A c #1E296B",
+" S c #344C66",
+" D c #43963C",
+" F c #1D276A",
+" G c #1C2769",
+" H c #2C377C",
+" J c #2B357B",
+" K c #4C5C98",
+" L c #4A5A96",
+" P c #242F74",
+" I c #475693",
+" U c #222D72",
+" Y c #202B70",
+" T c #43528F",
+" R c #33407C",
+" E c #323E7B",
+" W c #41508D",
+" Q c #364482",
+" ! c #354281",
+" ~ c #2E3A7A",
+" ^ c #7F88AF",
+" / c #2C3B6E",
+" ( c #7B84AB",
+" ) c #263272",
+" _ c #364285",
+" ` c #475299",
+" ' c #28356A",
+" ] c #294357",
+" [ c #242E70",
+" { c #212C6D",
+" } c #1F2A6B",
+" | c #1D2869",
+". c #1C2668",
+".. c #495994",
+".X c #354087",
+".o c #242E73",
+".O c #232E72",
+".+ c #465591",
+".@ c #222C71",
+".# c #212C70",
+".$ c #202A6F",
+".% c #1F2A6E",
+".& c #42518D",
+".* c #1E286D",
+".= c #3D4B88",
+".- c #3B4986",
+".; c #294F49",
+".: c #33417E",
+".> c #626DB6",
+"., c #3FB01F",
+".< c #2D3978",
+".1 c #2C3777",
+".2 c #3D4C81",
+".3 c #2A3575",
+".4 c #1A2362",
+".5 c #283373",
+".6 c None",
+".7 c #263171",
+".8 c #222D6D",
+".9 c #365466",
+".0 c #323D80",
+".q c #202B6B",
+".w c #70799F",
+".e c #313E75",
+".r c #2D397B",
+".t c #1D2768",
+".y c #2B3779",
+".u c #3DAA20",
+".i c #293377",
+".p c #495893",
+".a c #182059",
+".s c #222D70",
+".d c #333D84",
+".f c #45548F",
+".g c #35427C",
+".h c #313B82",
+".j c #42508C",
+".k c #347B35",
+".l c #2E397F",
+".z c #1D276B",
+".x c #404E8A",
+".c c #4E5E9B",
+".v c #4C5C99",
+".b c #3C4A86",
+".n c #2C3873",
+".m c #4A5A97",
+".M c #7986A4",
+".N c #399729",
+".B c #3B7F3F",
+".V c #455492",
+".C c #6772BA",
+".Z c #313E7B",
+".A c #303C7A",
+".S c #202A67",
+".D c #21315E",
+".F c #2E3A78",
+".G c #41A42A",
+".H c #1F2D5C",
+".J c #1C2663",
+".K c #5D68B0",
+".L c #2B3675",
+".P c #334080",
+".I c #33486C",
+".U c #327C2F",
+".Y c #1E2B5E",
+".T c #2B396E",
+".R c #384488",
+".E c #253072",
+".W c #242E71",
+".Q c #212C6E",
+".! c #303C80",
+".~ c #202A6D",
+".^ c #42BA1D",
+"./ c #24365D",
+".( c #1E286B",
+".) c #414F8A",
+"._ c #1C2669",
+".` c #2B367B",
+".' c #4D5D99",
+".] c #1F354E",
+".[ c #293479",
+".{ c #4B5B97",
+".} c #273277",
+".| c #657096",
+"X c #2C5C40",
+"X. c #485794",
+"XX c #27336D",
+"Xo c #647C81",
+"XO c #242F6A",
+"X+ c #335B54",
+"X@ c #3F4D8B",
+"X# c #2F3B78",
+"X$ c #307433",
+"X% c #48C31F",
+"X& c #344180",
+"X* c #303D7C",
+"X= c #525DA4",
+"X- c #303B7C",
+"X; c #2B3777",
+"X: c #4A559C",
+"X> c #48CC18",
+"X, c #343F83",
+"X< c #222D6E",
+"X1 c #313D80",
+"X2 c #424D94",
+"X3 c #303D7F",
+"X4 c #404B92",
+"X5 c #1E296A",
+"X6 c #2D397C",
+"X7 c #3E4990",
+"X8 c #1D2769",
+"X9 c #327931",
+"X0 c #2A3579",
+"Xq c #283377",
+"Xw c #273376",
+"Xe c #263175",
+"Xr c #4DAE34",
+"Xt c #2B6634",
+"Xy c #475692",
+"Xu c #294950",
+"Xi c #378A2F",
+"Xp c #212B70",
+"Xa c #44528F",
+"Xs c #43528E",
+"Xd c #346B4A",
+"Xf c #1F296E",
+"Xg c #1E296D",
+"Xh c #2E3980",
+"Xj c #233A54",
+"Xk c #1D276C",
+"Xl c #2C377E",
+"Xz c #3E4C89",
+"Xx c #7E8CAA",
+"Xc c #495897",
+/* pixels */
+".6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.E 2.i.[Xq u P.o.@ 9 A.t.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.n E 3.X.d 0 r J.[.} u P.o U.@ Y.$Xf.4.4.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6 fX2X4 1.R.X.d 0 r.W.[ 8 8 P.o U.@ Y.$.$XfXf.(.4.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6 ! + d `X2X4 1.R.X.h 0 r.W.[ 8 8.o.o U.@ Y.$.$XfXg.*.* q._.4.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6 p pX= d `X2X7 1 3 6.h 0Xl.W.[ 8 8.o.o UXp Y.$.%XfXg.* q q q.z. .6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.6.6.6.6 K.K.K p +X: `X2X7 1 3 6.hXh H.W.[ 8 8.o.o UXp Y.$XfXfXg.* q q w.z.z._.4.6.6.6.6.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.6.6.6.C.>.K.K p +X: `X2X7 1 3 6.h.l H JXq.} P.o.o.@Xp.$.$XfXfXg.* q q.z.z.z F F. .6.6.6.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.6 l.C.C.>.K pX= dX: `X4X7 n 3.d.h.l.`.[Xq u P.o U.@Xp.$.$XfXf.* q q q.z.z F F F F. .a.6.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.p.C.C.>.K.K p + d `X2X7 1.R.X.d 0 r J.s.} 8 8.o U.@Xp.$.%XfXg.* q q w.z.z F F FX8._. .a.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6 K.C.C.C.>.K pX= +X: `X2X7 1 3 6.h 0 H J.s u 8.w.sXp.$.$.$.%XfXg.* q q w.z.z F F FX8._._. .a.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.p.C.C.C.>.K.K p + d `X2X4 1 n.X.d.h.l HX0 C u.w.w.8 C 9.%XfXfXfXg q q w.z.z F F FX8 G._._. v.a.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6 l.C.C.C.>.K.K pX= dX: `X2X7 1 3.X.d 0 r.`.[.q [.|Xo.Y @X5XfXgXfXf.* q q q.(.z.z F F FX8X8._. . v.a.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.C.C.C.>.K.K pX= +X: `X2X4 1 n 3 6.h.l H.[.} *XOXj.;.].H @ qXgXfXfXgXg q q q q.(.(.(.(.( FX8X8. . v.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.C.C.>.>.K.K pX= + d ` `X4X7 1 3.X.d 0 r J 2.7.DXj.;XtXu.H @ qXf 9 9 9 9 9 9 9.~.~.~.~ } q A.(.(.(X8.t v.6.6.6.6.6.6",
+".6.6.6.6.6 K.>.>.K.K.K pX= + dX: `X2X7 1 n.X.d.h.l.`.[ %XO.] j DXr j.].Y.~ 9.#.#.#.#.Q.Q.s.s.Q.Q.Q.Q {.~.~.~ AX5X5 |.4.6.6.6.6.6",
+".6.6.6.6.6.K.K.K.K p pX= + dX: `X2X7 1 n 3 6.h 0 H.[ %.DXj j.UXr OX .].Y {.s 5 5 5 5 5 5 5 5 5 5.s.s.sX<.Q { {.q.q } |.6.6.6.6.6",
+".6.6.6.6 p.K.K p pX= + dX: ` `X2X4 1 n 3.X.d.h r J.5XXXj j.U., 4 4Xt.].D - 5.o.o M M.E.E.E.E.E M N N N [ 5 - -X< {.q.q |.6.6.6.6",
+".6.6.6 ! p p pX= + + dX: ` `X2X7 1 1 3.X.d.h rX0.5 'Xj j.U .X%X%X%XtXj.D [.E m m m m m m m m m m m m m.E * M [ [ -X<.8 {.J.6.6.6",
+".6.6.6 +X= + + d dX: ` `X2X4X7 1 n 3.X.d.h.l H $XXXjX .U OX%X>X>.^XtXj.D m mXwXqXqXqXqXqXqXqXwXwXw.5 m m % m m * * h -.8.q.6.6.6",
+".6.6.6 d dX:X:X: ` `X2X2X4X7 1 n 3.X.d.h.l.`.3 'Xj j.U.N.^X>X>X>.^XtXj.D.5Xw.i bX0X0X0X0X0 b b bXw $.5.5 % % ) % m.7 * h -.6.6.6",
+".6.6 f ` ` ` ` `X2X2X4X7 1 1 n 3.X.d.h.l H.3XX ;X .k O.^X%X>X>X>X%XtXj ' $ bX0.y.y.y.y.y.y.y.yX;X; g $ $ $ $.5.5.5 %.7.7 *.Y.6.6",
+".6.6X2X2X2X2X2X4X7X7 1 1 n 3.X 6.d.h.l ,.3 ' ]X .k.N O.NXi ..^ 4 4XtXj ' b.y , , ,.r.r.r.r.r ,X; g '././ 'XX.3 b b $.5 %.7 h.6.6",
+".6.nX4X4X7X7X7X7 1 1 n 3 3.X.d.h.h r H.3XX ]XdXi O O O.UX X9.N O 4XtXj 'X; ,X6 > > > z z z > >.n.T ].; ]./ ' g.L.L.L g $.5 %.S.6",
+".6 E 1 1 1 1 1 n.R 3.X.X 6.d.h 0 r.y g ' ]Xd &.G O &X9 j ;X XiXr 4Xt ; ' , > z ZX3X3X3X3 z x.n / ]X X$.;./ '.n # #.1.L.3 $.5.S.6",
+".6 3.R.R 3 3 3 3.X 6.d.d.h 0.l H J $XX ].B DX% 4 OX9.; ;./.;.U.N.,Xt ] ' > zX3X1X1X1.0X1X1X# / ]XdXi.NX ] '.<.F.F.< #X;.L.3 %.6",
+".6.X.X.X 6 6 6.d.d.h.h 0.l r.`.[.5 ' ]Xd D.G 4.NX9.;Xj./ 'Xu.U.N.^X$ ] /.AX3.0 k.P.P k o s / ]X &.N .X ].TX#.A z x.F.< #.L.3.6",
+".E.d.d.h.h.h.h.h 0 0.l r H J.[ %XX ;Xd &X% 4 OX9.;Xj 'XXXX ;X9XrX%.BX+.I o kX,X, !X,X& E.e ]XdXi.,.u .X ] / s.Z o.A.A.F.< #.L $",
+" 2 0 0 0 0Xh.l.l r H H.`.[ 2 %.DXjX Xi.G 4.NX9 jXj ' g g g ;.UXrX%.BX+.I k.P ! _ !X& a / ]X Xi.N., &X$Xu /.e a a k o.Z.AX#.F # g",
+".i r r rXl H H.` J JX0.[.}.7XOXj j.U O O.^.k.;Xj ' g ,X;.n ;X9XrX% DX+.IX& ! _ _ Q.: : ]X .U.u.u.,.k.; ].e E X XX& X a o.AX#.F.L",
+".[ J.W.W.W.W J.[.s.s C.q *.D.] j.U.N 4.G &X Xj.D $X; * hXOXu.UXrX% DX+.I ! Q _ !.: : ]X X9.N.,.G DXd S.I V.g ! ! !X& X a.Z.AX# #",
+"Xq.[.[.[.[.[XqXq.} u u [XOXj j.U.,.^X% DXdXu ' g.y , z.<.nXu.U.N.^ DX+.I Q Q ! V ]X X9.u.,.^ D.B.9 = = i i i Q !X& X a o.A.F",
+" u.} 8 8 8 8.} u 8.w.w.|Xj j DXr 4Xr.G.BXoXo.w 8 HX6 ( 8.wXoXi ..^.BXo.w ( ( Q.IXo.B D.G.u.GXrXoXo.w i i ^ ^ ^ ^ i Q ^ ^ ( (.ZX#",
+" P u 8 8 8 8 P.o 8.w.|Xo j.U 4 4 4Xr.BX+.w.w 8 8 H z ( 8.wXoXi ..^.kXo.w ( 8 V S.B D O O., DXoXo.MXx.=.= ^ ^ ^ ^ i ^ ^ ^ ( a.A",
+".o P P.o.o.o.o U.s.Y.] j.U &.u.N.UXdX+ ] g gX0.` z ZX3.A.eX+ &.G.^X$ S.I =.I SX .k &.u &.kXd.9.9 < <XzXzXz.=.=.- f i Q !X& X.Z",
+".@.o.o.o.o.o.o C.q.] jX$.u.u.uX9 jXu 'XXXqX0 ,X6 z.!X1 s.eX+ &Xr 4Xt ;./ ' ;X .k . . .X9X+.9.I : E a WX@.Z.Z s.A.b.-.F #.n.n.: a",
+" 9 U U U U U.@.~.S.]Xt.U.uXiX$ jXj./XX %.iX0 ,X6 ZX3.0 o :X+ &Xr 4X$ ; ] SX .k &.u &.kX+ S.2 <.).&.& T W WX@X@Xz.=.b y i QX& a",
+" A.@.@.@XpXpXp A @.]X$Xi .X$.;.].SXO mXwX0.y.r z ZX1.P o :X+ &Xr 4.k.;X X .k.u.u.u.kX+ S.2 tXaXa.V.VXa T.& W WX@Xz.=.- y i ! R",
+".t Y Y Y Y Y.$.( @.]XtXtXt.;.].H.q hXeXqX0 ,X6 zX3X1.P a :X+XiXrX% &Xt.kXi.N.u &.kX+ S =.)Xs.V.V I.+.V.V T T.& WX@Xz.=.- y i Q.:",
+".6.$.$.$.$.$.$X5 @.] j j.;.].Y.q 5.EXw.iX0 ,X6 zX3.0X, X VX+Xi .X%.u.N ..,.u.u.kX+ S.2.j.V IX.X.X. I I.+.VXaXs.&.xX@Xz.b.- i.6",
+".6Xf.$.$.%XfXf.( |.H.].].].Y.S {.O.EXq b.y , > ZX1 kX, X VXu.U .X>.^.,.,.u &.kX+ S.2 l.fX.XcXc LXc..X. I.+.VXaXs.j.xXz.=.b y i.6",
+".6.4XfXfXfXfXf.( F.J.Y.Y.J.t 9.s M mXqX0.y , >X3X1.P !.: VXu.U.GX>X>X>.^.u.kX+ S.2.j I...m.m.m.m.m.m LX. I.+.VXa.& WX@Xz.b.-.e.6",
+".6.4XfXgXgXgXgXk.z v.J.J @.(.$.s M mXqX0.y.r >X3X1.P !.: VXuX9.GX>.^.^.N.kX+ S.2.j.+...m.v.v.v.v.v K.m LX. I.+.fXs.j.xXz.b.- V.6",
+".6.6.(.*.*.*.*.z.z FX8X8 FXf.Q 5.E mXqX0.y.r zX3.0.P !.: VXuX9.GX>.^.u.kX+ S.2 l I...v.v.'.c.c.c.c.'.v.m LX.Xy.VXa.&.) t.= y.6.6",
+".6.6.4.* q q q q.z.z G.z wXf.Q 5.E mXqX0.y.r zX3.0.P !.: VXuX9.G.^.NX$X+ S =.j.f...m.v.c.c.c.c.c.c.c.' K.m..X..+XaXs.) tXz V.6.6",
+".6.6.6 q q q q q w w.z.( q 9.s 5.E mXqX0.y.r zX3 k.P !.: VXuX9 & ..kX+ S.2.).VX..m.v.'.c.c e e e e e.c.'.{ LX.Xy.fXs.j.xXz.6.6.6",
+".6.6.6._ q w.z.z.z.z.z.z q.~.s 5.E mXq b.y.r zX3 kX& !.: V ]XtX$X$X+ S = tXs IXc.m.v.c.c e e e e e e.c.c K L.pXy.fXs.j.x.b.6.6.6",
+".6.6.6.4.z.z.z.z.z.z F.z.(.~.Q 5.E mXw b.y.r zX- k.P !.g V ]X .BXo S / < T.VX.Xc.m.v.c.c e e e e e e e.c K L.pXy.fXa.j.x =.6.6.6",
+".6.6.6.6. .z.z F F F F F.(.~.Q 5 M mXw b.y.r zX- k.P !X&.g.IXuXoXo =.e.xXa.VX. L.m.v.c.c e e e B e e e.c K L.pXy.fXs.j <.6.6.6.6",
+".6.6.6.6.6._ F F F F F F.(.~.Q.s N mXw b.y.r xX- k.P ! ! ! : :.w.M.b E.&.V IX.Xc.m.v.c.c e e e e e e.c.' K L.pXy.fXs.x.6.6.6.6.6",
+".6.6.6.6.6.4 F F F FX8 F.( }.Q.s N m.5 b.y c >X- k.P ! ! Q.g V.M (.= a.&.V.+ I...m K.'.c e e e e e e.c.'.{ LX..+.fXs.2.6.6.6.6.6",
+".6.6.6.6.6.6. FX8X8 GX8.( q {.s N m m bX; , ~ z k kX& ! Q i i f.bXz W TXa.V IX. L.m.v.'.c.c e e.c.c.' K L.pXy 7Xa.).6.6.6.6.6.6",
+".6.6.6.6.6.6.6. ._._._X8 F A.~X< [.E m bX; #.r z o kX& ! Q i f.=XzX@ W T.V.+ IX. L.m K.'.c.c.c.'.' K L..Xy.+.f.j.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.a. ._._._X8.(.~.Q 5 * % $ b.y.< zX* k.P ! Q f ^ ^Xz.Z W.& T.V.+ IX. L.m.{ K K K K.{ L..X.Xy.f.& =.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.a. . . X8.(.~ { - M m.5 bX; , ~X- o kX& Q i ^ ^.=.ZX@ W TXa.V.+ IX... L L L L L L.pXyXy 7.& =.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.a v. . .( A { - [ m.5 bX; #.F z o kX& ! Q ^ ^.= sX@ W.&XsXa.V.+XyX.X..p.p.p.pX.Xy.+.f.& =.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.a v. X8X5.qX< [ * % $ b.1.<.AX- a XX& Q i ^ ^.-.AXzX@ W.&XsXa.f.V.+XyXyXyXyXy.+ 7.f.& =.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.6.a v.tX5.q { - * m.5 b.L #.F z o kX& ! Q i f.b.=XzX@.x.j.&XsXaXa.f.f.f.f.f.fXa.j =.6.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.6.6.6 v | }.qX< h.7 % $.L.1.< x.A o XX& ! Q i .-.b.=XzX@.x W.j.&XsXsXsXaXsXsXs.).6.6.6.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.6.6.6.6.4 |.q.8 - *.7.5 g.L #.F.A.Z a XX& ^ ^ i.F y.-.=XzXzX@.x.).).j.j.j.j.x.2.6.6.6.6.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6 | {.8 h.7 % $.3X;.<.F.A o a X ^ ^ Q # y.-.b.=XzXz t t.x.x.x <.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.J.q - *.7.5 $.L #.<X#.A.Z a ( ^ !.n i y.-.b.b.b.=XzXz.b =.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.Y h %.5.3.L #.FX#.A o ( (X&.n Q i i y.-.- y V.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.S.S %.3.L #.FX#.A.Z a X.:X& ! Q i i.e V.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6",
+".6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6 $ g.L #.FX#.A.Z a a R.:.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6.6"
+};
diff --git a/arts/builder/pics/Synth_XFADE.xpm b/arts/builder/pics/Synth_XFADE.xpm
new file mode 100644
index 00000000..296b9584
--- /dev/null
+++ b/arts/builder/pics/Synth_XFADE.xpm
@@ -0,0 +1,313 @@
+/* XPM */
+static char *noname[] = {
+/* width height ncolors chars_per_pixel */
+"64 64 242 2",
+/* colors */
+" c #374482",
+" . c #3BA318",
+" X c #39477A",
+" o c #354280",
+" O c #395766",
+" + c #313E7C",
+" @ c #303C7B",
+" # c #2F3C7A",
+" $ c #33921A",
+" % c #338C1A",
+" & c #2C3877",
+" * c #1A2462",
+" = c #4D5D94",
+" - c #253070",
+" ; c #36A316",
+" : c #2E711F",
+" > c #46558D",
+" , c #838CB5",
+" < c #202A6B",
+" 1 c #1C2667",
+" 2 c #32801C",
+" 3 c #39B212",
+" 4 c #283276",
+" 5 c #384289",
+" 6 c #364287",
+" 7 c #242E72",
+" 8 c #283A62",
+" 9 c #232E71",
+" 0 c #343E85",
+" q c #333E84",
+" w c #747AA6",
+" e c #202A6E",
+" r c #424F8C",
+" t c #212D65",
+" y c #1E286C",
+" u c #2E387F",
+" i c #3FC111",
+" p c #1C266A",
+" a c #2B367C",
+" s c #314A5A",
+" d c #2A3771",
+" f c #1A235E",
+" g c #495996",
+" h c #32741F",
+" j c #475594",
+" k c #232E74",
+" l c #445391",
+" z c #333F7D",
+" x c #243261",
+" c c #27523C",
+" v c #313D7B",
+" b c #3B4988",
+" n c #374584",
+" m c #848DB5",
+" M c #376948",
+" N c #2E3B7B",
+" B c #2D397A",
+" V c #33871C",
+" C c #1B2565",
+" Z c #648088",
+" A c #2E5249",
+" S c #222D6F",
+" D c #323D82",
+" F c #55C733",
+" G c #1F296C",
+" H c #1D276A",
+" J c #404E89",
+" K c #1C2769",
+" L c #283378",
+" P c #263176",
+" I c #394682",
+" U c #3AA915",
+" Y c #242F74",
+" T c #475693",
+" R c #232D73",
+" E c #455491",
+" W c #25306B",
+" Q c #202B70",
+" ! c #43528F",
+" ~ c #33407C",
+" ^ c #5F7286",
+" / c #1E296E",
+" ( c #404E8C",
+" ) c #2E3A77",
+" _ c #2D3876",
+" ` c #3BBA0F",
+" ' c #1B2661",
+" ] c #3A4886",
+" [ c #374483",
+" { c #354281",
+" } c #232E6C",
+" | c #2E3A7A",
+". c #3B488A",
+".. c #7C84AC",
+".X c #283474",
+".o c #384487",
+".O c #475299",
+".+ c #38457D",
+".@ c #232E6F",
+".# c #323F77",
+".$ c #1E286A",
+".% c #1C2668",
+".& c #2B367A",
+".* c #3C468E",
+".= c #4B5996",
+".- c #273276",
+".; c #4B5796",
+".: c #629174",
+".> c #354087",
+"., c #767EA9",
+".< c #757CA8",
+".1 c #222C71",
+".2 c #212C70",
+".3 c #44538F",
+".4 c #737AA6",
+".5 c #202A6F",
+".6 c #1F2A6E",
+".7 c #2F3A81",
+".8 c #1E286D",
+".9 c #414F8C",
+".0 c #1D286C",
+".q c #606BB1",
+".w c #4D5B9B",
+".e c #3B4986",
+".r c #1F3150",
+".t c #364381",
+".y c #34417F",
+".u c #435191",
+".i c #555FA6",
+".p c #69E23B",
+".a c #3E4D8C",
+".s c #2A3575",
+".d c #394787",
+".f c #293574",
+".g c #384586",
+".h c None",
+".j c #263171",
+".k c #222D6D",
+".l c #434D94",
+".z c #3E498F",
+".x c #1D2768",
+".c c #346146",
+".v c #1B2566",
+".b c #487453",
+".n c #2A3578",
+".m c #3C4D79",
+".M c #263174",
+".N c #2D5049",
+".B c #59D62E",
+".V c #2F6C23",
+".C c #45548F",
+".Z c #202B6E",
+".A c #313B82",
+".S c #285A30",
+".D c #1E296C",
+".F c #2E397F",
+".G c #1D276B",
+".H c #3E4C88",
+".J c #2A357B",
+".K c #1F2D59",
+".L c #1C2860",
+".P c #213947",
+".I c #283379",
+".U c #3B4885",
+".Y c #3BAD17",
+".T c #28346F",
+".R c #6B76BE",
+".E c #435090",
+".W c #2C6623",
+".Q c #313C7B",
+".! c #1E2A65",
+".~ c #4D589D",
+".^ c #357B25",
+"./ c #2B3675",
+".( c #3A4687",
+".) c #384685",
+"._ c #485498",
+".` c #273271",
+".' c #48598E",
+".] c #273567",
+".[ c #334080",
+".{ c #313E7E",
+".} c #838CB4",
+".| c #39B811",
+"X c #273274",
+"X. c #364086",
+"XX c #171F57",
+"Xo c #222C6F",
+"XO c #1D286A",
+"X+ c #6E769F",
+"X@ c #23493E",
+"X# c #293479",
+"X$ c #283278",
+"X% c #253075",
+"X& c #2E7524",
+"X* c #5965A8",
+"X= c #465592",
+"X- c #222C72",
+"X; c #212C71",
+"X: c #42518E",
+"X> c #323F7B",
+"X, c #202B66",
+"X< c #2F3B78",
+"X1 c #3D4B89",
+"X2 c #394785",
+"X3 c #364382",
+"X4 c #344180",
+"X5 c #323F7E",
+"X6 c #303D7C",
+"X7 c #24503B",
+"X8 c #404B8F",
+"X9 c #8089B0",
+"X0 c #2D3979",
+"Xq c #40B517",
+"Xw c #2B3777",
+"Xe c #3C478B",
+"Xr c #2D3F65",
+"Xt c #2E7A20",
+"Xy c #3C526D",
+"Xu c #47568F",
+"Xi c #212B6D",
+"Xp c #369A17",
+"Xa c #43528B",
+"Xs c #2C377B",
+"Xd c #3E4C86",
+"Xf c #3A458C",
+"Xg c #2F7824",
+"Xh c #273176",
+"Xj c #485893",
+"Xk c #252F74",
+"Xl c #222D71",
+"Xz c #212B70",
+"Xx c #6570B6",
+"Xc c #1F296E",
+"Xv c #42508D",
+"Xb c #1E296D",
+"Xn c #2E3980",
+"Xm c #2C377E",
+"XM c #3E4C89",
+"XN c #213652",
+"XB c #1C2661",
+"XV c #2A3672",
+/* pixels */
+".h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.j 4 L.IX$ P Y k.1 e.D.x.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.hXV.Q 5.> q.7Xm a.IX$X% Y RX-X; Q.5Xc * f.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.e.lX8.* 5.> q.7Xm 7.I.< w Y RX-X; Q.5.5Xc / y f.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h o.~.~.O.lX8.* 5.> D.7Xm 7.I.< w k RX-X; Q.5.5XcXb.8.8 y.% f.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.iX*.i.~.O.lX8.* 5 0.AXnXm 7.I.< w k RX-X; Q.5.6XcXb.8 y y.0.G.%.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.h.h.h.h.w.qX*.i.i.~.O.l.zXf 5 0.AXnXm 7.I.< w k RX-X; Q.5XcXcXb.8 y y.G.G.G.% f.h.h.h.h.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.h.h.hXxXx.qX*.i.~.~.O.l.zXf 5 0.A.FXm.JX$ PXk k R.1Xz.5.5XcXcXb.8 y y.G.G.G H H.v.h.h.h.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.hXa.RXx.q.qX*.i.~.O.O.l.zXf 6 q.7 u aX#X$ PXk RXlX;Xz.5.5XcXc.8 y y.0.G.G H H H H.%XX.h.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.;.R.RXx.qX*.i.i.~.O.lX8.* 5.> D.7Xm aXlX$.<.4 RXlX;Xz.5.6XcXb.8 y y.G.G.G H H H H.% 1XX.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h =.R.RXx.q.qX*.i.~.~.O.l.zXf 5 0.AXnXm.J.@Xh w.4 RX-X; Q.5.6XcXb.8 y y.G.G.G H H H H.%.% 1XX.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.;.R.RXxXx.qX*.i.i.~.O.lX8.*Xf 6 q.7.F a.JXo P w.4 R.1Xz.5.5XcXcXb y y.G.G.G H H H H K.%.%.%.vXX.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.hXa.R.RXxXx.qX*.i.i.~.~.O.l.z.* 5X. D.7Xm aX#Xo P w.4XlX;Xz.5.6XcXc.8 y y y y.G.G H H H H H.%.%.%.vXX.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.hXxXx.q.qX*.i.i.w.=._.l.lX8.*Xf 6 0.A.FXm.J.IXhX% Y RX-X; Q.5.6XcXcXbXb y.D.GXO C C C CXB C * 1.v.%.v.h.h.h.h.h.h.h",
+".h.h.h.h.h.hXxXx.q.qX*X*.i = =Xj.C.EX8.zXf 5X. D.7Xm aX#X$ PXk 7 R.1Xz Q.5.5 e e e e eXc G.!.L.L.L.L.L.L 'XB.x.%.x C.h.h.h.h.h.h",
+".h.h.h.h.h.;.qX+ Z.:.:.:.:.:.:.b.bXy.U.o 5X. q.A.FXm.J.I.-Xi Y.4.4.1.2.2.2.2.2.2.2.2.ZX,.!.rX@X@X7X7X7X@X@.r.!.x.$.$ f.h.h.h.h.h",
+".h.h.h.h.hX*X* Z.p.p.p.p.p.p.p F F.b X.tX. q D.7Xm aX#X$ PXi k.4.4 RXlXlXlXlXl 9 9Xl SX,.KX7Xp U.|.|.| ; $X@.!.! < <.x.h.h.h.h.h",
+".h.h.h.h.iX*.i ^.p.p.p.p.p.p.p.p.B.b MXyX> @.7 u a.J.IXh PXi k.4.4 7 Y Y Y Y Y Y 7 } tXNX7Xg.|.| `.|.| ; $X@ tX,XiXi <.x.h.h.h.h",
+".h.h.h oX*.i.w ^ F.p.p.p.p.p.p.p.p.B F MXr ) u a.JX#X$ PX%XiXk w wXkXkXkXk.M.MXk.j t xX7Xp.| i i ` `.| ; $X@ t <.@ S.kXiXB.h.h.h",
+".h.h.h.~.i.~.~.' ^.b.b.b.b.b.b F.B.B.B.^.cXrXV.X.I L.-Xh P P P P P P P.-.-.-X - WXNX7Xg.|.|.| V.S.S c cX@XN W } -.@.@.k <.h.h.h",
+".h.h.h.~.~.~._ j.3 r JXd.e X X.b F.B.B FXq.c.].TX$ P.-.-.-.-.-.-.-.- L L L 4.X W x c $ 3 i.|Xp c x x.].].] W.j.j.j.j -.@.@.h.h.h",
+".h.h.e.O.O.O.O.lX8X8Xe.(.o.t.y s M.^ F F F.^ AXN W - P.- L.@ L.,.,X#.n.n L.` WXN cXg 3 3 3Xg cXN.].T.T.T.T.T.X.X.X.`.j.j -.!.h.h",
+".h.h.l.l.l.l.l.lX8.z.*.*Xf 5 0 vXr.cXq F.BXq . c x W.-.- L.@X#.,.,.&.&.&.n.T x c $ 3 i 3Xp c 8.T & &X0 &XwXwXw.s.f.X.X.`.j -.h.h",
+".hXVX8X8X8.z.z.z.*XfXf 5 6X. D @ _Xr.c.^ iXqXq.^ cXN W.` L.@.n.,.,.&.&.f.TXN cXg.Y 3 3Xg cXN d _ B N | BX0X0 & &././.f.X.`.` t.h",
+".h.Q.*.*.*XfXfXf 5 5 6X. 0 D.A.FXmXV.] A .Xq iXqXp c x WX#.@.&.,.,XsXs.T.] c $ U i.Y $ c 8 d N NX6X6X6 N N | |X0 & &./.s.X.X t.h",
+".h 5 5 5 5 5 5 6.> 0 q D.A.7.FXm.J.X.TXN A.^XqXqXqXg cXN.T.f.&XsXsXw dXN cX& U U UXg c 8 _X<.{X5X5.{.{ +X6X6 N # |X0 &Xw./.f.`.h",
+".h.>.>.> 0 0 0 q D.A.7.7.FXmXm a.J L.- W x cXpXq i.Y $ c.].TXs B B d.] c % U i U $ cXr )X5.[.[.[.[.[.[X5X5 + +X6 N N |X0 &./.f.h",
+".j q q D.A.A.A.7.7Xn.FXmXm a.JX#.IX$ P - WXN cXg.Y.Y.YX& cXN dX+X+ 8 cX& ; ; UX& AXr.#X> {X3 { { { {X4X4.[.[X5X5 + @ # |X0 &./.T",
+" 4.7.7.7XnXn.F uXmXm a a.JX#.IX$Xh PXh PX W x c $.Y i U %X7 8 ^ ^ c V ; ` ; % AXr.# {X3 [ [ [ [X3X3X3 { {X4.[.[X5 + v #X< ) &XV",
+" LXmXmXmXmXmXm a a.J.JX#.IX$.- P PX% P.-.-.j WXN cX& U . .X& c.b.bX& ; ; ;X& AXr.#.y n.g.g.).g.).).) n [X3X3 {X4.yX5X5 + #X< )./",
+".I a 7 7 7 7.JX#Xl.@XoXoXh PXiXiXiXi P.-.@ S.k t x c V ; ` U ; . . U ` ; V AXr.# n.g.d.(.(.(.(.dX2X2.).) n [ [X3 o.yX5X5 + #X< _",
+"X$.I.I.I.I.IX$X$X$Xh P PX%Xk Y k kXk P.- LX#X#.X.TXN cXg.Y.Y 3 U U U UX& AXr.#.t.d b. b b b b b b b ].(X2.) n [X3 {X4X5X5 + # )",
+" PX$.<.<.<.< P P.< w w w Y 7.4.4.4 w P.-.,.,.,.,Xs.T ^.b .Xq ` ` ` U ..b ^.4.d b.}.}.} ,X1X1.}.}.}.}X1 b.}X9X9X9 [ X9...... vX<",
+" YX% w w w wXkXk.4.4.4.4 R R.4.4.4 w P.-.,.,.,.,Xs.T ^.b ..Y ` ` ` U ..b ^ w b. , , m m.a.a m m m mXMX1.}.}X9X9.) [X9X9....X> #",
+" k Y Y k k k k R R R RXlX-.1.1 R 7Xk P.-X#.&.&Xs B d 8 cXp ; ` ` ` UXp cXr ~X1X1.a.a.a ( ( ( ( ( ( (.a.aXMX1 b.e ]X2 [ .t.y ~ v",
+".1 R R R R R RXlXlX-.1X;X;Xz.2Xl YXk P L.n.&.&./ d 8X@.VXp ; ; U U ;Xp.VX@XN.+.e +X5 z zX:X: z z z z.9 ( + + v #.e.e ) _ _./.y +",
+" eX-X-X-X-X-.1X;X;X;XzXz Q Q.2Xl YXk.- L.n.&.&.T.]X@Xg % UXp $ . .Xp U $.^.N.# I (Xv.u.u.u.u ! !.u !X:Xv.9 (.aXMX1.e ]X2 I.t o ~",
+".DX;X;X;X;X;XzXzXz Q.5.5.5.5.2Xl YXk.- L L.X.TXNX@.S % % %.V c.b.b.V % % %.W.NXr IXM.u l E E E E l l l !X:Xv (.aXMX1.e ] I I.t ~",
+".x Q Q Q Q Q.5.5.5.5.5.6.6.5.2Xl Y.M.- 4.n.T xX@X& V ; %Xg.NXr ^ ^.NXt % ; %Xg A XXd l EX= j jX=X=X= E l ! !Xv.9.aXMX1.eX2 I.t ~",
+".h.5.5.5.5.5.5.5.6.6XcXcXc e.2Xl Y.MX .j WXNX@.S V V V.S.N 8.# ~ ~Xr.N.W % V V.S AXyXdXa TXjXjXj T T TX= E lX:Xv (XM.H.e.U I I.h",
+".hXc.5.5.6XcXcXcXcXcXcXcXc e.2 9 YXkX W xX@.V 2Xp VX&.NXr.#.) ] b.+.#.NXg VXp VX& A.m J T g g g g gXj TX= E lX:Xv (XMXd.eX2 I.h",
+".h *XcXcXcXcXcXcXbXbXb.8Xb e.2 9 7 } WXNX@.S 2 2 2.SX@ 8.# o.d.}.}.U dXr A.S V V 2.S AXyXa.C.=.=.=.= g g TX= E !Xv.9XM.H.e.U.#.h",
+".h f /XbXbXbXb.8.8.8 y yXb e.2Xl 7 t x.P.V 2 $ 2 :X@Xr.# [.g b.} ,.a + I X AX& 2Xp 2X& A.mXa.=.=.w.=.=.=Xj TX=.C !Xv (XMX1.e.#.h",
+".h.h y.8.8.8.8 y y y y y y e.Z < t.r.P.S 2 2 2.SX@ 8X< ~ n.d. .} m.a +.HXdXy A.S 2 2 2.S AXy >Xj.w.w.w.=.=Xj T E !Xv.9XMXd.U.h.h",
+".h.h f.8 y y y y y y.G y.DXcXiX,.K.P.W h %Xt.VX@.] _X4X3.g.( b , m ( zX: !Xd.m AX& 2 % 2.V A.m >.w.w.w.w.= gXjX=.3X:.9XM.H.#.h.h",
+".h.h.h y y y y.0 H.% C C C.!.!.r.P.S : h h.SX@XN d # { [.g.( bX1.a (X:.u lXa JXy A.S 2 2Xt.S AXy >.'Xj.'XuXu T T.C !Xv J.H.h.h.h",
+".h.h.h.%.0.G.G p.% C ' '.L.L.K.P.W : V :.W.P.] d +.[X3 [.).( bX1.a (X:.u EX= T J.m A.VXt % h.V A.mXa >XaXa >XjX=.C !Xv J.e.h.h.h",
+".h.h.h f.G.G.G.% CXX.P.P.P.PX@.S : : :.S.PXN.T _.{.[ { [.g.( b.} m ( z ! E j T.CXaXy A.S h h h.S A A s s sXy >.C.C !Xv J.+.h.h.h",
+".h.h.h.h.%.G.G C '.P.S.W.W : : h 2 :.W.P x.T | NX5.[ { [.).d b.} m ( z ! EX=Xj g.=Xa.m A.V h 2 h : :.V.V.W O >Xa.C !XvXd.h.h.h.h",
+".h.h.h.h.h.% H C '.P.W.W h h h : :.S.P.r WXV BX6X5.[ {X3.)X2 b.} m ( z.u lX= T g.=Xu >Xy A.S h h h h h.V.V O.'Xa.CX: J.h.h.h.h.h",
+".h.h.h.h.h f H C '.P.W h 2 2 2.V.W.P.K W./ & NX6.{.[ {X3.)X2 b.} m ( z ! lX= T g.=.=.w >.m s.W.V.^ h h.^.^.b >Xa.CX: I.h.h.h.h.h",
+".h.h.h.h.h.h.v 1XBXN c.c M.c.cX7.P.r t -.sX0 |X6.{.[X4X3 n.) ]X1XM.a.9X: l E TXj g.=.=Xj >Xy O O.b.b.b.b.bXy >Xa.3 J.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.v 1.! x 8 8 8 8 x t }.j.X.n & B N +X5X4 { [.).( bX1.a (Xv ! lX= T g.=.=.= =Xj.'.'.'.'.'.'.' >.C.3Xa.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.hXX.v.v.!.!.!.! tX, < }.j.X.sXwX0 NX6X5.[ {X3 nX2.}.}XM +.9X: ! EX= TXj.=.=.=Xj.'.'.'.'.' > > >.3Xa X.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.hXX 1.%.% H.$ <Xi.@ -.j.X.fXwX0 |X6 +.[X4X3 [.)X9.}X1 + (Xv ! l EX= TXj g.=.=.=.=.=.=XjXjX=.CXa X.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.hXX.v.%.%.$ GXi.@ -.jX .XXw & | N +X5.[ { [ nX9X9 b v.a (XvX: l EX= TXjXjXjXjXjXjXj TX=.CXa X.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.hXX.v.% H.$Xi S.@ -.`.X.s &X0 #X6X5.[X4X3 [X9X9.e #XM.a.9XvX: !.C EX= T T T TX=X=.C.CXa X.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.hXX.v.x.$ <Xi.@ -.j.X.f./ & | N +X5.y oX3 [.) ].eX1XM.a (XvXv ! !.3.C.C.C.C.C.C.3Xa X.h.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.h.h.h C.$ <Xi S.@.j.`.X./ &X0 N @ +X5.y { [X2.e.eX1XMXM (.9XvXvX: ! ! ! !X:X: J.h.h.h.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.h.h.h.h f.x <.k.@ -.j.X.f./ & | # vX5X5X4X9X9 [ ) ].eX1.HXMXM (.9.9XvXvXvXv J I.h.h.h.h.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.xXi.k.@.j.`.X.sXwX0 | # +X5X5..X9 _X2 ].e.eXd.HXMXMXM J J JXd.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.hXB <.@ -.j.`.X./ &X0X< # +X5.....t _ I IX2.U.e.eX1Xd.H.H.e.+.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.! -.`.X.f./ & )X< # +.....y./.t I I IX2.U.e.U.#.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h t t.`.f./ & )X< # vX> ~.y o.t.t I I.#.#.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h",
+".h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.TXV./ _ )X< # v + ~ ~ ~.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h.h"
+};
diff --git a/arts/builder/pics/cr16-action-artsbuilderexecute.png b/arts/builder/pics/cr16-action-artsbuilderexecute.png
new file mode 100644
index 00000000..abd8f18a
--- /dev/null
+++ b/arts/builder/pics/cr16-action-artsbuilderexecute.png
Binary files differ
diff --git a/arts/builder/pics/cr22-action-artsbuilderexecute.png b/arts/builder/pics/cr22-action-artsbuilderexecute.png
new file mode 100644
index 00000000..d4fbdae4
--- /dev/null
+++ b/arts/builder/pics/cr22-action-artsbuilderexecute.png
Binary files differ
diff --git a/arts/builder/pics/hi16-app-artsbuilder.png b/arts/builder/pics/hi16-app-artsbuilder.png
new file mode 100644
index 00000000..cc030d39
--- /dev/null
+++ b/arts/builder/pics/hi16-app-artsbuilder.png
Binary files differ
diff --git a/arts/builder/pics/hi16-app-artscontrol.png b/arts/builder/pics/hi16-app-artscontrol.png
new file mode 100644
index 00000000..1271ba0a
--- /dev/null
+++ b/arts/builder/pics/hi16-app-artscontrol.png
Binary files differ
diff --git a/arts/builder/pics/hisc-app-artsbuilder.svgz b/arts/builder/pics/hisc-app-artsbuilder.svgz
new file mode 100644
index 00000000..72c9647d
--- /dev/null
+++ b/arts/builder/pics/hisc-app-artsbuilder.svgz
Binary files differ
diff --git a/arts/builder/pics/hisc-app-artscontrol.svgz b/arts/builder/pics/hisc-app-artscontrol.svgz
new file mode 100644
index 00000000..98633799
--- /dev/null
+++ b/arts/builder/pics/hisc-app-artscontrol.svgz
Binary files differ
diff --git a/arts/builder/portposdlg.cpp b/arts/builder/portposdlg.cpp
new file mode 100644
index 00000000..240b3a13
--- /dev/null
+++ b/arts/builder/portposdlg.cpp
@@ -0,0 +1,258 @@
+ /*
+
+ Copyright (C) 1998 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include "portposdlg.h"
+#include "structureport.h"
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qlistbox.h>
+#include <kbuttonbox.h>
+#include <klocale.h>
+#include <kinputdialog.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <kseparator.h>
+#include <qlineedit.h>
+#include <stdio.h>
+#include <arts/debug.h>
+#include <qpushbutton.h>
+#include <kstdguiitem.h>
+
+using namespace std;
+
+PortPosDlg::PortPosDlg(QWidget *parent, Structure *structure) :QDialog(parent,"Props", TRUE)
+{
+ this->structure = structure;
+
+ setCaption(i18n("aRts: Structureport View"));
+
+ QVBoxLayout *mainlayout = new QVBoxLayout(this);
+ //QHBoxLayout *contentslayout = new QHBoxLayout;
+
+// object type
+/*
+ mainlayout->addSpacing(5);
+ QLabel *objectlabel = new QLabel(this);
+ QFont labelfont(objectlabel->font());
+ labelfont.setPointSize(labelfont.pointSize()*3/2);
+ objectlabel->setFont(labelfont);
+ objectlabel->setText(QString(" ")+i18n("Object type: ")+QString(port->owner->name())+QString(" "));
+ objectlabel->setAlignment(AlignCenter);
+ min_size(objectlabel);
+ mainlayout->addWidget(objectlabel);
+*/
+
+// port description
+
+/*
+ mainlayout->addSpacing(5);
+ QLabel *portlabel = new QLabel(this);
+ labelfont.setPointSize(labelfont.pointSize()*4/5);
+ portlabel->setFont(labelfont);
+ portlabel->setText(i18n("Port description: ")+ port->description);
+ min_size(portlabel);
+ portlabel->setAlignment(AlignCenter);
+ mainlayout->addWidget(portlabel);
+
+ int labelwidth = imax(portlabel->sizeHint().width(),objectlabel->sizeHint().width());
+
+ portlabel->setMinimumWidth(labelwidth);
+ objectlabel->setMinimumWidth(labelwidth);
+
+// hruler
+
+ mainlayout->addSpacing(5);
+ KSeparator *ruler = new KSeparator( KSeparator::HLine, this);
+ mainlayout->addWidget(ruler);
+ mainlayout->addSpacing(5);
+ mainlayout->addLayout(contentslayout);
+*/
+// list
+
+ listbox = new QListBox(this);
+
+ update();
+
+ listbox->setMinimumSize(100,200);
+ mainlayout->addWidget(listbox);
+// hruler
+
+ mainlayout->addSpacing(5);
+ KSeparator *ruler2 = new KSeparator( KSeparator::HLine, this);
+ mainlayout->addWidget(ruler2);
+
+// buttons
+
+ QHBoxLayout *buttonlayout = new QHBoxLayout;
+ mainlayout->addSpacing(5);
+ mainlayout->addLayout(buttonlayout);
+ mainlayout->addSpacing(5);
+
+ buttonlayout->addSpacing(5);
+ KButtonBox *bbox = new KButtonBox(this);
+
+ bbox->addButton(KStdGuiItem::help(), this, SLOT( help() ));
+ bbox->addStretch(1);
+
+ KIconLoader iconloader;
+ QButton *raise = bbox->addButton(i18n("&Raise"));
+ raise->setPixmap(iconloader.loadIcon("up", KIcon::Small));
+ connect( raise, SIGNAL( clicked() ), SLOT( raise() ));
+
+ QButton *lower = bbox->addButton(i18n("&Lower"));
+ lower->setPixmap(iconloader.loadIcon("down", KIcon::Small));
+ connect( lower, SIGNAL( clicked() ), SLOT( lower() ));
+
+ QButton *rename = bbox->addButton(i18n("R&ename..."));
+ connect( rename, SIGNAL( clicked() ), SLOT( rename() ));
+
+ QButton *okbutton = bbox->addButton(KStdGuiItem::ok());
+ connect( okbutton, SIGNAL( clicked() ), SLOT(accept() ) );
+
+/*
+ QButton *cancelbutton = bbox->addButton(i18n("Cancel"));
+ connect( cancelbutton, SIGNAL( clicked() ), SLOT(reject() ) );
+*/
+ bbox->layout();
+ //min_size(bbox);
+
+ buttonlayout->addWidget(bbox);
+ buttonlayout->addSpacing(5);
+
+ //mainlayout->activate();
+ mainlayout->freeze();
+}
+
+void PortPosDlg::raise()
+{
+ int i = listbox->currentItem();
+ arts_debug("selected %d",i);
+ if(i < 0) return;
+
+ StructurePort *port = listports[i];
+ assert(port);
+
+ // hmm ok this is ugly that the raise function calls lowerPosition
+ port->lowerPosition();
+ update();
+
+ unsigned long l;
+ for(l=0;l<listports.size();l++)
+ if(listports[l]->id() == port->id())
+ listbox->setCurrentItem(l);
+}
+
+void PortPosDlg::lower()
+{
+ int i = listbox->currentItem();
+ arts_debug("selected %d",i);
+ if(i < 0) return;
+ StructurePort *port = listports[i];
+ assert(port);
+
+ port->raisePosition();
+ update();
+
+ unsigned long l;
+ for(l=0;l<listports.size();l++)
+ if(listports[l]->id() == port->id())
+ listbox->setCurrentItem(l);
+}
+
+void PortPosDlg::rename()
+{
+ int i = listbox->currentItem();
+ arts_debug("selected %d",i);
+ if(i < 0) return;
+ StructurePort *port = listports[i];
+ assert(port);
+
+ bool ok;
+ QString name = KInputDialog::getText( i18n( "Rename Port" ),
+ i18n( "Enter port name:" ), port->name(), &ok, this );
+ if (ok)
+ {
+ arts_debug("rename OK...");
+ port->rename(name.local8Bit());
+ }
+ update();
+
+ unsigned long l;
+ for(l=0;l<listports.size();l++)
+ if(listports[l]->id() == port->id())
+ listbox->setCurrentItem(l);
+}
+void PortPosDlg::update()
+{
+ list<StructureComponent *> &cl = *structure->getComponentList();
+ list<StructureComponent *>::iterator ci;
+
+ listports.erase(listports.begin(), listports.end());
+ listbox->clear();
+
+ // first incoming ports, then outgoing (which are represented by
+ // the opposite directions inside the structure)
+ for(int direction = 0; direction < 2; direction++)
+ {
+ map<long, StructurePort *> pmap;
+ int finddirection = ModulePort::in;
+ int pcount = 0;
+
+ if(direction == 0) finddirection = ModulePort::out;
+
+ for(ci = cl.begin(); ci != cl.end(); ++ci)
+ {
+ StructureComponent *component = *ci;
+ if(component->type() == StructureComponent::ctPort)
+ {
+ StructurePort *port = (StructurePort *)component;
+ if(port->port()->direction == finddirection)
+ {
+ arts_debug("port %s position %ld",
+ port->name().local8Bit().data(), port->position());
+ pmap[port->position()] = port;
+ pcount++;
+ }
+ }
+ }
+ for(int i=0;i<pcount;i++)
+ {
+ StructurePort *port = pmap[i];
+ if (port)
+ {
+ assert(port);
+ listbox->insertItem(port->name(),listports.size());
+ listports.push_back(port);
+ arts_debug("listports.size() is now %d",listports.size());
+ }
+ }
+ }
+ listbox->repaint();
+}
+
+void PortPosDlg::help()
+{
+ KApplication::kApplication()->invokeHelp("", "karts");
+}
+
+#include "portposdlg.moc"
diff --git a/arts/builder/portposdlg.h b/arts/builder/portposdlg.h
new file mode 100644
index 00000000..e9c8f855
--- /dev/null
+++ b/arts/builder/portposdlg.h
@@ -0,0 +1,51 @@
+ /*
+
+ Copyright (C) 1998-1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __PORTPOSDLG_H_
+#define __PORTPOSDLG_H_
+
+#include "structure.h"
+#include "structureport.h"
+#include <qdialog.h>
+#include <qlistbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <vector>
+
+class PortPosDlg :public QDialog {
+ Q_OBJECT
+protected:
+ Structure *structure;
+ QListBox *listbox;
+
+ std::vector<StructurePort *> listports;
+public:
+ PortPosDlg(QWidget *parent, Structure *structure);
+
+ void update();
+public slots:
+ void raise();
+ void lower();
+ void rename();
+ void help();
+};
+
+#endif
diff --git a/arts/builder/propertypanel.cpp b/arts/builder/propertypanel.cpp
new file mode 100644
index 00000000..39c84ac6
--- /dev/null
+++ b/arts/builder/propertypanel.cpp
@@ -0,0 +1,404 @@
+/*
+
+ Copyright (C) 2001 Hans Meine <hans_meine@gmx.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#include "propertypanel.h"
+#include "propertypanel.moc"
+#include "module.h"
+
+#include <kapplication.h>
+#include <klocale.h>
+#include <kdebug.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qcombobox.h>
+#include <qlistbox.h>
+#include <qlineedit.h>
+
+#include <arts/debug.h>
+
+PropertyPanel::PropertyPanel( QWidget* parent, const char* name, WFlags fl )
+ : PropertyPanelBase( parent, name, fl ),
+ component(0L),
+ port(0L)
+{
+ setTitleFont();
+ setTitleColors();
+ connect( kapp, SIGNAL( kdisplayFontChanged() ),
+ this, SLOT( setTitleFont() ));
+ connect( kapp, SIGNAL( kdisplayPaletteChanged() ),
+ this, SLOT( setTitleColors() ));
+ connect( portValueGroup, SIGNAL( clicked(int) ),
+ this, SLOT( pvModeChanged(int) ));
+ connect( constantValueEdit, SIGNAL( returnPressed() ),
+ this, SLOT( writePortProperties() ));
+ connect( constantValueComboBox, SIGNAL( activated(int) ),
+ this, SLOT( writePortProperties() ));
+ connect( portCombo, SIGNAL( activated(int) ),
+ this, SLOT( comboPortSelected(int) ));
+ connect( connectButton, SIGNAL( clicked() ),
+ this, SLOT( connectButtonClicked() ));
+
+ constantValueComboBox->hide();
+ setEnabled( false );
+ tipLabel->hide();
+}
+
+void PropertyPanel::setTitleFont()
+{
+ QFont titleFont = font();
+ titleFont.setPointSizeFloat( titleFont.pointSizeFloat()*1.5f );
+ moduleNameLabel->setFont( titleFont );
+ titleFont = font();
+ titleFont.setPointSizeFloat( titleFont.pointSizeFloat()*1.15f );
+ selectedLabel->setFont( titleFont );
+}
+
+QColorGroup PropertyPanel::highlightColorGroup( QColorGroup cg )
+{
+ cg.setColor( QColorGroup::Foreground, cg.highlightedText() );
+ cg.setColor( QColorGroup::Background, cg.highlight() );
+ return cg;
+}
+
+void PropertyPanel::setTitleColors()
+{
+ QPalette palette = titleFrame->palette();
+ palette.setActive( highlightColorGroup( palette.active() ) );
+ palette.setInactive( highlightColorGroup( palette.inactive() ) );
+ palette.setDisabled( highlightColorGroup( palette.disabled() ) );
+ titleFrame->setPalette( palette );
+}
+
+void PropertyPanel::resizeEvent ( QResizeEvent * )
+{
+ if(width()*3 < height()*4)
+ mainBoxLayout->setDirection( QBoxLayout::TopToBottom );
+ else
+ mainBoxLayout->setDirection( QBoxLayout::LeftToRight );
+}
+
+/*************************************************************/
+
+void PropertyPanel::setSelectedComponent( StructureComponent *component )
+{
+ //kdDebug() << QString("PropertyPanel::setSelectedComponent ") << component << endl;
+ if( this->component == component ) return;
+
+ this->component = component;
+ portCombo->clear();
+ modulePorts.clear();
+ if(!component)
+ setEnabled(false);
+ else
+ {
+ moduleNameLabel->setText( component->name() );
+ if(component->pixmap())
+ {
+ moduleIconLabel->setPixmap( *component->pixmap() );
+ moduleIconLabel->setMinimumSize( moduleIconLabel->sizeHint() );
+ moduleIconLabel->show();
+ }
+ else
+ moduleIconLabel->hide();
+
+ component->dumpPorts(modulePorts);
+
+ // fill combobox
+ for(std::list<ModulePort *>::iterator it = modulePorts.begin();
+ it != modulePorts.end(); it++)
+ {
+ QString portTitle = (*it)->description
+ + QString(" (%1)").arg( (*it)->PortDesc.type().direction == Arts::output ?
+ i18n("OUTPUT") : i18n("INPUT") );
+ portCombo->insertItem( portTitle );
+ }
+ //portCombo->setMinimumSize( portCombo->sizeHint() );
+ setEnabled(true);
+ }
+}
+
+void PropertyPanel::setSelectedPort( ModulePort *port )
+{
+ if( this->port == port ) return;
+
+// if( this->port ) writePortProperties( false ); // rereading not necessary here
+
+ this->port = port;
+ if(port)
+ {
+ setSelectedComponent( port->owner );
+ rereadPortProperties();
+ portValueGroup->setEnabled( true );
+ QString tipText = i18n("Tip: Just typing numbers or alphabetic characters starts entering constant values.");
+ tipLabel->setText( tipText );
+ tipLabel->show();
+
+ // select port in combobox - bah, should be easier ;-)
+ portCombo->setCurrentItem(
+ portCombo->listBox()->index(
+ portCombo->listBox()->findItem( port->description + " (" ) ) );
+ }
+ else
+ {
+ portValueGroup->setEnabled( false );
+ tipLabel->hide();
+ }
+}
+
+void PropertyPanel::pvModeChanged( int newMode )
+{
+ if(!port) return; // sanity check
+
+ switch( newMode )
+ {
+ case 0:
+ case 1:
+ writePortProperties();
+ break;
+ case 2:
+ ; // connection should already be established
+ }
+}
+
+void PropertyPanel::comboPortSelected( int number )
+{
+ if(!component) return;
+
+ std::list<ModulePort *>::iterator it;
+ for( it = modulePorts.begin();
+ (it != modulePorts.end()) && number > 0; it++, number--)
+ ;
+ setSelectedPort( *it );
+ emit portSelected( *it );
+}
+
+void PropertyPanel::connectButtonClicked()
+{
+ if(!port) return; // sanity check
+
+ pvConnectionButton->setChecked( true );
+ emit startConnection( port );
+}
+
+// this is a slot connected to changed() of the editing stuff
+void PropertyPanel::writePortProperties()
+{
+ writePortProperties( true );
+}
+
+void PropertyPanel::writePortProperties( bool reread )
+{
+ //kdDebug() << QString("PropertyPanel::writePortProperties") << endl;
+ if(!port) return; // sanity check
+
+ bool dirty = false;
+
+ if(!pvConnectionButton->isChecked())
+ {
+ if(port->PortDesc.isConnected())
+ {
+ port->PortDesc.disconnectAll();
+ dirty = true;
+ }
+ }
+
+ if(pvNotSetButton->isChecked() &&
+ (port->PortDesc.isConnected() || port->PortDesc.hasValue()))
+ {
+ port->PortDesc.hasValue(false);
+ dirty = true;
+ }
+
+ if(pvConstantButton->isChecked())
+ {
+ std::string type = port->PortDesc.type().dataType;
+ QString newvalue = constantValueEdit->text();
+
+ Arts::Any a;
+ a.type = type;
+ Arts::Buffer b;
+ if(type == "float")
+ b.writeFloat(newvalue.toFloat());
+ else if(type == "long")
+ b.writeLong(newvalue.toLong());
+ else if(type == "string")
+ b.writeString(newvalue.local8Bit().data());
+ else if(type == "boolean")
+ {
+ b.writeBool(newvalue.upper() == "TRUE" || newvalue.upper() == "T"
+ || newvalue == "1");
+ }
+ else if(isEnum(type))
+ {
+ b.writeLong(selectedEnumValue(type));
+ }
+
+ if(b.size() > 0)
+ {
+ b.read(a.value, b.size());
+ port->PortDesc.value(a);
+ dirty = true;
+ }
+ }
+
+ if( dirty )
+ emit portPropertiesChanged( port );
+
+ if( reread )
+ rereadPortProperties();
+}
+
+void PropertyPanel::rereadPortProperties()
+{
+ //kdDebug() << QString("PropertyPanel::rereadPortProperties") << endl;
+ if(!port) return; // sanity check
+
+ std::string dataType = port->PortDesc.type().dataType;
+ if(isEnum(dataType))
+ {
+ constantValueEdit->hide();
+ constantValueComboBox->show();
+
+ fillEnumChoices(dataType);
+ }
+ else
+ {
+ constantValueEdit->show();
+ constantValueComboBox->hide();
+ }
+
+ if( port->PortDesc.hasValue() )
+ {
+ pvConstantButton->setChecked( true );
+
+ QString constValue;
+
+ Arts::Any value = port->PortDesc.value();
+ Arts::Buffer b;
+ b.write(value.value);
+
+ if(isEnum(value.type))
+ {
+ long v = b.readLong();
+ constantValueComboBox->setCurrentItem(findEnumIndex(value.type,v));
+ }
+ else
+ {
+ if(value.type == "float")
+ constValue.sprintf("%2.4f", b.readFloat());
+ else if(value.type == "long")
+ constValue.sprintf("%ld", b.readLong());
+ else if(value.type == "string")
+ {
+ std::string s;
+ b.readString(s);
+ constValue = s.c_str();
+ }
+ else if(value.type == "boolean")
+ {
+ if(b.readBool())
+ constValue = "true";
+ else
+ constValue = "false";
+ }
+ else constValue = ("*unknown type* " + value.type).c_str();
+
+ constantValueEdit->setText( constValue );
+ }
+ }
+ else if( port->PortDesc.isConnected() )
+ pvConnectionButton->setChecked( true );
+ else
+ {
+ pvNotSetButton->setChecked( true );
+ constantValueEdit->clear();
+ }
+
+ pvConnectionButton->setEnabled( port->PortDesc.isConnected() );
+}
+
+bool PropertyPanel::eventFilter( QObject *o, QEvent *e )
+{
+ if( port && !constantValueEdit->hasFocus() && (e->type() == QEvent::KeyPress) ) {
+// kdDebug() << QString(" ..is KeyPress") << endl;
+ QString entered = static_cast<QKeyEvent *>(e)->text();
+ bool goodString = entered.length() > 0;
+
+// kdDebug() << QString("pressed '%1'").arg(entered) << endl;
+
+ for( unsigned int i = 0; i < entered.length(); i++)
+ goodString = goodString && entered[i].isLetterOrNumber();
+
+ if( goodString )
+ {
+ pvConstantButton->setChecked( true );
+ constantValueEdit->setText( entered );
+ constantValueEdit->setFocus();
+// kdDebug() << "keyPress used in propPanel" << endl;
+ return TRUE; // eat event
+ }
+ }
+// else
+// kdDebug() << "event type = " << e->type() << " != " << QEvent::KeyPress << endl;
+ return FALSE; // PropertyPanelBase::eventFilter( o, e );
+}
+
+bool PropertyPanel::isEnum(const std::string& type)
+{
+ Arts::InterfaceRepoV2 interfaceRepo = Arts::DynamicCast(Arts::Dispatcher::the()->interfaceRepo());
+ return (interfaceRepo.identifyType(type) == Arts::tiEnum);
+}
+
+void PropertyPanel::fillEnumChoices(const std::string& type)
+{
+ Arts::EnumDef edef =
+ Arts::Dispatcher::the()->interfaceRepo().queryEnum(type);
+
+ constantValueComboBox->clear();
+
+ std::vector<Arts::EnumComponent>::const_iterator eci;
+ for(eci = edef.contents.begin(); eci != edef.contents.end(); ++eci)
+ constantValueComboBox->insertItem(QString::fromUtf8(eci->name.c_str()));
+}
+
+long PropertyPanel::selectedEnumValue(const std::string& type)
+{
+ unsigned int i = (unsigned int)constantValueComboBox->currentItem();
+ Arts::EnumDef edef =
+ Arts::Dispatcher::the()->interfaceRepo().queryEnum(type);
+
+ if(i >= edef.contents.size()) i = 0;
+ if(edef.contents.size() == 0) return 0;
+ return edef.contents[i].value;
+}
+
+int PropertyPanel::findEnumIndex(const std::string& type, long value)
+{
+ Arts::EnumDef edef =
+ Arts::Dispatcher::the()->interfaceRepo().queryEnum(type);
+
+ for(unsigned int i = 0; i < edef.contents.size(); i++)
+ if(edef.contents[i].value == value)
+ return i;
+ return 0;
+}
diff --git a/arts/builder/propertypanel.h b/arts/builder/propertypanel.h
new file mode 100644
index 00000000..90e1b171
--- /dev/null
+++ b/arts/builder/propertypanel.h
@@ -0,0 +1,78 @@
+/*
+
+ Copyright (C) 2001 Hans Meine <hans_meine@gmx.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+#ifndef PROPERTYPANEL_H
+#define PROPERTYPANEL_H
+
+#include "propertypanelbase.h"
+#include "qpalette.h"
+
+#include <vector>
+#include <list>
+#include <string>
+
+class StructureComponent;
+class ModulePort;
+
+class PropertyPanel: public PropertyPanelBase
+{
+ Q_OBJECT
+
+public:
+ PropertyPanel( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+
+public slots:
+ void setSelectedComponent( StructureComponent *component );
+ void setSelectedPort( ModulePort *port );
+
+protected slots:
+ void setTitleFont();
+ void setTitleColors();
+
+ void pvModeChanged( int newMode );
+ void comboPortSelected( int number );
+ void connectButtonClicked();
+
+ void writePortProperties(); // default reread-> true
+ void writePortProperties( bool reread );
+ void rereadPortProperties();
+
+ bool eventFilter( QObject *, QEvent * );
+
+signals:
+ void startConnection( ModulePort * );
+ void portSelected( ModulePort * );
+ void portPropertiesChanged( ModulePort * ); // might be emitted a little bit too often (see writePortP..)
+
+protected:
+ enum ConnType { ctNone, ctValue, ctConnection };
+ void resizeEvent ( QResizeEvent * );
+
+ StructureComponent *component;
+ ModulePort *port;
+ std::list<ModulePort *> modulePorts;
+
+ QColorGroup highlightColorGroup( QColorGroup cg );
+ bool isEnum(const std::string& type);
+ void fillEnumChoices(const std::string& type);
+ long selectedEnumValue(const std::string& type);
+ int findEnumIndex(const std::string& type, long value);
+};
+
+#endif // PROPERTYPANEL_H
diff --git a/arts/builder/propertypanelbase.ui b/arts/builder/propertypanelbase.ui
new file mode 100644
index 00000000..c89abcc6
--- /dev/null
+++ b/arts/builder/propertypanelbase.ui
@@ -0,0 +1,362 @@
+<!DOCTYPE UI><UI version="3.0" stdsetdef="1">
+<class>PropertyPanelBase</class>
+<author>Hans Meine &lt;hans_meine@gmx.net&gt;</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>propertyPanelBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>628</width>
+ <height>484</height>
+ </rect>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <property name="layoutSpacing" stdset="0">
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>titleFrame</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>8</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>selectedLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Properties of selected module/port:</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>spacerLayout</cstring>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>mainBoxLayout</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout17</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout13</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>moduleIconLabel</cstring>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout16</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>moduleNameLabel</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout10</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>portComboLabel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Port:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>portCombo</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <property name="name">
+ <cstring>portCombo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer28</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>portValueGroup</cstring>
+ </property>
+ <property name="title">
+ <string>Port Value</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>pvNotSetButton</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Not set</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>Layout9</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>pvConstantButton</cstring>
+ </property>
+ <property name="text">
+ <string>Constant &amp;value:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <property name="name">
+ <cstring>constantValueComboBox</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>constantValueEdit</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>connectionLayout</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>pvConnectionButton</cstring>
+ </property>
+ <property name="text">
+ <string>From connection</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer13</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>connectButton</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Connect</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>tipLabel</cstring>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter|AlignLeft</set>
+ </property>
+ <property name="wordwrap" stdset="0">
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>pvConstantButton</sender>
+ <signal>clicked()</signal>
+ <receiver>constantValueEdit</receiver>
+ <slot>setFocus()</slot>
+ </connection>
+ <connection>
+ <sender>pvConstantButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>constantValueEdit</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>pvConstantButton</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>constantValueComboBox</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<slots>
+ <slot access="protected">setTitleFont()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/arts/builder/qttableview.cpp b/arts/builder/qttableview.cpp
new file mode 100644
index 00000000..7f044d25
--- /dev/null
+++ b/arts/builder/qttableview.cpp
@@ -0,0 +1,2274 @@
+/**********************************************************************
+** $Id$
+**
+** Implementation of QtTableView class
+**
+** Created : 941115
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file contains a class moved out of the Qt GUI Toolkit API. It
+** may be used, distributed and modified without limitation.
+**
+**********************************************************************/
+
+#include "qttableview.h"
+#include "qttableview.moc"
+#ifndef QT_NO_QTTABLEVIEW
+#include "qscrollbar.h"
+#include "qpainter.h"
+#include "qdrawutil.h"
+#include <limits.h>
+
+enum ScrollBarDirtyFlags {
+ verGeometry = 0x01,
+ verSteps = 0x02,
+ verRange = 0x04,
+ verValue = 0x08,
+ horGeometry = 0x10,
+ horSteps = 0x20,
+ horRange = 0x40,
+ horValue = 0x80,
+ verMask = 0x0F,
+ horMask = 0xF0
+};
+
+
+#define HSBEXT horizontalScrollBar()->sizeHint().height()
+#define VSBEXT verticalScrollBar()->sizeHint().width()
+
+
+class QCornerSquare : public QWidget // internal class
+{
+public:
+ QCornerSquare( QWidget *, const char* = 0 );
+ void paintEvent( QPaintEvent * );
+};
+
+QCornerSquare::QCornerSquare( QWidget *parent, const char *name )
+ : QWidget( parent, name )
+{
+}
+
+void QCornerSquare::paintEvent( QPaintEvent * )
+{
+}
+
+
+// NOT REVISED
+/*!
+ \class QtTableView qttableview.h
+ \brief The QtTableView class provides an abstract base for tables.
+
+ \obsolete
+
+ A table view consists of a number of abstract cells organized in rows
+ and columns, and a visible part called a view. The cells are identified
+ with a row index and a column index. The top-left cell is in row 0,
+ column 0.
+
+ The behavior of the widget can be finely tuned using
+ setTableFlags(); a typical subclass will consist of little more than a
+ call to setTableFlags(), some table content manipulation and an
+ implementation of paintCell(). Subclasses that need cells with
+ variable width or height must reimplement cellHeight() and/or
+ cellWidth(). Use updateTableSize() to tell QtTableView when the
+ width or height has changed.
+
+ When you read this documentation, it is important to understand the
+ distinctions among the four pixel coordinate systems involved.
+
+ \list 1
+ \i The \e cell coordinates. (0,0) is the top-left corner of a cell.
+ Cell coordinates are used by functions such as paintCell().
+
+ \i The \e table coordinates. (0,0) is the top-left corner of the cell at
+ row 0 and column 0. These coordinates are absolute; that is, they are
+ independent of what part of the table is visible at the moment. They are
+ used by functions such as setXOffset() or maxYOffset().
+
+ \i The \e widget coordinates. (0,0) is the top-left corner of the widget,
+ \e including the frame. They are used by functions such as repaint().
+
+ \i The \e view coordinates. (0,0) is the top-left corner of the view, \e
+ excluding the frame. This is the least-used coordinate system; it is used by
+ functions such as viewWidth(). \endlist
+
+ It is rather unfortunate that we have to use four different
+ coordinate systems, but there was no alternative to provide a flexible and
+ powerful base class.
+
+ Note: The row,column indices are always given in that order,
+ i.e., first the vertical (row), then the horizontal (column). This is
+ the opposite order of all pixel operations, which take first the
+ horizontal (x) and then the vertical (y).
+
+ <img src=qtablevw-m.png> <img src=qtablevw-w.png>
+
+ \warning the functions setNumRows(), setNumCols(), setCellHeight(),
+ setCellWidth(), setTableFlags() and clearTableFlags() may cause
+ virtual functions such as cellWidth() and cellHeight() to be called,
+ even if autoUpdate() is FALSE. This may cause errors if relevant
+ state variables are not initialized.
+
+ \warning Experience has shown that use of this widget tends to cause
+ more bugs than expected and our analysis indicates that the widget's
+ very flexibility is the problem. If QScrollView or QListBox can
+ easily be made to do the job you need, we recommend subclassing
+ those widgets rather than QtTableView. In addition, QScrollView makes
+ it easy to have child widgets inside tables, which QtTableView
+ doesn't support at all.
+
+ \sa QScrollView
+ \link guibooks.html#fowler GUI Design Handbook: Table\endlink
+*/
+
+
+/*!
+ Constructs a table view. The \a parent, \a name and \f arguments
+ are passed to the QFrame constructor.
+
+ The \link setTableFlags() table flags\endlink are all cleared (set to 0).
+ Set \c Tbl_autoVScrollBar or \c Tbl_autoHScrollBar to get automatic scroll
+ bars and \c Tbl_clipCellPainting to get safe clipping.
+
+ The \link setCellHeight() cell height\endlink and \link setCellWidth()
+ cell width\endlink are set to 0.
+
+ Frame line shapes (QFrame::HLink and QFrame::VLine) are disallowed;
+ see QFrame::setFrameStyle().
+
+ Note that the \a f argument is \e not \link setTableFlags() table
+ flags \endlink but rather \link QWidget::QWidget() widget
+ flags. \endlink
+
+*/
+
+QtTableView::QtTableView( QWidget *parent, const char *name, WFlags f )
+ : QFrame( parent, name, f )
+{
+ nRows = nCols = 0; // zero rows/cols
+ xCellOffs = yCellOffs = 0; // zero offset
+ xCellDelta = yCellDelta = 0; // zero cell offset
+ xOffs = yOffs = 0; // zero total pixel offset
+ cellH = cellW = 0; // user defined cell size
+ tFlags = 0;
+ vScrollBar = hScrollBar = 0; // no scroll bars
+ cornerSquare = 0;
+ sbDirty = 0;
+ eraseInPaint = FALSE;
+ verSliding = FALSE;
+ verSnappingOff = FALSE;
+ horSliding = FALSE;
+ horSnappingOff = FALSE;
+ coveringCornerSquare = FALSE;
+ inSbUpdate = FALSE;
+}
+
+/*!
+ Destroys the table view.
+*/
+
+QtTableView::~QtTableView()
+{
+ delete vScrollBar;
+ delete hScrollBar;
+ delete cornerSquare;
+}
+
+
+/*!
+ \internal
+ Reimplements QWidget::setBackgroundColor() for binary compatibility.
+ \sa setPalette()
+*/
+
+void QtTableView::setBackgroundColor( const QColor &c )
+{
+ QWidget::setBackgroundColor( c );
+}
+
+/*!\reimp
+*/
+
+void QtTableView::setPalette( const QPalette &p )
+{
+ QWidget::setPalette( p );
+}
+
+/*!\reimp
+*/
+
+void QtTableView::show()
+{
+ showOrHideScrollBars();
+ QWidget::show();
+}
+
+
+/*!
+ \overload void QtTableView::repaint( bool erase )
+ Repaints the entire view.
+*/
+
+/*!
+ Repaints the table view directly by calling paintEvent() directly
+ unless updates are disabled.
+
+ Erases the view area \a (x,y,w,h) if \a erase is TRUE. Parameters \a
+ (x,y) are in \e widget coordinates.
+
+ If \a w is negative, it is replaced with <code>width() - x</code>.
+ If \a h is negative, it is replaced with <code>height() - y</code>.
+
+ Doing a repaint() usually is faster than doing an update(), but
+ calling update() many times in a row will generate a single paint
+ event.
+
+ At present, QtTableView is the only widget that reimplements \link
+ QWidget::repaint() repaint()\endlink. It does this because by
+ clearing and then repainting one cell at at time, it can make the
+ screen flicker less than it would otherwise. */
+
+void QtTableView::repaint( int x, int y, int w, int h, bool erase )
+{
+ if ( !isVisible() || testWState(WState_BlockUpdates) )
+ return;
+ if ( w < 0 )
+ w = width() - x;
+ if ( h < 0 )
+ h = height() - y;
+ QRect r( x, y, w, h );
+ if ( r.isEmpty() )
+ return; // nothing to do
+ QPaintEvent e( r );
+ if ( erase && backgroundMode() != NoBackground )
+ eraseInPaint = TRUE; // erase when painting
+ paintEvent( &e );
+ eraseInPaint = FALSE;
+}
+
+/*!
+ \overload void QtTableView::repaint( const QRect &r, bool erase )
+ Replaints rectangle \a r. If \a erase is TRUE draws the background
+ using the palette's background.
+*/
+
+
+/*!
+ \fn int QtTableView::numRows() const
+ Returns the number of rows in the table.
+ \sa numCols(), setNumRows()
+*/
+
+/*!
+ Sets the number of rows of the table to \a rows (must be non-negative).
+ Does not change topCell().
+
+ The table repaints itself automatically if autoUpdate() is set.
+
+ \sa numCols(), setNumCols(), numRows()
+*/
+
+void QtTableView::setNumRows( int rows )
+{
+ if ( rows < 0 ) {
+#if defined(QT_CHECK_RANGE)
+ qWarning( "QtTableView::setNumRows: (%s) Negative argument %d.",
+ name( "unnamed" ), rows );
+#endif
+ return;
+ }
+ if ( nRows == rows )
+ return;
+
+ if ( autoUpdate() && isVisible() ) {
+ int oldLastVisible = lastRowVisible();
+ int oldTopCell = topCell();
+ nRows = rows;
+ if ( autoUpdate() && isVisible() &&
+ ( oldLastVisible != lastRowVisible() || oldTopCell != topCell() ) )
+ repaint( oldTopCell != topCell() );
+ } else {
+ // Be more careful - if destructing, bad things might happen.
+ nRows = rows;
+ }
+ updateScrollBars( verRange );
+ updateFrameSize();
+}
+
+/*!
+ \fn int QtTableView::numCols() const
+ Returns the number of columns in the table.
+ \sa numRows(), setNumCols()
+*/
+
+/*!
+ Sets the number of columns of the table to \a cols (must be non-negative).
+ Does not change leftCell().
+
+ The table repaints itself automatically if autoUpdate() is set.
+
+ \sa numCols(), numRows(), setNumRows()
+*/
+
+void QtTableView::setNumCols( int cols )
+{
+ if ( cols < 0 ) {
+#if defined(QT_CHECK_RANGE)
+ qWarning( "QtTableView::setNumCols: (%s) Negative argument %d.",
+ name( "unnamed" ), cols );
+#endif
+ return;
+ }
+ if ( nCols == cols )
+ return;
+ int oldCols = nCols;
+ nCols = cols;
+ if ( autoUpdate() && isVisible() ) {
+ int maxCol = lastColVisible();
+ if ( maxCol >= oldCols || maxCol >= nCols )
+ repaint();
+ }
+ updateScrollBars( horRange );
+ updateFrameSize();
+}
+
+
+/*!
+ \fn int QtTableView::topCell() const
+ Returns the index of the first row in the table that is visible in
+ the view. The index of the first row is 0.
+ \sa leftCell(), setTopCell()
+*/
+
+/*!
+ Scrolls the table so that \a row becomes the top row.
+ The index of the very first row is 0.
+ \sa setYOffset(), setTopLeftCell(), setLeftCell()
+*/
+
+void QtTableView::setTopCell( int row )
+{
+ setTopLeftCell( row, -1 );
+ return;
+}
+
+/*!
+ \fn int QtTableView::leftCell() const
+ Returns the index of the first column in the table that is visible in
+ the view. The index of the very leftmost column is 0.
+ \sa topCell(), setLeftCell()
+*/
+
+/*!
+ Scrolls the table so that \a col becomes the leftmost
+ column. The index of the leftmost column is 0.
+ \sa setXOffset(), setTopLeftCell(), setTopCell()
+*/
+
+void QtTableView::setLeftCell( int col )
+{
+ setTopLeftCell( -1, col );
+ return;
+}
+
+/*!
+ Scrolls the table so that the cell at row \a row and colum \a
+ col becomes the top-left cell in the view. The cell at the extreme
+ top left of the table is at position (0,0).
+ \sa setLeftCell(), setTopCell(), setOffset()
+*/
+
+void QtTableView::setTopLeftCell( int row, int col )
+{
+ int newX = xOffs;
+ int newY = yOffs;
+
+ if ( col >= 0 ) {
+ if ( cellW ) {
+ newX = col*cellW;
+ if ( newX > maxXOffset() )
+ newX = maxXOffset();
+ } else {
+ newX = 0;
+ while ( col )
+ newX += cellWidth( --col ); // optimize using current! ###
+ }
+ }
+ if ( row >= 0 ) {
+ if ( cellH ) {
+ newY = row*cellH;
+ if ( newY > maxYOffset() )
+ newY = maxYOffset();
+ } else {
+ newY = 0;
+ while ( row )
+ newY += cellHeight( --row ); // optimize using current! ###
+ }
+ }
+ setOffset( newX, newY );
+}
+
+
+/*!
+ \fn int QtTableView::xOffset() const
+
+ Returns the x coordinate in \e table coordinates of the pixel that is
+ currently on the left edge of the view.
+
+ \sa setXOffset(), yOffset(), leftCell() */
+
+/*!
+ Scrolls the table so that \a x becomes the leftmost pixel in the view.
+ The \a x parameter is in \e table coordinates.
+
+ The interaction with \link setTableFlags() Tbl_snapToHGrid
+ \endlink is tricky.
+
+ \sa xOffset(), setYOffset(), setOffset(), setLeftCell()
+*/
+
+void QtTableView::setXOffset( int x )
+{
+ setOffset( x, yOffset() );
+}
+
+/*!
+ \fn int QtTableView::yOffset() const
+
+ Returns the y coordinate in \e table coordinates of the pixel that is
+ currently on the top edge of the view.
+
+ \sa setYOffset(), xOffset(), topCell()
+*/
+
+
+/*!
+ Scrolls the table so that \a y becomes the top pixel in the view.
+ The \a y parameter is in \e table coordinates.
+
+ The interaction with \link setTableFlags() Tbl_snapToVGrid
+ \endlink is tricky.
+
+ \sa yOffset(), setXOffset(), setOffset(), setTopCell()
+*/
+
+void QtTableView::setYOffset( int y )
+{
+ setOffset( xOffset(), y );
+}
+
+/*!
+ Scrolls the table so that \a (x,y) becomes the top-left pixel
+ in the view. Parameters \a (x,y) are in \e table coordinates.
+
+ The interaction with \link setTableFlags() Tbl_snapTo*Grid \endlink
+ is tricky. If \a updateScrBars is TRUE, the scroll bars are
+ updated.
+
+ \sa xOffset(), yOffset(), setXOffset(), setYOffset(), setTopLeftCell()
+*/
+
+void QtTableView::setOffset( int x, int y, bool updateScrBars )
+{
+ if ( (!testTableFlags(Tbl_snapToHGrid) || xCellDelta == 0) &&
+ (!testTableFlags(Tbl_snapToVGrid) || yCellDelta == 0) &&
+ (x == xOffs && y == yOffs) )
+ return;
+
+ if ( x < 0 )
+ x = 0;
+ if ( y < 0 )
+ y = 0;
+
+ if ( cellW ) {
+ if ( x > maxXOffset() )
+ x = maxXOffset();
+ xCellOffs = x / cellW;
+ if ( !testTableFlags(Tbl_snapToHGrid) ) {
+ xCellDelta = (short)(x % cellW);
+ } else {
+ x = xCellOffs*cellW;
+ xCellDelta = 0;
+ }
+ } else {
+ int xn=0, xcd=0, col = 0;
+ while ( col < nCols-1 && x >= xn+(xcd=cellWidth(col)) ) {
+ xn += xcd;
+ col++;
+ }
+ xCellOffs = col;
+ if ( testTableFlags(Tbl_snapToHGrid) ) {
+ xCellDelta = 0;
+ x = xn;
+ } else {
+ xCellDelta = (short)(x-xn);
+ }
+ }
+ if ( cellH ) {
+ if ( y > maxYOffset() )
+ y = maxYOffset();
+ yCellOffs = y / cellH;
+ if ( !testTableFlags(Tbl_snapToVGrid) ) {
+ yCellDelta = (short)(y % cellH);
+ } else {
+ y = yCellOffs*cellH;
+ yCellDelta = 0;
+ }
+ } else {
+ int yn=0, yrd=0, row=0;
+ while ( row < nRows-1 && y >= yn+(yrd=cellHeight(row)) ) {
+ yn += yrd;
+ row++;
+ }
+ yCellOffs = row;
+ if ( testTableFlags(Tbl_snapToVGrid) ) {
+ yCellDelta = 0;
+ y = yn;
+ } else {
+ yCellDelta = (short)(y-yn);
+ }
+ }
+ int dx = (x - xOffs);
+ int dy = (y - yOffs);
+ xOffs = x;
+ yOffs = y;
+ if ( autoUpdate() && isVisible() )
+ scroll( dx, dy );
+ if ( updateScrBars )
+ updateScrollBars( verValue | horValue );
+}
+
+
+/*!
+ \overload int QtTableView::cellWidth() const
+
+ Returns the column width in pixels. Returns 0 if the columns have
+ variable widths.
+
+ \sa setCellWidth(), cellHeight()
+*/
+
+/*!
+ Returns the width of column \a col in pixels.
+
+ This function is virtual and must be reimplemented by subclasses that
+ have variable cell widths. Note that if the total table width
+ changes, updateTableSize() must be called.
+
+ \sa setCellWidth(), cellHeight(), totalWidth(), updateTableSize()
+*/
+
+int QtTableView::cellWidth( int )
+{
+ return cellW;
+}
+
+
+/*!
+ Sets the width in pixels of the table cells to \a cellWidth.
+
+ Setting it to 0 means that the column width is variable. When
+ set to 0 (this is the default) QtTableView calls the virtual function
+ cellWidth() to get the width.
+
+ \sa cellWidth(), setCellHeight(), totalWidth(), numCols()
+*/
+
+void QtTableView::setCellWidth( int cellWidth )
+{
+ if ( cellW == cellWidth )
+ return;
+#if defined(QT_CHECK_RANGE)
+ if ( cellWidth < 0 || cellWidth > SHRT_MAX ) {
+ qWarning( "QtTableView::setCellWidth: (%s) Argument out of range (%d)",
+ name( "unnamed" ), cellWidth );
+ return;
+ }
+#endif
+ cellW = (short)cellWidth;
+
+ updateScrollBars( horSteps | horRange );
+ if ( autoUpdate() && isVisible() )
+ repaint();
+
+}
+
+/*!
+ \overload int QtTableView::cellHeight() const
+
+ Returns the row height, in pixels. Returns 0 if the rows have
+ variable heights.
+
+ \sa setCellHeight(), cellWidth()
+*/
+
+
+/*!
+ Returns the height of row \a row in pixels.
+
+ This function is virtual and must be reimplemented by subclasses that
+ have variable cell heights. Note that if the total table height
+ changes, updateTableSize() must be called.
+
+ \sa setCellHeight(), cellWidth(), totalHeight()
+*/
+
+int QtTableView::cellHeight( int )
+{
+ return cellH;
+}
+
+/*!
+ Sets the height in pixels of the table cells to \a cellHeight.
+
+ Setting it to 0 means that the row height is variable. When set
+ to 0 (this is the default), QtTableView calls the virtual function
+ cellHeight() to get the height.
+
+ \sa cellHeight(), setCellWidth(), totalHeight(), numRows()
+*/
+
+void QtTableView::setCellHeight( int cellHeight )
+{
+ if ( cellH == cellHeight )
+ return;
+#if defined(QT_CHECK_RANGE)
+ if ( cellHeight < 0 || cellHeight > SHRT_MAX ) {
+ qWarning( "QtTableView::setCellHeight: (%s) Argument out of range (%d)",
+ name( "unnamed" ), cellHeight );
+ return;
+ }
+#endif
+ cellH = (short)cellHeight;
+ if ( autoUpdate() && isVisible() )
+ repaint();
+ updateScrollBars( verSteps | verRange );
+}
+
+
+/*!
+ Returns the total width of the table in pixels.
+
+ This function is virtual and should be reimplemented by subclasses that
+ have variable cell widths and a non-trivial cellWidth() function, or a
+ large number of columns in the table.
+
+ The default implementation may be slow for very wide tables.
+
+ \sa cellWidth(), totalHeight() */
+
+int QtTableView::totalWidth()
+{
+ if ( cellW ) {
+ return cellW*nCols;
+ } else {
+ int tw = 0;
+ for( int i = 0 ; i < nCols ; i++ )
+ tw += cellWidth( i );
+ return tw;
+ }
+}
+
+/*!
+ Returns the total height of the table in pixels.
+
+ This function is virtual and should be reimplemented by subclasses that
+ have variable cell heights and a non-trivial cellHeight() function, or a
+ large number of rows in the table.
+
+ The default implementation may be slow for very tall tables.
+
+ \sa cellHeight(), totalWidth()
+*/
+
+int QtTableView::totalHeight()
+{
+ if ( cellH ) {
+ return cellH*nRows;
+ } else {
+ int th = 0;
+ for( int i = 0 ; i < nRows ; i++ )
+ th += cellHeight( i );
+ return th;
+ }
+}
+
+
+/*!
+ \fn uint QtTableView::tableFlags() const
+
+ Returns the union of the table flags that are currently set.
+
+ \sa setTableFlags(), clearTableFlags(), testTableFlags()
+*/
+
+/*!
+ \fn bool QtTableView::testTableFlags( uint f ) const
+
+ Returns TRUE if any of the table flags in \a f are currently set,
+ otherwise FALSE.
+
+ \sa setTableFlags(), clearTableFlags(), tableFlags()
+*/
+
+/*!
+ Sets the table flags to \a f.
+
+ If a flag setting changes the appearance of the table, the table is
+ repainted if - and only if - autoUpdate() is TRUE.
+
+ The table flags are mostly single bits, though there are some multibit
+ flags for convenience. Here is a complete list:
+
+ <dl compact>
+ <dt> Tbl_vScrollBar <dd> - The table has a vertical scroll bar.
+ <dt> Tbl_hScrollBar <dd> - The table has a horizontal scroll bar.
+ <dt> Tbl_autoVScrollBar <dd> - The table has a vertical scroll bar if
+ - and only if - the table is taller than the view.
+ <dt> Tbl_autoHScrollBar <dd> The table has a horizontal scroll bar if
+ - and only if - the table is wider than the view.
+ <dt> Tbl_autoScrollBars <dd> - The union of the previous two flags.
+ <dt> Tbl_clipCellPainting <dd> - The table uses QPainter::setClipRect() to
+ make sure that paintCell() will not draw outside the cell
+ boundaries.
+ <dt> Tbl_cutCellsV <dd> - The table will never show part of a
+ cell at the bottom of the table; if there is not space for all of
+ a cell, the space is left blank.
+ <dt> Tbl_cutCellsH <dd> - The table will never show part of a
+ cell at the right side of the table; if there is not space for all of
+ a cell, the space is left blank.
+ <dt> Tbl_cutCells <dd> - The union of the previous two flags.
+ <dt> Tbl_scrollLastHCell <dd> - When the user scrolls horizontally,
+ let him/her scroll the last cell left until it is at the left
+ edge of the view. If this flag is not set, the user can only scroll
+ to the point where the last cell is completely visible.
+ <dt> Tbl_scrollLastVCell <dd> - When the user scrolls vertically, let
+ him/her scroll the last cell up until it is at the top edge of
+ the view. If this flag is not set, the user can only scroll to the
+ point where the last cell is completely visible.
+ <dt> Tbl_scrollLastCell <dd> - The union of the previous two flags.
+ <dt> Tbl_smoothHScrolling <dd> - The table scrolls as smoothly as
+ possible when the user scrolls horizontally. When this flag is not
+ set, scrolling is done one cell at a time.
+ <dt> Tbl_smoothVScrolling <dd> - The table scrolls as smoothly as
+ possible when scrolling vertically. When this flag is not set,
+ scrolling is done one cell at a time.
+ <dt> Tbl_smoothScrolling <dd> - The union of the previous two flags.
+ <dt> Tbl_snapToHGrid <dd> - Except when the user is actually scrolling,
+ the leftmost column shown snaps to the leftmost edge of the view.
+ <dt> Tbl_snapToVGrid <dd> - Except when the user is actually
+ scrolling, the top row snaps to the top edge of the view.
+ <dt> Tbl_snapToGrid <dd> - The union of the previous two flags.
+ </dl>
+
+ You can specify more than one flag at a time using bitwise OR.
+
+ Example:
+ \code
+ setTableFlags( Tbl_smoothScrolling | Tbl_autoScrollBars );
+ \endcode
+
+ \warning The cutCells options (\c Tbl_cutCells, \c Tbl_cutCellsH and
+ Tbl_cutCellsV) may cause painting problems when scrollbars are
+ enabled. Do not combine cutCells and scrollbars.
+
+
+ \sa clearTableFlags(), testTableFlags(), tableFlags()
+*/
+
+void QtTableView::setTableFlags( uint f )
+{
+ f = (f ^ tFlags) & f; // clear flags already set
+ tFlags |= f;
+
+ bool updateOn = autoUpdate();
+ setAutoUpdate( FALSE );
+
+ uint repaintMask = Tbl_cutCellsV | Tbl_cutCellsH;
+
+ if ( f & Tbl_vScrollBar ) {
+ setVerScrollBar( TRUE );
+ }
+ if ( f & Tbl_hScrollBar ) {
+ setHorScrollBar( TRUE );
+ }
+ if ( f & Tbl_autoVScrollBar ) {
+ updateScrollBars( verRange );
+ }
+ if ( f & Tbl_autoHScrollBar ) {
+ updateScrollBars( horRange );
+ }
+ if ( f & Tbl_scrollLastHCell ) {
+ updateScrollBars( horRange );
+ }
+ if ( f & Tbl_scrollLastVCell ) {
+ updateScrollBars( verRange );
+ }
+ if ( f & Tbl_snapToHGrid ) {
+ updateScrollBars( horRange );
+ }
+ if ( f & Tbl_snapToVGrid ) {
+ updateScrollBars( verRange );
+ }
+ if ( f & Tbl_snapToGrid ) { // Note: checks for 2 flags
+ if ( (f & Tbl_snapToHGrid) != 0 && xCellDelta != 0 || //have to scroll?
+ (f & Tbl_snapToVGrid) != 0 && yCellDelta != 0 ) {
+ snapToGrid( (f & Tbl_snapToHGrid) != 0, // do snapping
+ (f & Tbl_snapToVGrid) != 0 );
+ repaintMask |= Tbl_snapToGrid; // repaint table
+ }
+ }
+
+ if ( updateOn ) {
+ setAutoUpdate( TRUE );
+ updateScrollBars();
+ if ( isVisible() && (f & repaintMask) )
+ repaint();
+ }
+
+}
+
+/*!
+ Clears the \link setTableFlags() table flags\endlink that are set
+ in \a f.
+
+ Example (clears a single flag):
+ \code
+ clearTableFlags( Tbl_snapToGrid );
+ \endcode
+
+ The default argument clears all flags.
+
+ \sa setTableFlags(), testTableFlags(), tableFlags()
+*/
+
+void QtTableView::clearTableFlags( uint f )
+{
+ f = (f ^ ~tFlags) & f; // clear flags that are already 0
+ tFlags &= ~f;
+
+ bool updateOn = autoUpdate();
+ setAutoUpdate( FALSE );
+
+ uint repaintMask = Tbl_cutCellsV | Tbl_cutCellsH;
+
+ if ( f & Tbl_vScrollBar ) {
+ setVerScrollBar( FALSE );
+ }
+ if ( f & Tbl_hScrollBar ) {
+ setHorScrollBar( FALSE );
+ }
+ if ( f & Tbl_scrollLastHCell ) {
+ int maxX = maxXOffset();
+ if ( xOffs > maxX ) {
+ setOffset( maxX, yOffs );
+ repaintMask |= Tbl_scrollLastHCell;
+ }
+ updateScrollBars( horRange );
+ }
+ if ( f & Tbl_scrollLastVCell ) {
+ int maxY = maxYOffset();
+ if ( yOffs > maxY ) {
+ setOffset( xOffs, maxY );
+ repaintMask |= Tbl_scrollLastVCell;
+ }
+ updateScrollBars( verRange );
+ }
+ if ( f & Tbl_smoothScrolling ) { // Note: checks for 2 flags
+ if ((f & Tbl_smoothHScrolling) != 0 && xCellDelta != 0 ||//must scroll?
+ (f & Tbl_smoothVScrolling) != 0 && yCellDelta != 0 ) {
+ snapToGrid( (f & Tbl_smoothHScrolling) != 0, // do snapping
+ (f & Tbl_smoothVScrolling) != 0 );
+ repaintMask |= Tbl_smoothScrolling; // repaint table
+ }
+ }
+ if ( f & Tbl_snapToHGrid ) {
+ updateScrollBars( horRange );
+ }
+ if ( f & Tbl_snapToVGrid ) {
+ updateScrollBars( verRange );
+ }
+ if ( updateOn ) {
+ setAutoUpdate( TRUE );
+ updateScrollBars(); // returns immediately if nothing to do
+ if ( isVisible() && (f & repaintMask) )
+ repaint();
+ }
+
+}
+
+
+/*!
+ \fn bool QtTableView::autoUpdate() const
+
+ Returns TRUE if the view updates itself automatically whenever it
+ is changed in some way.
+
+ \sa setAutoUpdate()
+*/
+
+/*!
+ Sets the auto-update option of the table view to \a enable.
+
+ If \a enable is TRUE (this is the default), the view updates itself
+ automatically whenever it has changed in some way (for example, when a
+ \link setTableFlags() flag\endlink is changed).
+
+ If \a enable is FALSE, the view does NOT repaint itself or update
+ its internal state variables when it is changed. This can be
+ useful to avoid flicker during large changes and is singularly
+ useless otherwise. Disable auto-update, do the changes, re-enable
+ auto-update and call repaint().
+
+ \warning Do not leave the view in this state for a long time
+ (i.e., between events). If, for example, the user interacts with the
+ view when auto-update is off, strange things can happen.
+
+ Setting auto-update to TRUE does not repaint the view; you must call
+ repaint() to do this.
+
+ \sa autoUpdate(), repaint()
+*/
+
+void QtTableView::setAutoUpdate( bool enable )
+{
+ if ( isUpdatesEnabled() == enable )
+ return;
+ setUpdatesEnabled( enable );
+ if ( enable ) {
+ showOrHideScrollBars();
+ updateScrollBars();
+ }
+}
+
+
+/*!
+ Repaints the cell at row \a row, column \a col if it is inside the view.
+
+ If \a erase is TRUE, the relevant part of the view is cleared to the
+ background color/pixmap before the contents are repainted.
+
+ \sa isVisible()
+*/
+
+void QtTableView::updateCell( int row, int col, bool erase )
+{
+ int xPos, yPos;
+ if ( !colXPos( col, &xPos ) )
+ return;
+ if ( !rowYPos( row, &yPos ) )
+ return;
+ QRect uR = QRect( xPos, yPos,
+ cellW ? cellW : cellWidth(col),
+ cellH ? cellH : cellHeight(row) );
+ repaint( uR.intersect(viewRect()), erase );
+}
+
+
+/*!
+ \fn QRect QtTableView::cellUpdateRect() const
+
+ This function should be called only from the paintCell() function in
+ subclasses. It returns the portion of a cell that actually needs to be
+ updated in \e cell coordinates. This is useful only for non-trivial
+ paintCell().
+
+*/
+
+/*!
+ Returns the rectangle that is the actual table, excluding any
+ frame, in \e widget coordinates.
+*/
+
+QRect QtTableView::viewRect() const
+{
+ return QRect( frameWidth(), frameWidth(), viewWidth(), viewHeight() );
+}
+
+
+/*!
+ Returns the index of the last (bottom) row in the view.
+ The index of the first row is 0.
+
+ If no rows are visible it returns -1. This can happen if the
+ view is too small for the first row and Tbl_cutCellsV is set.
+
+ \sa lastColVisible()
+*/
+
+int QtTableView::lastRowVisible() const
+{
+ int cellMaxY;
+ int row = findRawRow( maxViewY(), &cellMaxY );
+ if ( row == -1 || row >= nRows ) { // maxViewY() past end?
+ row = nRows - 1; // yes: return last row
+ } else {
+ if ( testTableFlags(Tbl_cutCellsV) && cellMaxY > maxViewY() ) {
+ if ( row == yCellOffs ) // cut by right margin?
+ return -1; // yes, nothing in the view
+ else
+ row = row - 1; // cut by margin, one back
+ }
+ }
+ return row;
+}
+
+/*!
+ Returns the index of the last (right) column in the view.
+ The index of the first column is 0.
+
+ If no columns are visible it returns -1. This can happen if the
+ view is too narrow for the first column and Tbl_cutCellsH is set.
+
+ \sa lastRowVisible()
+*/
+
+int QtTableView::lastColVisible() const
+{
+ int cellMaxX;
+ int col = findRawCol( maxViewX(), &cellMaxX );
+ if ( col == -1 || col >= nCols ) { // maxViewX() past end?
+ col = nCols - 1; // yes: return last col
+ } else {
+ if ( testTableFlags(Tbl_cutCellsH) && cellMaxX > maxViewX() ) {
+ if ( col == xCellOffs ) // cut by bottom margin?
+ return -1; // yes, nothing in the view
+ else
+ col = col - 1; // cell by margin, one back
+ }
+ }
+ return col;
+}
+
+/*!
+ Returns TRUE if \a row is at least partially visible.
+ \sa colIsVisible()
+*/
+
+bool QtTableView::rowIsVisible( int row ) const
+{
+ return rowYPos( row, 0 );
+}
+
+/*!
+ Returns TRUE if \a col is at least partially visible.
+ \sa rowIsVisible()
+*/
+
+bool QtTableView::colIsVisible( int col ) const
+{
+ return colXPos( col, 0 );
+}
+
+
+/*!
+ \internal
+ Called when both scroll bars are active at the same time. Covers the
+ bottom left corner between the two scroll bars with an empty widget.
+*/
+
+void QtTableView::coverCornerSquare( bool enable )
+{
+ coveringCornerSquare = enable;
+ if ( !cornerSquare && enable ) {
+ cornerSquare = new QCornerSquare( this );
+ Q_CHECK_PTR( cornerSquare );
+ cornerSquare->setGeometry( maxViewX() + frameWidth() + 1,
+ maxViewY() + frameWidth() + 1,
+ VSBEXT,
+ HSBEXT);
+ }
+ if ( autoUpdate() && cornerSquare ) {
+ if ( enable )
+ cornerSquare->show();
+ else
+ cornerSquare->hide();
+ }
+}
+
+
+/*!
+ \internal
+ Scroll the view to a position such that:
+
+ If \a horizontal is TRUE, the leftmost column shown fits snugly
+ with the left edge of the view.
+
+ If \a vertical is TRUE, the top row shown fits snugly with the top
+ of the view.
+
+ You can achieve the same effect automatically by setting any of the
+ \link setTableFlags() Tbl_snapTo*Grid \endlink table flags.
+*/
+
+void QtTableView::snapToGrid( bool horizontal, bool vertical )
+{
+ int newXCell = -1;
+ int newYCell = -1;
+ if ( horizontal && xCellDelta != 0 ) {
+ int w = cellW ? cellW : cellWidth( xCellOffs );
+ if ( xCellDelta >= w/2 )
+ newXCell = xCellOffs + 1;
+ else
+ newXCell = xCellOffs;
+ }
+ if ( vertical && yCellDelta != 0 ) {
+ int h = cellH ? cellH : cellHeight( yCellOffs );
+ if ( yCellDelta >= h/2 )
+ newYCell = yCellOffs + 1;
+ else
+ newYCell = yCellOffs;
+ }
+ setTopLeftCell( newYCell, newXCell ); //row,column
+}
+
+/*!
+ \internal
+ This internal slot is connected to the horizontal scroll bar's
+ QScrollBar::valueChanged() signal.
+
+ Moves the table horizontally to offset \a val without updating the
+ scroll bar.
+*/
+
+void QtTableView::horSbValue( int val )
+{
+ if ( horSliding ) {
+ horSliding = FALSE;
+ if ( horSnappingOff ) {
+ horSnappingOff = FALSE;
+ tFlags |= Tbl_snapToHGrid;
+ }
+ }
+ setOffset( val, yOffs, FALSE );
+}
+
+/*!
+ \internal
+ This internal slot is connected to the horizontal scroll bar's
+ QScrollBar::sliderMoved() signal.
+
+ Scrolls the table smoothly horizontally even if \c Tbl_snapToHGrid is set.
+*/
+
+void QtTableView::horSbSliding( int val )
+{
+ if ( testTableFlags(Tbl_snapToHGrid) &&
+ testTableFlags(Tbl_smoothHScrolling) ) {
+ tFlags &= ~Tbl_snapToHGrid; // turn off snapping while sliding
+ setOffset( val, yOffs, FALSE );
+ tFlags |= Tbl_snapToHGrid; // turn on snapping again
+ } else {
+ setOffset( val, yOffs, FALSE );
+ }
+}
+
+/*!
+ \internal
+ This internal slot is connected to the horizontal scroll bar's
+ QScrollBar::sliderReleased() signal.
+*/
+
+void QtTableView::horSbSlidingDone( )
+{
+ if ( testTableFlags(Tbl_snapToHGrid) &&
+ testTableFlags(Tbl_smoothHScrolling) )
+ snapToGrid( TRUE, FALSE );
+}
+
+/*!
+ \internal
+ This internal slot is connected to the vertical scroll bar's
+ QScrollBar::valueChanged() signal.
+
+ Moves the table vertically to offset \a val without updating the
+ scroll bar.
+*/
+
+void QtTableView::verSbValue( int val )
+{
+ if ( verSliding ) {
+ verSliding = FALSE;
+ if ( verSnappingOff ) {
+ verSnappingOff = FALSE;
+ tFlags |= Tbl_snapToVGrid;
+ }
+ }
+ setOffset( xOffs, val, FALSE );
+}
+
+/*!
+ \internal
+ This internal slot is connected to the vertical scroll bar's
+ QScrollBar::sliderMoved() signal.
+
+ Scrolls the table smoothly vertically even if \c Tbl_snapToVGrid is set.
+*/
+
+void QtTableView::verSbSliding( int val )
+{
+ if ( testTableFlags(Tbl_snapToVGrid) &&
+ testTableFlags(Tbl_smoothVScrolling) ) {
+ tFlags &= ~Tbl_snapToVGrid; // turn off snapping while sliding
+ setOffset( xOffs, val, FALSE );
+ tFlags |= Tbl_snapToVGrid; // turn on snapping again
+ } else {
+ setOffset( xOffs, val, FALSE );
+ }
+}
+
+/*!
+ \internal
+ This internal slot is connected to the vertical scroll bar's
+ QScrollBar::sliderReleased() signal.
+*/
+
+void QtTableView::verSbSlidingDone( )
+{
+ if ( testTableFlags(Tbl_snapToVGrid) &&
+ testTableFlags(Tbl_smoothVScrolling) )
+ snapToGrid( FALSE, TRUE );
+}
+
+
+/*!
+ This virtual function is called before painting of table cells
+ is started. It can be reimplemented by subclasses that want to
+ to set up the painter in a special way and that do not want to
+ do so for each cell.
+*/
+
+void QtTableView::setupPainter( QPainter * )
+{
+}
+
+/*!
+ \fn void QtTableView::paintCell( QPainter *p, int row, int col )
+
+ This pure virtual function is called to paint the single cell at \a
+ (row,col) using \a p, which is open when paintCell() is called and
+ must remain open.
+
+ The coordinate system is \link QPainter::translate() translated \endlink
+ so that the origin is at the top-left corner of the cell to be
+ painted, i.e. \e cell coordinates. Do not scale or shear the coordinate
+ system (or if you do, restore the transformation matrix before you
+ return).
+
+ The painter is not clipped by default and for maximum efficiency. For safety,
+ call setTableFlags(Tbl_clipCellPainting) to enable clipping.
+
+ \sa paintEvent(), setTableFlags() */
+
+
+/*!
+ Handles paint events, \a e, for the table view.
+
+ Calls paintCell() for the cells that needs to be repainted.
+*/
+
+void QtTableView::paintEvent( QPaintEvent *e )
+{
+ QRect updateR = e->rect(); // update rectangle
+ if ( sbDirty ) {
+ bool e = eraseInPaint;
+ updateScrollBars();
+ eraseInPaint = e;
+ }
+
+ QPainter paint( this );
+
+ if ( !contentsRect().contains( updateR, TRUE ) ) {// update frame ?
+ drawFrame( &paint );
+ if ( updateR.left() < frameWidth() ) //###
+ updateR.setLeft( frameWidth() );
+ if ( updateR.top() < frameWidth() )
+ updateR.setTop( frameWidth() );
+ }
+
+ int maxWX = maxViewX();
+ int maxWY = maxViewY();
+ if ( updateR.right() > maxWX )
+ updateR.setRight( maxWX );
+ if ( updateR.bottom() > maxWY )
+ updateR.setBottom( maxWY );
+
+ setupPainter( &paint ); // prepare for painting table
+
+ int firstRow = findRow( updateR.y() );
+ int firstCol = findCol( updateR.x() );
+ int xStart, yStart;
+ if ( !colXPos( firstCol, &xStart ) || !rowYPos( firstRow, &yStart ) ) {
+ paint.eraseRect( updateR ); // erase area outside cells but in view
+ return;
+ }
+ int maxX = updateR.right();
+ int maxY = updateR.bottom();
+ int row = firstRow;
+ int col;
+ int yPos = yStart;
+ int xPos = maxX+1; // in case the while() is empty
+ int nextX;
+ int nextY;
+ QRect winR = viewRect();
+ QRect cellR;
+ QRect cellUR;
+#ifndef QT_NO_TRANSFORMATIONS
+ QWMatrix matrix;
+#endif
+
+ while ( yPos <= maxY && row < nRows ) {
+ nextY = yPos + (cellH ? cellH : cellHeight( row ));
+ if ( testTableFlags( Tbl_cutCellsV ) && nextY > ( maxWY + 1 ) )
+ break;
+ col = firstCol;
+ xPos = xStart;
+ while ( xPos <= maxX && col < nCols ) {
+ nextX = xPos + (cellW ? cellW : cellWidth( col ));
+ if ( testTableFlags( Tbl_cutCellsH ) && nextX > ( maxWX + 1 ) )
+ break;
+
+ cellR.setRect( xPos, yPos, cellW ? cellW : cellWidth(col),
+ cellH ? cellH : cellHeight(row) );
+ cellUR = cellR.intersect( updateR );
+ if ( cellUR.isValid() ) {
+ cellUpdateR = cellUR;
+ cellUpdateR.moveBy( -xPos, -yPos ); // cell coordinates
+ if ( eraseInPaint )
+ paint.eraseRect( cellUR );
+
+#ifndef QT_NO_TRANSFORMATIONS
+ matrix.translate( xPos, yPos );
+ paint.setWorldMatrix( matrix );
+ if ( testTableFlags(Tbl_clipCellPainting) ||
+ frameWidth() > 0 && !winR.contains( cellR ) ) { //##arnt
+ paint.setClipRect( cellUR );
+ paintCell( &paint, row, col );
+ paint.setClipping( FALSE );
+ } else {
+ paintCell( &paint, row, col );
+ }
+ matrix.reset();
+ paint.setWorldMatrix( matrix );
+#else
+ paint.translate( xPos, yPos );
+ if ( testTableFlags(Tbl_clipCellPainting) ||
+ frameWidth() > 0 && !winR.contains( cellR ) ) { //##arnt
+ paint.setClipRect( cellUR );
+ paintCell( &paint, row, col );
+ paint.setClipping( FALSE );
+ } else {
+ paintCell( &paint, row, col );
+ }
+ paint.translate( -xPos, -yPos );
+#endif
+ }
+ col++;
+ xPos = nextX;
+ }
+ row++;
+ yPos = nextY;
+ }
+
+ // while painting we have to erase any areas in the view that
+ // are not covered by cells but are covered by the paint event
+ // rectangle these must be erased. We know that xPos is the last
+ // x pixel updated + 1 and that yPos is the last y pixel updated + 1.
+
+ // Note that this needs to be done regardless whether we do
+ // eraseInPaint or not. Reason: a subclass may implement
+ // flicker-freeness and encourage the use of repaint(FALSE).
+ // The subclass, however, cannot draw all pixels, just those
+ // inside the cells. So QtTableView is reponsible for all pixels
+ // outside the cells.
+
+ QRect viewR = viewRect();
+ const QColorGroup g = colorGroup();
+
+ if ( xPos <= maxX ) {
+ QRect r = viewR;
+ r.setLeft( xPos );
+ r.setBottom( yPos<maxY?yPos:maxY );
+ if ( inherits( "QMultiLineEdit" ) )
+ paint.fillRect( r.intersect( updateR ), g.base() );
+ else
+ paint.eraseRect( r.intersect( updateR ) );
+ }
+ if ( yPos <= maxY ) {
+ QRect r = viewR;
+ r.setTop( yPos );
+ if ( inherits( "QMultiLineEdit" ) )
+ paint.fillRect( r.intersect( updateR ), g.base() );
+ else
+ paint.eraseRect( r.intersect( updateR ) );
+ }
+}
+
+/*!\reimp
+*/
+void QtTableView::resizeEvent( QResizeEvent * )
+{
+ updateScrollBars( horValue | verValue | horSteps | horGeometry | horRange |
+ verSteps | verGeometry | verRange );
+ showOrHideScrollBars();
+ updateFrameSize();
+ int maxX = QMIN( xOffs, maxXOffset() ); // ### can be slow
+ int maxY = QMIN( yOffs, maxYOffset() );
+ setOffset( maxX, maxY );
+}
+
+
+/*!
+ Redraws all visible cells in the table view.
+*/
+
+void QtTableView::updateView()
+{
+ repaint( viewRect() );
+}
+
+/*!
+ Returns a pointer to the vertical scroll bar mainly so you can
+ connect() to its signals. Note that the scroll bar works in pixel
+ values; use findRow() to translate to cell numbers.
+*/
+
+QScrollBar *QtTableView::verticalScrollBar() const
+{
+ QtTableView *that = (QtTableView*)this; // semantic const
+ if ( !vScrollBar ) {
+ QScrollBar *sb = new QScrollBar( QScrollBar::Vertical, that );
+#ifndef QT_NO_CURSOR
+ sb->setCursor( arrowCursor );
+#endif
+ sb->resize( sb->sizeHint() ); // height is irrelevant
+ Q_CHECK_PTR(sb);
+ sb->setTracking( FALSE );
+ sb->setFocusPolicy( NoFocus );
+ connect( sb, SIGNAL(valueChanged(int)),
+ SLOT(verSbValue(int)));
+ connect( sb, SIGNAL(sliderMoved(int)),
+ SLOT(verSbSliding(int)));
+ connect( sb, SIGNAL(sliderReleased()),
+ SLOT(verSbSlidingDone()));
+ sb->hide();
+ that->vScrollBar = sb;
+ return sb;
+ }
+ return vScrollBar;
+}
+
+/*!
+ Returns a pointer to the horizontal scroll bar mainly so you can
+ connect() to its signals. Note that the scroll bar works in pixel
+ values; use findCol() to translate to cell numbers.
+*/
+
+QScrollBar *QtTableView::horizontalScrollBar() const
+{
+ QtTableView *that = (QtTableView*)this; // semantic const
+ if ( !hScrollBar ) {
+ QScrollBar *sb = new QScrollBar( QScrollBar::Horizontal, that );
+#ifndef QT_NO_CURSOR
+ sb->setCursor( arrowCursor );
+#endif
+ sb->resize( sb->sizeHint() ); // width is irrelevant
+ sb->setFocusPolicy( NoFocus );
+ Q_CHECK_PTR(sb);
+ sb->setTracking( FALSE );
+ connect( sb, SIGNAL(valueChanged(int)),
+ SLOT(horSbValue(int)));
+ connect( sb, SIGNAL(sliderMoved(int)),
+ SLOT(horSbSliding(int)));
+ connect( sb, SIGNAL(sliderReleased()),
+ SLOT(horSbSlidingDone()));
+ sb->hide();
+ that->hScrollBar = sb;
+ return sb;
+ }
+ return hScrollBar;
+}
+
+/*!
+ Enables or disables the horizontal scroll bar, as required by
+ setAutoUpdate() and the \link setTableFlags() table flags\endlink.
+*/
+
+void QtTableView::setHorScrollBar( bool on, bool update )
+{
+ if ( on ) {
+ tFlags |= Tbl_hScrollBar;
+ horizontalScrollBar(); // created
+ if ( update )
+ updateScrollBars( horMask | verMask );
+ else
+ sbDirty = sbDirty | (horMask | verMask);
+ if ( testTableFlags( Tbl_vScrollBar ) )
+ coverCornerSquare( TRUE );
+ if ( autoUpdate() )
+ sbDirty = sbDirty | horMask;
+ } else {
+ tFlags &= ~Tbl_hScrollBar;
+ if ( !hScrollBar )
+ return;
+ coverCornerSquare( FALSE );
+ bool hideScrollBar = autoUpdate() && hScrollBar->isVisible();
+ if ( hideScrollBar )
+ hScrollBar->hide();
+ if ( update )
+ updateScrollBars( verMask );
+ else
+ sbDirty = sbDirty | verMask;
+ if ( hideScrollBar && isVisible() )
+ repaint( hScrollBar->x(), hScrollBar->y(),
+ width() - hScrollBar->x(), hScrollBar->height() );
+ }
+ if ( update )
+ updateFrameSize();
+}
+
+
+/*!
+ Enables or disables the vertical scroll bar, as required by
+ setAutoUpdate() and the \link setTableFlags() table flags\endlink.
+*/
+
+void QtTableView::setVerScrollBar( bool on, bool update )
+{
+ if ( on ) {
+ tFlags |= Tbl_vScrollBar;
+ verticalScrollBar(); // created
+ if ( update )
+ updateScrollBars( verMask | horMask );
+ else
+ sbDirty = sbDirty | (horMask | verMask);
+ if ( testTableFlags( Tbl_hScrollBar ) )
+ coverCornerSquare( TRUE );
+ if ( autoUpdate() )
+ sbDirty = sbDirty | verMask;
+ } else {
+ tFlags &= ~Tbl_vScrollBar;
+ if ( !vScrollBar )
+ return;
+ coverCornerSquare( FALSE );
+ bool hideScrollBar = autoUpdate() && vScrollBar->isVisible();
+ if ( hideScrollBar )
+ vScrollBar->hide();
+ if ( update )
+ updateScrollBars( horMask );
+ else
+ sbDirty = sbDirty | horMask;
+ if ( hideScrollBar && isVisible() )
+ repaint( vScrollBar->x(), vScrollBar->y(),
+ vScrollBar->width(), height() - vScrollBar->y() );
+ }
+ if ( update )
+ updateFrameSize();
+}
+
+
+
+
+int QtTableView::findRawRow( int yPos, int *cellMaxY, int *cellMinY,
+ bool goOutsideView ) const
+{
+ int r = -1;
+ if ( nRows == 0 )
+ return r;
+ if ( goOutsideView || yPos >= minViewY() && yPos <= maxViewY() ) {
+ if ( yPos < minViewY() ) {
+#if defined(QT_CHECK_RANGE)
+ qWarning( "QtTableView::findRawRow: (%s) internal error: "
+ "yPos < minViewY() && goOutsideView "
+ "not supported. (%d,%d)",
+ name( "unnamed" ), yPos, yOffs );
+#endif
+ return -1;
+ }
+ if ( cellH ) { // uniform cell height
+ r = (yPos - minViewY() + yCellDelta)/cellH; // cell offs from top
+ if ( cellMaxY )
+ *cellMaxY = (r + 1)*cellH + minViewY() - yCellDelta - 1;
+ if ( cellMinY )
+ *cellMinY = r*cellH + minViewY() - yCellDelta;
+ r += yCellOffs; // absolute cell index
+ } else { // variable cell height
+ QtTableView *tw = (QtTableView *)this;
+ r = yCellOffs;
+ int h = minViewY() - yCellDelta; //##arnt3
+ int oldH = h;
+ Q_ASSERT( r < nRows );
+ while ( r < nRows ) {
+ oldH = h;
+ h += tw->cellHeight( r ); // Start of next cell
+ if ( yPos < h )
+ break;
+ r++;
+ }
+ if ( cellMaxY )
+ *cellMaxY = h - 1;
+ if ( cellMinY )
+ *cellMinY = oldH;
+ }
+ }
+ return r;
+
+}
+
+
+int QtTableView::findRawCol( int xPos, int *cellMaxX, int *cellMinX ,
+ bool goOutsideView ) const
+{
+ int c = -1;
+ if ( nCols == 0 )
+ return c;
+ if ( goOutsideView || xPos >= minViewX() && xPos <= maxViewX() ) {
+ if ( xPos < minViewX() ) {
+#if defined(QT_CHECK_RANGE)
+ qWarning( "QtTableView::findRawCol: (%s) internal error: "
+ "xPos < minViewX() && goOutsideView "
+ "not supported. (%d,%d)",
+ name( "unnamed" ), xPos, xOffs );
+#endif
+ return -1;
+ }
+ if ( cellW ) { // uniform cell width
+ c = (xPos - minViewX() + xCellDelta)/cellW; //cell offs from left
+ if ( cellMaxX )
+ *cellMaxX = (c + 1)*cellW + minViewX() - xCellDelta - 1;
+ if ( cellMinX )
+ *cellMinX = c*cellW + minViewX() - xCellDelta;
+ c += xCellOffs; // absolute cell index
+ } else { // variable cell width
+ QtTableView *tw = (QtTableView *)this;
+ c = xCellOffs;
+ int w = minViewX() - xCellDelta; //##arnt3
+ int oldW = w;
+ Q_ASSERT( c < nCols );
+ while ( c < nCols ) {
+ oldW = w;
+ w += tw->cellWidth( c ); // Start of next cell
+ if ( xPos < w )
+ break;
+ c++;
+ }
+ if ( cellMaxX )
+ *cellMaxX = w - 1;
+ if ( cellMinX )
+ *cellMinX = oldW;
+ }
+ }
+ return c;
+}
+
+
+/*!
+ Returns the index of the row at position \a yPos, where \a yPos is in
+ \e widget coordinates. Returns -1 if \a yPos is outside the valid
+ range.
+
+ \sa findCol(), rowYPos()
+*/
+
+int QtTableView::findRow( int yPos ) const
+{
+ int cellMaxY;
+ int row = findRawRow( yPos, &cellMaxY );
+ if ( testTableFlags(Tbl_cutCellsV) && cellMaxY > maxViewY() )
+ row = - 1; // cell cut by bottom margin
+ if ( row >= nRows )
+ row = -1;
+ return row;
+}
+
+
+/*!
+ Returns the index of the column at position \a xPos, where \a xPos is
+ in \e widget coordinates. Returns -1 if \a xPos is outside the valid
+ range.
+
+ \sa findRow(), colXPos()
+*/
+
+int QtTableView::findCol( int xPos ) const
+{
+ int cellMaxX;
+ int col = findRawCol( xPos, &cellMaxX );
+ if ( testTableFlags(Tbl_cutCellsH) && cellMaxX > maxViewX() )
+ col = - 1; // cell cut by right margin
+ if ( col >= nCols )
+ col = -1;
+ return col;
+}
+
+
+/*!
+ Computes the position in the widget of row \a row.
+
+ Returns TRUE and stores the result in \a *yPos (in \e widget
+ coordinates) if the row is visible. Returns FALSE and does not modify
+ \a *yPos if \a row is invisible or invalid.
+
+ \sa colXPos(), findRow()
+*/
+
+bool QtTableView::rowYPos( int row, int *yPos ) const
+{
+ int y;
+ if ( row >= yCellOffs ) {
+ if ( cellH ) {
+ int lastVisible = lastRowVisible();
+ if ( row > lastVisible || lastVisible == -1 )
+ return FALSE;
+ y = (row - yCellOffs)*cellH + minViewY() - yCellDelta;
+ } else {
+ //##arnt3
+ y = minViewY() - yCellDelta; // y of leftmost cell in view
+ int r = yCellOffs;
+ QtTableView *tw = (QtTableView *)this;
+ int maxY = maxViewY();
+ while ( r < row && y <= maxY )
+ y += tw->cellHeight( r++ );
+ if ( y > maxY )
+ return FALSE;
+
+ }
+ } else {
+ return FALSE;
+ }
+ if ( yPos )
+ *yPos = y;
+ return TRUE;
+}
+
+
+/*!
+ Computes the position in the widget of column \a col.
+
+ Returns TRUE and stores the result in \a *xPos (in \e widget
+ coordinates) if the column is visible. Returns FALSE and does not
+ modify \a *xPos if \a col is invisible or invalid.
+
+ \sa rowYPos(), findCol()
+*/
+
+bool QtTableView::colXPos( int col, int *xPos ) const
+{
+ int x;
+ if ( col >= xCellOffs ) {
+ if ( cellW ) {
+ int lastVisible = lastColVisible();
+ if ( col > lastVisible || lastVisible == -1 )
+ return FALSE;
+ x = (col - xCellOffs)*cellW + minViewX() - xCellDelta;
+ } else {
+ //##arnt3
+ x = minViewX() - xCellDelta; // x of uppermost cell in view
+ int c = xCellOffs;
+ QtTableView *tw = (QtTableView *)this;
+ int maxX = maxViewX();
+ while ( c < col && x <= maxX )
+ x += tw->cellWidth( c++ );
+ if ( x > maxX )
+ return FALSE;
+ }
+ } else {
+ return FALSE;
+ }
+ if ( xPos )
+ *xPos = x;
+ return TRUE;
+}
+
+
+/*!
+ Moves the visible area of the table right by \a xPixels and
+ down by \a yPixels pixels. Both may be negative.
+
+ \warning You might find that QScrollView offers a higher-level of
+ functionality than using QtTableView and this function.
+
+ This function is \e not the same as QWidget::scroll(); in particular,
+ the signs of \a xPixels and \a yPixels have the reverse semantics.
+
+ \sa setXOffset(), setYOffset(), setOffset(), setTopCell(),
+ setLeftCell()
+*/
+
+void QtTableView::scroll( int xPixels, int yPixels )
+{
+ QWidget::scroll( -xPixels, -yPixels, contentsRect() );
+}
+
+
+/*!
+ Returns the leftmost pixel of the table view in \e view
+ coordinates. This excludes the frame and any header.
+
+ \sa maxViewY(), viewWidth(), contentsRect()
+*/
+
+int QtTableView::minViewX() const
+{
+ return frameWidth();
+}
+
+
+/*!
+ Returns the top pixel of the table view in \e view
+ coordinates. This excludes the frame and any header.
+
+ \sa maxViewX(), viewHeight(), contentsRect()
+*/
+
+int QtTableView::minViewY() const
+{
+ return frameWidth();
+}
+
+
+/*!
+ Returns the rightmost pixel of the table view in \e view
+ coordinates. This excludes the frame and any scroll bar, but
+ includes blank pixels to the right of the visible table data.
+
+ \sa maxViewY(), viewWidth(), contentsRect()
+*/
+
+int QtTableView::maxViewX() const
+{
+ return width() - 1 - frameWidth()
+ - (tFlags & Tbl_vScrollBar ? VSBEXT
+ : 0);
+}
+
+
+/*!
+ Returns the bottom pixel of the table view in \e view
+ coordinates. This excludes the frame and any scroll bar, but
+ includes blank pixels below the visible table data.
+
+ \sa maxViewX(), viewHeight(), contentsRect()
+*/
+
+int QtTableView::maxViewY() const
+{
+ return height() - 1 - frameWidth()
+ - (tFlags & Tbl_hScrollBar ? HSBEXT
+ : 0);
+}
+
+
+/*!
+ Returns the width of the table view, as such, in \e view
+ coordinates. This does not include any header, scroll bar or frame,
+ but it does include background pixels to the right of the table data.
+
+ \sa minViewX() maxViewX(), viewHeight(), contentsRect() viewRect()
+*/
+
+int QtTableView::viewWidth() const
+{
+ return maxViewX() - minViewX() + 1;
+}
+
+
+/*!
+ Returns the height of the table view, as such, in \e view
+ coordinates. This does not include any header, scroll bar or frame,
+ but it does include background pixels below the table data.
+
+ \sa minViewY() maxViewY() viewWidth() contentsRect() viewRect()
+*/
+
+int QtTableView::viewHeight() const
+{
+ return maxViewY() - minViewY() + 1;
+}
+
+
+void QtTableView::doAutoScrollBars()
+{
+ int viewW = width() - frameWidth() - minViewX();
+ int viewH = height() - frameWidth() - minViewY();
+ bool vScrollOn = testTableFlags(Tbl_vScrollBar);
+ bool hScrollOn = testTableFlags(Tbl_hScrollBar);
+ int w = 0;
+ int h = 0;
+ int i;
+
+ if ( testTableFlags(Tbl_autoHScrollBar) ) {
+ if ( cellW ) {
+ w = cellW*nCols;
+ } else {
+ i = 0;
+ while ( i < nCols && w <= viewW )
+ w += cellWidth( i++ );
+ }
+ if ( w > viewW )
+ hScrollOn = TRUE;
+ else
+ hScrollOn = FALSE;
+ }
+
+ if ( testTableFlags(Tbl_autoVScrollBar) ) {
+ if ( cellH ) {
+ h = cellH*nRows;
+ } else {
+ i = 0;
+ while ( i < nRows && h <= viewH )
+ h += cellHeight( i++ );
+ }
+
+ if ( h > viewH )
+ vScrollOn = TRUE;
+ else
+ vScrollOn = FALSE;
+ }
+
+ if ( testTableFlags(Tbl_autoHScrollBar) && vScrollOn && !hScrollOn )
+ if ( w > viewW - VSBEXT )
+ hScrollOn = TRUE;
+
+ if ( testTableFlags(Tbl_autoVScrollBar) && hScrollOn && !vScrollOn )
+ if ( h > viewH - HSBEXT )
+ vScrollOn = TRUE;
+
+ setHorScrollBar( hScrollOn, FALSE );
+ setVerScrollBar( vScrollOn, FALSE );
+ updateFrameSize();
+}
+
+
+/*!
+ \fn void QtTableView::updateScrollBars()
+
+ Updates the scroll bars' contents and presence to match the table's
+ state. Generally, you should not need to call this.
+
+ \sa setTableFlags()
+*/
+
+/*!
+ Updates the scroll bars' contents and presence to match the table's
+ state \c or \a f.
+
+ \sa setTableFlags()
+*/
+
+void QtTableView::updateScrollBars( uint f )
+{
+ sbDirty = sbDirty | f;
+ if ( inSbUpdate )
+ return;
+ inSbUpdate = TRUE;
+
+ if ( testTableFlags(Tbl_autoHScrollBar) && (sbDirty & horRange) ||
+ testTableFlags(Tbl_autoVScrollBar) && (sbDirty & verRange) )
+ // if range change and auto
+ doAutoScrollBars(); // turn scroll bars on/off if needed
+
+ if ( !autoUpdate() ) {
+ inSbUpdate = FALSE;
+ return;
+ }
+ if ( yOffset() > 0 && testTableFlags( Tbl_autoVScrollBar ) &&
+ !testTableFlags( Tbl_vScrollBar ) ) {
+ setYOffset( 0 );
+ }
+ if ( xOffset() > 0 && testTableFlags( Tbl_autoHScrollBar ) &&
+ !testTableFlags( Tbl_hScrollBar ) ) {
+ setXOffset( 0 );
+ }
+ if ( !isVisible() ) {
+ inSbUpdate = FALSE;
+ return;
+ }
+
+ if ( testTableFlags(Tbl_hScrollBar) && (sbDirty & horMask) != 0 ) {
+ if ( sbDirty & horGeometry )
+ hScrollBar->setGeometry( 0,height() - HSBEXT,
+ viewWidth() + frameWidth()*2,
+ HSBEXT);
+
+ if ( sbDirty & horSteps ) {
+ if ( cellW )
+ hScrollBar->setSteps( QMIN(cellW,viewWidth()/2), viewWidth() );
+ else
+ hScrollBar->setSteps( 16, viewWidth() );
+ }
+
+ if ( sbDirty & horRange )
+ hScrollBar->setRange( 0, maxXOffset() );
+
+ if ( sbDirty & horValue )
+ hScrollBar->setValue( xOffs );
+
+ // show scrollbar only when it has a sane geometry
+ if ( !hScrollBar->isVisible() )
+ hScrollBar->show();
+ }
+
+ if ( testTableFlags(Tbl_vScrollBar) && (sbDirty & verMask) != 0 ) {
+ if ( sbDirty & verGeometry )
+ vScrollBar->setGeometry( width() - VSBEXT, 0,
+ VSBEXT,
+ viewHeight() + frameWidth()*2 );
+
+ if ( sbDirty & verSteps ) {
+ if ( cellH )
+ vScrollBar->setSteps( QMIN(cellH,viewHeight()/2), viewHeight() );
+ else
+ vScrollBar->setSteps( 16, viewHeight() ); // fttb! ###
+ }
+
+ if ( sbDirty & verRange )
+ vScrollBar->setRange( 0, maxYOffset() );
+
+ if ( sbDirty & verValue )
+ vScrollBar->setValue( yOffs );
+
+ // show scrollbar only when it has a sane geometry
+ if ( !vScrollBar->isVisible() )
+ vScrollBar->show();
+ }
+ if ( coveringCornerSquare &&
+ ( (sbDirty & verGeometry ) || (sbDirty & horGeometry)) )
+ cornerSquare->move( maxViewX() + frameWidth() + 1,
+ maxViewY() + frameWidth() + 1 );
+
+ sbDirty = 0;
+ inSbUpdate = FALSE;
+}
+
+
+void QtTableView::updateFrameSize()
+{
+ int rw = width() - ( testTableFlags(Tbl_vScrollBar) ?
+ VSBEXT : 0 );
+ int rh = height() - ( testTableFlags(Tbl_hScrollBar) ?
+ HSBEXT : 0 );
+ if ( rw < 0 )
+ rw = 0;
+ if ( rh < 0 )
+ rh = 0;
+
+ if ( autoUpdate() ) {
+ int fh = frameRect().height();
+ int fw = frameRect().width();
+ setFrameRect( QRect(0,0,rw,rh) );
+
+ if ( rw != fw )
+ update( QMIN(fw,rw) - frameWidth() - 2, 0, frameWidth()+4, rh );
+ if ( rh != fh )
+ update( 0, QMIN(fh,rh) - frameWidth() - 2, rw, frameWidth()+4 );
+ }
+}
+
+
+/*!
+ Returns the maximum horizontal offset within the table of the
+ view's left edge in \e table coordinates.
+
+ This is used mainly to set the horizontal scroll bar's range.
+
+ \sa maxColOffset(), maxYOffset(), totalWidth()
+*/
+
+int QtTableView::maxXOffset()
+{
+ int tw = totalWidth();
+ int maxOffs;
+ if ( testTableFlags(Tbl_scrollLastHCell) ) {
+ if ( nCols != 1)
+ maxOffs = tw - ( cellW ? cellW : cellWidth( nCols - 1 ) );
+ else
+ maxOffs = tw - viewWidth();
+ } else {
+ if ( testTableFlags(Tbl_snapToHGrid) ) {
+ if ( cellW ) {
+ maxOffs = tw - (viewWidth()/cellW)*cellW;
+ } else {
+ int goal = tw - viewWidth();
+ int pos = tw;
+ int nextCol = nCols - 1;
+ int nextCellWidth = cellWidth( nextCol );
+ while( nextCol > 0 && pos > goal + nextCellWidth ) {
+ pos -= nextCellWidth;
+ nextCellWidth = cellWidth( --nextCol );
+ }
+ if ( goal + nextCellWidth == pos )
+ maxOffs = goal;
+ else if ( goal < pos )
+ maxOffs = pos;
+ else
+ maxOffs = 0;
+ }
+ } else {
+ maxOffs = tw - viewWidth();
+ }
+ }
+ return maxOffs > 0 ? maxOffs : 0;
+}
+
+
+/*!
+ Returns the maximum vertical offset within the table of the
+ view's top edge in \e table coordinates.
+
+ This is used mainly to set the vertical scroll bar's range.
+
+ \sa maxRowOffset(), maxXOffset(), totalHeight()
+*/
+
+int QtTableView::maxYOffset()
+{
+ int th = totalHeight();
+ int maxOffs;
+ if ( testTableFlags(Tbl_scrollLastVCell) ) {
+ if ( nRows != 1)
+ maxOffs = th - ( cellH ? cellH : cellHeight( nRows - 1 ) );
+ else
+ maxOffs = th - viewHeight();
+ } else {
+ if ( testTableFlags(Tbl_snapToVGrid) ) {
+ if ( cellH ) {
+ maxOffs = th - (viewHeight()/cellH)*cellH;
+ } else {
+ int goal = th - viewHeight();
+ int pos = th;
+ int nextRow = nRows - 1;
+ int nextCellHeight = cellHeight( nextRow );
+ while( nextRow > 0 && pos > goal + nextCellHeight ) {
+ pos -= nextCellHeight;
+ nextCellHeight = cellHeight( --nextRow );
+ }
+ if ( goal + nextCellHeight == pos )
+ maxOffs = goal;
+ else if ( goal < pos )
+ maxOffs = pos;
+ else
+ maxOffs = 0;
+ }
+ } else {
+ maxOffs = th - viewHeight();
+ }
+ }
+ return maxOffs > 0 ? maxOffs : 0;
+}
+
+
+/*!
+ Returns the index of the last column, which may be at the left edge
+ of the view.
+
+ Depending on the \link setTableFlags() Tbl_scrollLastHCell\endlink flag,
+ this may or may not be the last column.
+
+ \sa maxXOffset(), maxRowOffset()
+*/
+
+int QtTableView::maxColOffset()
+{
+ int mx = maxXOffset();
+ if ( cellW )
+ return mx/cellW;
+ else {
+ int xcd=0, col=0;
+ while ( col < nCols && mx > (xcd=cellWidth(col)) ) {
+ mx -= xcd;
+ col++;
+ }
+ return col;
+ }
+}
+
+
+/*!
+ Returns the index of the last row, which may be at the top edge of
+ the view.
+
+ Depending on the \link setTableFlags() Tbl_scrollLastVCell\endlink flag,
+ this may or may not be the last row.
+
+ \sa maxYOffset(), maxColOffset()
+*/
+
+int QtTableView::maxRowOffset()
+{
+ int my = maxYOffset();
+ if ( cellH )
+ return my/cellH;
+ else {
+ int ycd=0, row=0;
+ while ( row < nRows && my > (ycd=cellHeight(row)) ) {
+ my -= ycd;
+ row++;
+ }
+ return row;
+ }
+}
+
+
+void QtTableView::showOrHideScrollBars()
+{
+ if ( !autoUpdate() )
+ return;
+ if ( vScrollBar ) {
+ if ( testTableFlags(Tbl_vScrollBar) ) {
+ if ( !vScrollBar->isVisible() )
+ sbDirty = sbDirty | verMask;
+ } else {
+ if ( vScrollBar->isVisible() )
+ vScrollBar->hide();
+ }
+ }
+ if ( hScrollBar ) {
+ if ( testTableFlags(Tbl_hScrollBar) ) {
+ if ( !hScrollBar->isVisible() )
+ sbDirty = sbDirty | horMask;
+ } else {
+ if ( hScrollBar->isVisible() )
+ hScrollBar->hide();
+ }
+ }
+ if ( cornerSquare ) {
+ if ( testTableFlags(Tbl_hScrollBar) &&
+ testTableFlags(Tbl_vScrollBar) ) {
+ if ( !cornerSquare->isVisible() )
+ cornerSquare->show();
+ } else {
+ if ( cornerSquare->isVisible() )
+ cornerSquare->hide();
+ }
+ }
+}
+
+
+/*!
+ Updates the scroll bars and internal state.
+
+ Call this function when the table view's total size is changed;
+ typically because the result of cellHeight() or cellWidth() have changed.
+
+ This function does not repaint the widget.
+*/
+
+void QtTableView::updateTableSize()
+{
+ bool updateOn = autoUpdate();
+ setAutoUpdate( FALSE );
+ int xofs = xOffset();
+ xOffs++; //so that setOffset will not return immediately
+ setOffset(xofs,yOffset(),FALSE); //to calculate internal state correctly
+ setAutoUpdate(updateOn);
+
+ updateScrollBars( horSteps | horRange |
+ verSteps | verRange );
+ showOrHideScrollBars();
+}
+
+
+#endif
diff --git a/arts/builder/qttableview.h b/arts/builder/qttableview.h
new file mode 100644
index 00000000..c5a540dd
--- /dev/null
+++ b/arts/builder/qttableview.h
@@ -0,0 +1,251 @@
+/**********************************************************************
+** $Id$
+**
+** Definition of QtTableView class
+**
+** Created : 941115
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file contains a class moved out of the Qt GUI Toolkit API. It
+** may be used, distributed and modified without limitation.
+**
+**********************************************************************/
+
+#ifndef QTTABLEVIEW_H
+#define QTTABLEVIEW_H
+
+#ifndef QT_H
+#include "qframe.h"
+#endif // QT_H
+
+#ifndef QT_NO_QTTABLEVIEW
+
+class QScrollBar;
+class QCornerSquare;
+
+
+class QtTableView : public QFrame
+{
+ Q_OBJECT
+public:
+ virtual void setBackgroundColor( const QColor & );
+ virtual void setPalette( const QPalette & );
+ void show();
+
+ void repaint( bool erase=TRUE );
+ void repaint( int x, int y, int w, int h, bool erase=TRUE );
+ void repaint( const QRect &, bool erase=TRUE );
+
+protected:
+ QtTableView( QWidget *parent=0, const char *name=0, WFlags f=0 );
+ ~QtTableView();
+
+ int numRows() const;
+ virtual void setNumRows( int );
+ int numCols() const;
+ virtual void setNumCols( int );
+
+ int topCell() const;
+ virtual void setTopCell( int row );
+ int leftCell() const;
+ virtual void setLeftCell( int col );
+ virtual void setTopLeftCell( int row, int col );
+
+ int xOffset() const;
+ virtual void setXOffset( int );
+ int yOffset() const;
+ virtual void setYOffset( int );
+ virtual void setOffset( int x, int y, bool updateScrBars = TRUE );
+
+ virtual int cellWidth( int col );
+ virtual int cellHeight( int row );
+ int cellWidth() const;
+ int cellHeight() const;
+ virtual void setCellWidth( int );
+ virtual void setCellHeight( int );
+
+ virtual int totalWidth();
+ virtual int totalHeight();
+
+ uint tableFlags() const;
+ bool testTableFlags( uint f ) const;
+ virtual void setTableFlags( uint f );
+ void clearTableFlags( uint f = ~0 );
+
+ bool autoUpdate() const;
+ virtual void setAutoUpdate( bool );
+
+ void updateCell( int row, int column, bool erase=TRUE );
+
+ QRect cellUpdateRect() const;
+ QRect viewRect() const;
+
+ int lastRowVisible() const;
+ int lastColVisible() const;
+
+ bool rowIsVisible( int row ) const;
+ bool colIsVisible( int col ) const;
+
+ QScrollBar *verticalScrollBar() const;
+ QScrollBar *horizontalScrollBar() const;
+
+private slots:
+ void horSbValue( int );
+ void horSbSliding( int );
+ void horSbSlidingDone();
+ void verSbValue( int );
+ void verSbSliding( int );
+ void verSbSlidingDone();
+
+protected:
+ virtual void paintCell( QPainter *, int row, int col ) = 0;
+ virtual void setupPainter( QPainter * );
+
+ void paintEvent( QPaintEvent * );
+ void resizeEvent( QResizeEvent * );
+
+ int findRow( int yPos ) const;
+ int findCol( int xPos ) const;
+
+ bool rowYPos( int row, int *yPos ) const;
+ bool colXPos( int col, int *xPos ) const;
+
+ int maxXOffset();
+ int maxYOffset();
+ int maxColOffset();
+ int maxRowOffset();
+
+ int minViewX() const;
+ int minViewY() const;
+ int maxViewX() const;
+ int maxViewY() const;
+ int viewWidth() const;
+ int viewHeight() const;
+
+ void scroll( int xPixels, int yPixels );
+ void updateScrollBars();
+ void updateTableSize();
+
+private:
+ void coverCornerSquare( bool );
+ void snapToGrid( bool horizontal, bool vertical );
+ virtual void setHorScrollBar( bool on, bool update = TRUE );
+ virtual void setVerScrollBar( bool on, bool update = TRUE );
+ void updateView();
+ int findRawRow( int yPos, int *cellMaxY, int *cellMinY = 0,
+ bool goOutsideView = FALSE ) const;
+ int findRawCol( int xPos, int *cellMaxX, int *cellMinX = 0,
+ bool goOutsideView = FALSE ) const;
+ int maxColsVisible() const;
+
+ void updateScrollBars( uint );
+ void updateFrameSize();
+
+ void doAutoScrollBars();
+ void showOrHideScrollBars();
+
+ int nRows;
+ int nCols;
+ int xOffs, yOffs;
+ int xCellOffs, yCellOffs;
+ short xCellDelta, yCellDelta;
+ short cellH, cellW;
+
+ uint eraseInPaint : 1;
+ uint verSliding : 1;
+ uint verSnappingOff : 1;
+ uint horSliding : 1;
+ uint horSnappingOff : 1;
+ uint coveringCornerSquare : 1;
+ uint sbDirty : 8;
+ uint inSbUpdate : 1;
+
+ uint tFlags;
+ QRect cellUpdateR;
+
+ QScrollBar *vScrollBar;
+ QScrollBar *hScrollBar;
+ QCornerSquare *cornerSquare;
+
+private: // Disabled copy constructor and operator=
+#if defined(Q_DISABLE_COPY)
+ QtTableView( const QtTableView & );
+ QtTableView &operator=( const QtTableView & );
+#endif
+};
+
+
+const uint Tbl_vScrollBar = 0x00000001;
+const uint Tbl_hScrollBar = 0x00000002;
+const uint Tbl_autoVScrollBar = 0x00000004;
+const uint Tbl_autoHScrollBar = 0x00000008;
+const uint Tbl_autoScrollBars = 0x0000000C;
+
+const uint Tbl_clipCellPainting = 0x00000100;
+const uint Tbl_cutCellsV = 0x00000200;
+const uint Tbl_cutCellsH = 0x00000400;
+const uint Tbl_cutCells = 0x00000600;
+
+const uint Tbl_scrollLastHCell = 0x00000800;
+const uint Tbl_scrollLastVCell = 0x00001000;
+const uint Tbl_scrollLastCell = 0x00001800;
+
+const uint Tbl_smoothHScrolling = 0x00002000;
+const uint Tbl_smoothVScrolling = 0x00004000;
+const uint Tbl_smoothScrolling = 0x00006000;
+
+const uint Tbl_snapToHGrid = 0x00008000;
+const uint Tbl_snapToVGrid = 0x00010000;
+const uint Tbl_snapToGrid = 0x00018000;
+
+
+inline int QtTableView::numRows() const
+{ return nRows; }
+
+inline int QtTableView::numCols() const
+{ return nCols; }
+
+inline int QtTableView::topCell() const
+{ return yCellOffs; }
+
+inline int QtTableView::leftCell() const
+{ return xCellOffs; }
+
+inline int QtTableView::xOffset() const
+{ return xOffs; }
+
+inline int QtTableView::yOffset() const
+{ return yOffs; }
+
+inline int QtTableView::cellHeight() const
+{ return cellH; }
+
+inline int QtTableView::cellWidth() const
+{ return cellW; }
+
+inline uint QtTableView::tableFlags() const
+{ return tFlags; }
+
+inline bool QtTableView::testTableFlags( uint f ) const
+{ return (tFlags & f) != 0; }
+
+inline QRect QtTableView::cellUpdateRect() const
+{ return cellUpdateR; }
+
+inline bool QtTableView::autoUpdate() const
+{ return isUpdatesEnabled(); }
+
+inline void QtTableView::repaint( bool erase )
+{ repaint( 0, 0, width(), height(), erase ); }
+
+inline void QtTableView::repaint( const QRect &r, bool erase )
+{ repaint( r.x(), r.y(), r.width(), r.height(), erase ); }
+
+inline void QtTableView::updateScrollBars()
+{ updateScrollBars( 0 ); }
+
+
+#endif // QT_NO_QTTABLEVIEW
+
+#endif // QTTABLEVIEW_H
diff --git a/arts/builder/retrievedlg.cpp b/arts/builder/retrievedlg.cpp
new file mode 100644
index 00000000..59a8079f
--- /dev/null
+++ b/arts/builder/retrievedlg.cpp
@@ -0,0 +1,137 @@
+ /*
+
+ Copyright (C) 1998 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include "retrievedlg.h"
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qlistbox.h>
+#include <kbuttonbox.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qlineedit.h>
+#include <kapplication.h>
+#include <kseparator.h>
+#include <klocale.h>
+#include <kstdguiitem.h>
+#include <stdio.h>
+#include <set>
+#include <arts/debug.h>
+#include <qpushbutton.h>
+
+static void min_size(QWidget *w) {
+ w->setMinimumSize(w->sizeHint());
+}
+
+RetrieveDlg::RetrieveDlg(QWidget *parent) :QDialog(parent,"X", TRUE)
+{
+ setCaption(i18n("Retrieve Structure From Server"));
+
+ QVBoxLayout *mainlayout = new QVBoxLayout(this);
+
+// caption label: "Synthesis running..."
+
+ mainlayout->addSpacing(5);
+ QLabel *captionlabel = new QLabel(this);
+ QFont labelfont(captionlabel->font());
+ labelfont.setPointSize(labelfont.pointSize()*3/2);
+ captionlabel->setFont(labelfont);
+ captionlabel->setText(QString(" ")+i18n("Published structures")+QString(" "));
+ captionlabel->setAlignment(AlignCenter);
+ min_size(captionlabel);
+ mainlayout->addWidget(captionlabel);
+
+// hruler
+
+ mainlayout->addSpacing(5);
+ KSeparator *ruler2 = new KSeparator( KSeparator::HLine, this);
+ mainlayout->addWidget(ruler2);
+ mainlayout->addSpacing(5);
+
+// listwidget
+
+ listbox = new QListBox(this);
+ listbox->setMinimumSize(300,200);
+
+ arts_debug("TODO:PORT:get available structures");
+#if 0
+ // sort the result:
+ vector<StructureDesc> *structures = Synthesizer->publishedStructures();
+ set<string> names;
+
+ unsigned long i;
+ for(i=0;i<structures->length();i++)
+ names.insert(structures[i]->Name());
+
+ set<string>::iterator ni;
+ for(ni=names.begin();ni!=names.end();++ni)
+ listbox->insertItem((*ni).c_str());
+#endif
+
+ mainlayout->addWidget(listbox);
+
+// hruler
+
+ mainlayout->addSpacing(5);
+ KSeparator *ruler = new KSeparator( KSeparator::HLine, this);
+ mainlayout->addWidget(ruler);
+ mainlayout->addSpacing(5);
+
+// buttons
+
+ QHBoxLayout *buttonlayout = new QHBoxLayout;
+ mainlayout->addSpacing(5);
+ mainlayout->addLayout(buttonlayout);
+ mainlayout->addSpacing(5);
+
+ buttonlayout->addSpacing(5);
+ KButtonBox *bbox = new KButtonBox(this);
+
+ bbox->addButton(KStdGuiItem::help(), this, SLOT( help() ));
+ bbox->addStretch(1);
+
+ QButton *cancelbutton = bbox->addButton(KStdGuiItem::cancel());
+ connect( cancelbutton, SIGNAL( clicked() ), SLOT(reject() ) );
+
+ QButton *okbutton = bbox->addButton(KStdGuiItem::ok());
+ connect( okbutton, SIGNAL( clicked() ), SLOT(accept() ) );
+
+ bbox->layout();
+
+ buttonlayout->addWidget(bbox);
+ buttonlayout->addSpacing(5);
+
+ mainlayout->freeze();
+}
+
+QString RetrieveDlg::result()
+{
+ if(listbox->currentItem() != -1)
+ {
+ return(listbox->text(listbox->currentItem()));
+ }
+ return QString::null;
+}
+
+void RetrieveDlg::help()
+{
+ KApplication::kApplication()->invokeHelp("", "karts");
+}
+#include "retrievedlg.moc"
diff --git a/arts/builder/retrievedlg.h b/arts/builder/retrievedlg.h
new file mode 100644
index 00000000..e37d3120
--- /dev/null
+++ b/arts/builder/retrievedlg.h
@@ -0,0 +1,45 @@
+ /*
+
+ Copyright (C) 1998 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __RETRIEVEDLG_H_
+#define __RETRIEVEDLG_H_
+
+#include "structure.h"
+
+#include <qdialog.h>
+#include <qtimer.h>
+#include <qlabel.h>
+#include <qscrollbar.h>
+#include <qlineedit.h>
+#include <qlayout.h>
+#include <qlistbox.h>
+#include <string>
+
+class RetrieveDlg :public QDialog {
+ Q_OBJECT
+ QListBox *listbox;
+public:
+ RetrieveDlg(QWidget *parent);
+ QString result();
+public slots:
+ void help();
+};
+#endif
diff --git a/arts/builder/scomponent.cpp b/arts/builder/scomponent.cpp
new file mode 100644
index 00000000..e894abaa
--- /dev/null
+++ b/arts/builder/scomponent.cpp
@@ -0,0 +1,108 @@
+ /*
+
+ Copyright (C) 1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include "scomponent.h"
+//#include <arts/debug.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <stdio.h>
+
+StructureComponent::StructureComponent(StructureCanvas *canvas)
+: _x(0), _y(0)
+{
+ this->canvas = canvas;
+}
+
+StructureComponent::~StructureComponent()
+{
+}
+
+void StructureComponent::hide()
+{
+ if(_visible)
+ {
+ _visible = false;
+ redraw();
+ }
+}
+
+void StructureComponent::show()
+{
+ if(!_visible)
+ {
+ _visible = true;
+ redraw();
+ }
+}
+
+bool StructureComponent::visible()
+{
+ return(_visible);
+}
+
+void StructureComponent::redraw()
+{
+ canvas->redrawRect(x(), y(), width(), height());
+}
+
+bool StructureComponent::move(int newx, int newy)
+{
+ bool success = moveInternal(newx, newy);
+
+ if(success)
+ {
+ hide();
+ redraw();
+
+ _x = newx;
+ _y = newy;
+
+ show();
+ redraw();
+ }
+
+ return success;
+}
+
+int StructureComponent::x() const
+{
+ return _x;
+}
+
+int StructureComponent::y() const
+{
+ return _y;
+}
+
+bool StructureComponent::selected()
+{
+ return _selected;
+}
+
+void StructureComponent::setSelected(bool newselection)
+{
+ if(newselection != _selected)
+ {
+ _selected = newselection;
+ redraw();
+ }
+}
+
diff --git a/arts/builder/scomponent.h b/arts/builder/scomponent.h
new file mode 100644
index 00000000..c5bdcbad
--- /dev/null
+++ b/arts/builder/scomponent.h
@@ -0,0 +1,87 @@
+ /*
+
+ Copyright (C) 1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __SCOMPONENT_H__
+#define __SCOMPONENT_H__
+
+#include <qstring.h>
+#include <list>
+
+class ModulePort;
+class QPainter;
+class QPixmap;
+
+class StructureCanvas {
+public:
+ virtual void redrawRect(int x, int y, int width, int height) = 0;
+};
+
+class StructureComponent {
+protected:
+ StructureCanvas *canvas;
+
+ int _x, _y;
+ bool _selected, _visible;
+
+ virtual bool moveInternal(int x, int y) = 0;
+
+public:
+ StructureComponent(StructureCanvas *canvas);
+ virtual ~StructureComponent();
+
+ // type
+
+ enum ComponentType { ctModule, ctPort };
+ virtual ComponentType type() = 0;
+
+ // TODO: connection & autorouter
+
+ virtual ModulePort *portAt(int segment, int x, int y) = 0;
+ virtual void dumpPorts(std::list<ModulePort *>& ports) = 0;
+
+ // visibility
+ bool visible();
+ void show();
+ void hide();
+ void redraw();
+
+ // drawing
+ virtual bool drawNeedsBackground(int segment) = 0;
+ virtual void drawSegment(QPainter *dest, int cellsize, int segment) = 0;
+ virtual QPixmap *pixmap() = 0;
+ virtual QString name() = 0;
+
+ // space checking & positioning (dimensions in cells)
+ bool move(int x, int y);
+ int x() const;
+ int y() const;
+ virtual int width() const = 0;
+ virtual int height() const = 0;
+
+ // selection
+ bool selected();
+ void setSelected(bool newselection);
+
+ // creation and destruction are handled via standard
+ // constructors/destructors
+};
+
+#endif
diff --git a/arts/builder/session.cpp b/arts/builder/session.cpp
new file mode 100644
index 00000000..46efd7e1
--- /dev/null
+++ b/arts/builder/session.cpp
@@ -0,0 +1,80 @@
+ /*
+
+ Copyright (C) 1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include "session.h"
+#include <stdio.h>
+#include <arts/debug.h>
+
+Session::Session()
+{
+ session = 0;
+}
+
+Session::~Session()
+{
+ if(session) delete session;
+ session = 0;
+}
+
+bool Session::startExecute()
+{
+ arts_debug("TODO:PORT: Session::startExecute()");
+#if 0
+ assert(session);
+ assert(!execID);
+
+ // just in case synthesis has been halted before,
+ // restart it and hope we'll have enough computing power now
+ Synthesizer->Reset();
+ execID = Synthesizer->restoreSession(*session,preferredservers);
+#endif
+ return true;
+}
+
+bool Session::loadSession(const char *filename)
+{
+#if 0
+ if(session) delete session;
+ session = 0;
+
+ FILE *infile = fopen(filename,"r");
+ if(!infile) return false;
+
+ session = new ArtsCorba::StringSeq;
+
+ char line[1024];
+ unsigned long i = 0;
+
+ while(fgets(line,1024,infile))
+ {
+ // cut eventual CR and/or LFs at the end of the line
+ while(strlen(line) && line[strlen(line)-1] < 14)
+ line[strlen(line)-1] = 0;
+
+ session->length(i+1);
+ (*session)[i++] = CORBA::string_dup(line);
+ }
+ fclose(infile);
+ return true;
+#endif
+ arts_debug("TODO:PORT:loadSession(%s)",filename);
+ return false;
+}
diff --git a/arts/builder/session.h b/arts/builder/session.h
new file mode 100644
index 00000000..bfa0c3d8
--- /dev/null
+++ b/arts/builder/session.h
@@ -0,0 +1,38 @@
+ /*
+
+ Copyright (C) 1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __SESSION_H__
+#define __SESSION_H__
+
+#include "structure.h"
+
+class Session :public ExecutableStructure {
+ std::vector<std::string> *session;
+public:
+ Session();
+ ~Session();
+
+ bool startExecute();
+
+ bool loadSession(const char *filename);
+};
+
+#endif
diff --git a/arts/builder/structure.cpp b/arts/builder/structure.cpp
new file mode 100644
index 00000000..37950119
--- /dev/null
+++ b/arts/builder/structure.cpp
@@ -0,0 +1,462 @@
+ /*
+
+ Copyright (C) 1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include "structure.h"
+#include "soundserver.h"
+#include "kartsserver.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <iostream>
+#include <fstream>
+#include <kdebug.h>
+#include <arts/debug.h>
+
+using namespace std;
+
+ExecutableStructure::ExecutableStructure()
+{
+}
+
+ExecutableStructure::~ExecutableStructure()
+{
+ // to make destructor virtual
+ // stop execution here?
+}
+
+void ExecutableStructure::stopExecute()
+{
+ arts_debug("TODO: PORT: freeStructure");
+}
+
+bool ExecutableStructure::isExecuting()
+{
+ arts_debug("TODO:PORT:isExecuting()");
+ return false;
+}
+
+bool ExecutableStructure::saveSession(const char *filename)
+{
+ arts_debug("TODO:PORT:saveSession()");
+#if 0
+ assert(execID);
+
+ ArtsCorba::StringSeq_var data;
+ arts_debug("saveSession");
+ if(Synthesizer->saveSession(execID,true,data))
+ {
+ arts_debug("ok");
+ FILE *file = fopen(filename,"w");
+ if(!file) return false;
+
+ unsigned long i;
+ for(i=0;i<data->length();i++) fprintf(file,"%s\n",(char *)(*data)[i]);
+ fclose(file);
+
+ return true;
+ }
+ arts_debug("failed");
+#endif
+ return false;
+}
+
+Structure::Structure() :ExecutableStructure()
+{
+ canvas = 0;
+}
+
+void Structure::setCanvas(StructureCanvas *canvas)
+{
+ this->canvas = canvas;
+}
+
+Structure::~Structure()
+{
+ clear();
+ arts_debug("~Structure (releasing structuredesc from structure)");
+}
+
+bool Structure::startExecute()
+{
+#if 0
+ assert(!execID);
+
+ arts_debug("PORT: TODO startExecute()");
+ // just in case synthesis has been halted before,
+ // restart it and hope we'll have enough computing power now
+ //Synthesizer->Reset();
+ //execID = Synthesizer->createStructure(StructureDesc,preferredservers);
+ assert(execID);
+#endif
+
+ /* connect to the sound server */
+ Arts::SimpleSoundServer server = KArtsServer().server();
+
+ if(server.isNull())
+ return false;
+
+ /* move a copy of the structure to the server, so that there will be
+ no latencies in querying what to connect to what */
+ vector<string> *savePtr = StructureDesc.saveToList();
+ Arts::StructureDesc remoteSD;
+ remoteSD = Arts::DynamicCast(server.createObject("Arts::StructureDesc"));
+ assert(!remoteSD.isNull());
+ remoteSD.loadFromList(*savePtr);
+ delete savePtr;
+
+ /* create a structure builder on the server */
+ Arts::StructureBuilder builder;
+ builder = Arts::DynamicCast(server.createObject("Arts::StructureBuilder"));
+
+ /* create a local factory - this will enable the builder to create gui qt
+ widgets (which need to reside within an qt application to work) */
+
+ Arts::LocalFactory factory;
+ builder.addFactory(factory);
+
+ /* create the structure on the server */
+ structure = Arts::DynamicCast(builder.createObject(remoteSD));
+
+ if (structure.isNull())
+ return false;
+
+ structure.start();
+
+ return true;
+}
+
+void Structure::stopExecute()
+{
+
+ // TODO:PORT: verify this code
+ structure = Arts::SynthModule::null();
+}
+
+void Structure::publish()
+{
+ arts_debug("PORT: TODO publish()");
+ //Synthesizer->publishStructureDesc(StructureDesc);
+}
+
+bool Structure::valid()
+{
+ return StructureDesc.valid();
+}
+
+string Structure::name()
+{
+ return StructureDesc.name();
+}
+
+void Structure::rename(const char *newname)
+{
+ StructureDesc.name(newname);
+}
+
+void Structure::addInheritedInterface(const char *iface)
+{
+ StructureDesc.addInheritedInterface(iface);
+}
+
+vector<string> *Structure::inheritedInterfaces()
+{
+ return StructureDesc.inheritedInterfaces();
+}
+
+void Structure::removeInheritedInterface(const char *iface)
+{
+ StructureDesc.removeInheritedInterface(iface);
+}
+
+void Structure::saveInto(FILE *file)
+{
+ vector<string> *list = StructureDesc.saveToList();
+
+ vector<string>::iterator i;
+
+ for(i = list->begin(); i != list->end(); i++)
+ fprintf(file, "%s\n", (*i).c_str());
+
+ delete list;
+}
+
+bool Structure::save(const char *filename)
+{
+ FILE *file = fopen(filename,"w");
+ if (!file)
+ return false;
+
+ saveInto(file);
+
+ fclose(file);
+
+ return true;
+}
+
+void Structure::clear()
+{
+ list<StructureComponent *>::iterator ci;
+
+ arts_debug("clc");
+/*
+ for(ci = ComponentList.begin(); ci != ComponentList.end(); ++ci)
+ delete (*ci);
+
+ ComponentList.erase(ComponentList.begin(), ComponentList.end());
+ ModuleList.erase(ModuleList.begin(), ModuleList.end());
+*/
+ for(ci = ComponentList.begin(); ci != ComponentList.end(); ++ci)
+ (*ci)->setSelected(true);
+ deleteSelected();
+
+ arts_debug("sdc");
+ // shouldn't do much, now that we deleted every single component of
+ // the structure, but we to it anyway, just to be sure.
+ StructureDesc.clear();
+}
+
+void Structure::retrieve(const char *pubname)
+{
+ arts_debug("PORT: TODO: retrieve");
+#if 0
+ arts_debug("retrieve... %s",pubname);
+ ArtsCorba::StructureDesc_var psd = Synthesizer->lookupStructureDesc(pubname);
+
+ arts_debug("psdlookup ok");
+ if(psd)
+ {
+ arts_debug("starting savetolist");
+ ArtsCorba::StringSeq_var strseq=psd->saveToList();
+ arts_debug("savetolist ok");
+ loadFromList(strseq);
+ arts_debug("loadfromlist ok");
+ }
+ arts_debug("retrieve... ok");
+#endif
+}
+
+void Structure::load(const char *filename)
+{
+ ifstream infile(filename);
+ string line;
+ vector<string> strseq;
+
+ while(getline(infile,line))
+ strseq.push_back(line);
+
+ loadFromList(strseq);
+#if 0
+ FILE *infile = fopen(filename,"r");
+ ArtsCorba::StringSeq_var strseq = new ArtsCorba::StringSeq;
+
+ char line[1024];
+ unsigned long i = 0;
+
+ while(fgets(line,1024,infile))
+ {
+ // cut eventual CR and/or LFs at the end of the line
+ while(strlen(line) && line[strlen(line)-1] < 14)
+ line[strlen(line)-1] = 0;
+
+ strseq->length(i+1);
+ (*strseq)[i++] = CORBA::string_dup(line);
+ }
+ fclose(infile);
+
+ arts_debug(">>loadfromlist...");
+ loadFromList(strseq);
+ arts_debug("<<loadfromlist...");
+#endif
+}
+
+void Structure::loadFromList(const vector<string>& strseq)
+{
+ assert(canvas);
+
+ arts_debug(">>clear");
+ clear();
+ arts_debug("<<clear");
+
+ StructureDesc.loadFromList(strseq);
+
+ vector<Arts::ModuleDesc> *modules = StructureDesc.modules();
+ vector<Arts::ModuleDesc>::iterator mi;
+
+ for(mi=modules->begin(); mi != modules->end(); ++mi)
+ {
+ Module *m = new Module(*mi,StructureDesc,canvas);
+
+ m->show();
+ ModuleList.push_back(m);
+ ComponentList.push_back(m);
+ }
+ delete modules;
+
+ vector<Arts::StructurePortDesc> *ports = StructureDesc.ports();
+ vector<Arts::StructurePortDesc>::iterator pi;
+
+ for(pi=ports->begin(); pi != ports->end(); ++pi)
+ {
+ StructurePort *p = new StructurePort(*pi,StructureDesc,canvas);
+
+ p->show();
+ ComponentList.push_back(p);
+ }
+ delete ports;
+}
+
+Module *Structure::createModule(const Arts::ModuleInfo& minfo)
+{
+ assert(canvas);
+ Module *m = new Module(minfo,StructureDesc,canvas);
+
+ ComponentList.push_back(m);
+ ModuleList.push_back(m);
+ return m;
+}
+
+StructurePort *Structure::createStructurePort(const Arts::PortType& type)
+{ // TODO:PORT: verify this code
+#if 0
+ arts_debug("TODO:PORT:createStructurePort");
+#endif
+// portname generation
+ unsigned long portindex = 1,l,baselen;;
+ char name[100];
+
+ string namebase;
+ if(type.direction == Arts::input) {
+ // this is a port where our structure puts its results
+ // so it is an input port, that is named out
+ namebase = "out"; baselen = 3;
+ } else {
+ // this is a port where our structure gets data from
+ // so it is an output port, that is named in
+ namebase = "in"; baselen = 2;
+ }
+
+ vector<Arts::StructurePortDesc> *sps = StructureDesc.ports();
+
+ for(l=0;l<sps->size();l++) {
+ string thisname = (*sps)[l].name();
+ if(strncmp(thisname.c_str(), namebase.c_str(), baselen) == 0 &&
+ strlen(thisname.c_str()) > baselen)
+ {
+ unsigned long index2 = atol(&thisname.c_str()[baselen]);
+ if(index2 >= portindex) portindex = index2+1;
+ }
+ }
+ delete sps;
+
+ sprintf(name,"%s%ld",namebase.c_str(),portindex);
+ arts_debug("new Portname: %s",name);
+ Arts::StructurePortDesc spd =
+ StructureDesc.createStructurePortDesc(type,name);
+
+ assert(canvas);
+ StructurePort *s = new StructurePort(spd,StructureDesc,canvas);
+ ComponentList.push_back(s);
+ return s;
+}
+
+list<Module *> *Structure::getModuleList()
+{
+ return(&ModuleList);
+}
+
+list<StructureComponent *> *Structure::getComponentList()
+{
+ return(&ComponentList);
+}
+
+long Structure::countSelected()
+{
+ list<StructureComponent *>::iterator ci;
+ long targets = 0;
+
+ for(ci=ComponentList.begin();ci!=ComponentList.end();++ci)
+ if((*ci)->selected()) targets++;
+
+ return targets;
+}
+
+void Structure::deleteSelected()
+{
+ arts_debug("deleteSelected...");
+
+ // remove module from the ModuleList
+ list<Module *>::iterator mi;
+ for(mi=ModuleList.begin();mi!=ModuleList.end();)
+ {
+ if((*mi)->selected())
+ {
+ mi = ModuleList.erase(mi);
+ }
+ else mi++;
+ }
+
+ // disconnect ports (it might be useful to get this right in the model
+ // instead of doing it in the view - however at it works without end
+ // user visible bugs like this)
+
+ list<StructureComponent *>::iterator ci;
+ list<ModulePort *> allPorts;
+
+ for(ci = ComponentList.begin(); ci!=ComponentList.end(); ++ci)
+ if((*ci)->selected())
+ (*ci)->dumpPorts(allPorts);
+
+ list<ModulePort *>::iterator pi;
+ for(pi = allPorts.begin(); pi != allPorts.end(); ++pi)
+ (*pi)->PortDesc.disconnectAll();
+
+ // and from the ComponentList (the future ;)
+
+ ci = ComponentList.begin();
+ while(ci!=ComponentList.end())
+ {
+ if((*ci)->selected())
+ {
+ delete (*ci);
+ ci = ComponentList.erase(ci);
+ }
+ else ci++;
+ }
+
+ arts_debug("deleteSelected ok.");
+}
+
+StructureComponent *Structure::componentAt(long x, long y, bool ignore_selected)
+{
+ list<StructureComponent *>::iterator ci;
+
+ for(ci=ComponentList.begin();ci!=ComponentList.end();++ci)
+ {
+ StructureComponent *c = *ci;
+
+ if(x >= c->x() && x < c->x()+c->width() &&
+ y >= c->y() && y < c->y()+c->height())
+ {
+ if((c->selected() && !ignore_selected) || !c->selected()) return c;
+ }
+ }
+
+ return 0;
+}
diff --git a/arts/builder/structure.h b/arts/builder/structure.h
new file mode 100644
index 00000000..7717f3ef
--- /dev/null
+++ b/arts/builder/structure.h
@@ -0,0 +1,92 @@
+ /*
+
+ Copyright (C) 1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __STRUCTURE_H_
+#define __STRUCTURE_H_
+
+#include "artsbuilder.h"
+#include "module.h"
+#include "scomponent.h"
+#include "structureport.h"
+#include "artsflow.h"
+#include <vector>
+
+using namespace std;
+
+class ExecutableStructure
+{
+public:
+ ExecutableStructure();
+ virtual ~ExecutableStructure();
+
+ virtual bool startExecute() = 0;
+ virtual void stopExecute();
+ virtual bool isExecuting();
+ virtual bool saveSession(const char *filename);
+};
+
+class Structure :public ExecutableStructure
+{
+ Arts::StructureDesc StructureDesc;
+ Arts::SynthModule structure;
+ StructureCanvas *canvas;
+
+ std::list<Module *> ModuleList;
+ std::list<StructureComponent *> ComponentList;
+
+public:
+ Structure();
+ ~Structure();
+
+ void setCanvas(StructureCanvas *canvas);
+
+ bool startExecute();
+ void stopExecute();
+
+ bool valid();
+ void load(const char *filename);
+ void retrieve(const char *pubname);
+ void loadFromList(const std::vector<std::string>& strseq);
+ void saveInto(FILE *file);
+ bool save(const char *filename);
+ void clear();
+ void publish();
+
+ long countSelected();
+ void deleteSelected();
+
+ std::string name();
+ void rename(const char *newname);
+
+ void addInheritedInterface(const char *iface);
+ void removeInheritedInterface(const char *iface);
+ vector<std::string> *inheritedInterfaces();
+
+ Module *createModule(const Arts::ModuleInfo& minfo);
+ StructurePort *createStructurePort(const Arts::PortType& type);
+
+ StructureComponent *componentAt(long x, long y, bool ignore_selected);
+
+ std::list<Module *> *getModuleList();
+ std::list<StructureComponent *> *getComponentList();
+};
+
+#endif
diff --git a/arts/builder/structureport.cpp b/arts/builder/structureport.cpp
new file mode 100644
index 00000000..a645d60a
--- /dev/null
+++ b/arts/builder/structureport.cpp
@@ -0,0 +1,287 @@
+ /*
+
+ Copyright (C) 1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#include "structureport.h"
+#include "drawutils.h"
+#include <qpainter.h>
+#include <qpalette.h>
+#include <qdrawutil.h>
+#include <qbitmap.h>
+#include <assert.h>
+#include <stdio.h>
+#include <arts/debug.h>
+
+using namespace std;
+
+StructurePort::StructurePort(Arts::StructurePortDesc SPortDesc,
+ Arts::StructureDesc StructureDesc, StructureCanvas *canvas)
+ : StructureComponent(canvas)
+{
+ string portname = SPortDesc.name();
+ this->SPortDesc = SPortDesc;
+ this->StructureDesc = StructureDesc;
+ _x = SPortDesc.x();
+ _y = SPortDesc.y();
+ _selected = false;
+ _visible = false;
+
+ ModulePort::Direction dir;
+ if(SPortDesc.type().direction == Arts::input)
+ dir = ModulePort::in;
+ else
+ dir = ModulePort::out;
+
+ if(SPortDesc.type().connType == Arts::conn_property)
+ arts_debug("got property here....");
+ // owner, description, portnr
+ arts_debug(">>creating structureport: %s",portname.c_str());
+ _port = new ModulePort(this, portname.c_str(), 0, dir,this->SPortDesc);
+ arts_debug("<<");
+}
+
+StructurePort::~StructurePort()
+{
+ hide();
+ StructureDesc.freeStructurePortDesc(SPortDesc);
+ delete _port;
+}
+
+bool StructurePort::moveInternal(int x, int y)
+{
+ return SPortDesc.moveTo(x, y);
+}
+
+int StructurePort::width() const
+{
+ return 1;
+}
+
+int StructurePort::height() const
+{
+ return 1;
+}
+
+StructureComponent::ComponentType StructurePort::type()
+{
+ return ctPort;
+}
+
+bool StructurePort::drawNeedsBackground(int segment)
+{
+ assert(segment==0);
+ return true;
+}
+
+void StructurePort::drawSegment(QPainter *dest, int cellsize, int segment)
+{
+ QString pname = QString::fromLocal8Bit(SPortDesc.name().c_str());
+ assert(segment==0);
+
+ QPainter &p = *dest;
+
+ int direction = (_port->direction == ModulePort::out)?1:0;
+
+// FIXME: make these color defs available at one central place, they
+// are currently copied from main.cpp
+
+ QColor mcolor(43,43,168);
+ QColor mcolorlight(164,176,242);
+ QColorGroup g( Qt::white, Qt::blue, mcolorlight, mcolor.dark(), mcolor,
+ Qt::black, Qt::black );
+ QBrush fill( mcolor );
+ QPen textpen(QColor(255,255,180),1);
+ int border = cellsize/10;
+ int boxtop = (cellsize/2)*(1-direction);
+
+ qDrawShadePanel(&p,0,boxtop,cellsize,cellsize/2, g, false, 1, &fill);
+ p.setPen(textpen);
+
+ // Selection box
+ if(_selected)
+ {
+ QPen pen(Qt::white,1,Qt::DotLine);
+
+ p.setPen(pen);
+ p.drawRect(0,boxtop,cellsize,cellsize/2);
+ }
+ // ... doesn't look centered without the 2*border ?!?
+ int textwidth;
+ QString label=DrawUtils::cropText(&p, pname, cellsize-border*2, textwidth);
+ p.drawText(border,border+boxtop,cellsize-border-1,(cellsize/2-1)-2*border,
+ Qt::AlignCenter,label);
+
+ int arrowwidth = cellsize/4;
+
+ int i;
+ for(i=0;i<3;i++)
+ {
+ QBrush fbrush;
+ int delta = 0;
+ switch(i)
+ {
+ case 0: delta = 0;
+ fbrush = QBrush(g.light());
+ break;
+ case 1: delta = 2;
+ fbrush = QBrush(g.dark());
+ break;
+ case 2: delta = 1;
+ fbrush = fill;
+ break;
+ }
+
+/**********************
+- | |
+c | |
+- -+ +-
+d | |
+- \ /
+ \ /
+ \_/
+ |b| w |b|
+*********************/
+
+ int t = (cellsize/2-1)*direction; // top
+ int l = delta; // left
+ int w = arrowwidth-2; // arrow body width
+ int h = cellsize/2; // total arrow height
+
+ int b = (cellsize/2-arrowwidth)/2; // x border width
+/*
+ int c = cellsize/10;
+ int d = cellsize/6;
+*/
+ int c = cellsize/12;
+ int d = cellsize/5;
+
+ QPointArray a(9);
+ a.setPoint(0,b+l,t);
+ a.setPoint(1,b+l,t+c);
+ a.setPoint(2,l,t+c);
+ a.setPoint(3,l,t+c+d);
+ a.setPoint(4,b+w/2+l,t+h);
+ a.setPoint(5,b*2+w+l,t+c+d);
+ a.setPoint(6,b*2+w+l,t+c);
+ a.setPoint(7,b+w+l,t+c);
+ a.setPoint(8,b+w+l,t);
+ //a.setPoint(9,b+l,t);
+/*
+ a.setPoint(0,t,b+l);
+ a.setPoint(1,t+c,b+l);
+ a.setPoint(2,t+c,l);
+ a.setPoint(3,t+c+d,l);
+ a.setPoint(4,t+h,b+w/2+l);
+ a.setPoint(5,t+c+d,b*2+w+l);
+ a.setPoint(6,t+c,b*2+w+l);
+ a.setPoint(7,t+c,b+w+l);
+ a.setPoint(8,t,b+w+l);
+ a.setPoint(9,t,b+l);
+*/
+ p.setPen(Qt::NoPen);
+ p.setBrush(fbrush);
+ p.drawPolygon(a);
+ if(delta==1 && direction==0)
+ {
+ p.setPen(g.light());
+ p.drawLine(b+l,t,b+w+l,t);
+ }
+/*
+ p.fillRect((cellsize/2-arrowwidth)/2+delta,cellsize/2-1,
+ arrowwidth,cellsize/2,fbrush);
+*/
+ }
+ {
+ int border = cellsize/7;
+
+ QBrush pbrush(_port->color(false));
+
+ _port->clickrect = QRect(border,direction * cellsize/2 + border,
+ cellsize/2-2*border, cellsize/2-2*border);
+ qDrawShadePanel(&p, _port->clickrect, g, _port->down(), 2, &pbrush);
+ }
+}
+
+ModulePort *StructurePort::portAt(int segment, int x, int y)
+{
+ assert(segment == 0);
+
+ QPoint clickpoint(x,y);
+ if(_port->clickrect.contains(clickpoint)) return _port;
+ return 0;
+}
+
+void StructurePort::dumpPorts(list<ModulePort *>& ports)
+{
+ ports.push_back(_port);
+}
+
+QPixmap *StructurePort::pixmap()
+{
+ return 0;
+}
+
+QString StructurePort::name()
+{
+ return QString::fromLocal8Bit(SPortDesc.name().c_str());
+}
+
+void StructurePort::raisePosition()
+{
+ SPortDesc.raisePosition();
+}
+
+void StructurePort::lowerPosition()
+{
+ SPortDesc.lowerPosition();
+}
+
+void StructurePort::rename(const char *newname)
+{
+ SPortDesc.rename(newname);
+ canvas->redrawRect(_x,_y,1,1);
+}
+
+long StructurePort::id()
+{
+ return SPortDesc.ID();
+}
+
+long StructurePort::position()
+{
+ return SPortDesc.position();
+}
+
+ModulePort *StructurePort::port()
+{
+ return _port;
+}
+
+const char *StructurePort::inheritedInterface()
+{
+ static string ii;
+ ii = SPortDesc.inheritedInterface();
+ return ii.c_str();
+}
+
+void StructurePort::inheritedInterface(const char *iface)
+{
+ SPortDesc.inheritedInterface(iface);
+}
diff --git a/arts/builder/structureport.h b/arts/builder/structureport.h
new file mode 100644
index 00000000..3eac37a4
--- /dev/null
+++ b/arts/builder/structureport.h
@@ -0,0 +1,66 @@
+ /*
+
+ Copyright (C) 1999 Stefan Westerfeld
+ stefan@space.twc.de
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef STRUCTUREPORT_H
+#define STRUCTUREPORT_H
+
+#include "scomponent.h"
+#include "module.h"
+
+class StructurePort :public StructureComponent {
+protected:
+ Arts::StructurePortDesc SPortDesc;
+ Arts::StructureDesc StructureDesc;
+
+ ModulePort *_port;
+
+ bool moveInternal(int x, int y);
+
+public:
+ StructurePort( Arts::StructurePortDesc SPortDesc,
+ Arts::StructureDesc StructureDesc, StructureCanvas *canvas);
+ ~StructurePort();
+
+ void raisePosition();
+ void lowerPosition();
+ void rename(const char *newname);
+ long id();
+ long position();
+ ModulePort *port();
+
+ const char *inheritedInterface();
+ void inheritedInterface(const char *iface);
+
+ // StructureComponent Interface
+ int width() const;
+ int height() const;
+ ComponentType type();
+
+ ModulePort *portAt(int segment, int x, int y);
+ void dumpPorts(std::list<ModulePort *>& ports);
+
+ bool drawNeedsBackground(int segment);
+ void drawSegment(QPainter *dest, int cellsize, int segment);
+ QPixmap *pixmap();
+ QString name();
+};
+
+#endif // STRUCTUREPORT_H
diff --git a/arts/builder/x-artsbuilder.desktop b/arts/builder/x-artsbuilder.desktop
new file mode 100644
index 00000000..684125ae
--- /dev/null
+++ b/arts/builder/x-artsbuilder.desktop
@@ -0,0 +1,60 @@
+# KDE Config File
+[Desktop Entry]
+MimeType=application/x-artsbuilder
+Comment=Arts Builder
+Comment[ar]=أداة لبناء الأصوات باستخدام aRts
+Comment[bg]=Аудио дизайнер
+Comment[bn]=আর্ট্‌স্ বিল্ডার
+Comment[br]=Arload Arts Builder
+Comment[ca]=Constructor Arts
+Comment[cs]=Konstruktér aRts
+Comment[cy]=Adeiladwr Arts
+Comment[da]=aRts-bygger
+Comment[de]=Arts-Builder
+Comment[eo]=Arts-Kreilo
+Comment[es]=Arts Builder (diseñador del sintetizador aRts)
+Comment[et]=aRts'i generaator
+Comment[fa]=سازندۀ Arts
+Comment[fi]=Arts-rakentaja
+Comment[fr]=Créateur de synthétiseurs d'aRts
+Comment[ga]=Tógálaí Arts
+Comment[gl]=Constructor Arts
+Comment[he]=בנאי של Arts
+Comment[hi]=एआरटीएस बिल्डर
+Comment[hu]=aRts-alapú hangmodellező program
+Comment[id]=Builder Arts
+Comment[is]=Arts smiður
+Comment[it]=Costruttore per aRts
+Comment[ja]=aRts ビルダー
+Comment[kk]=Arts құрастырғышы
+Comment[km]=កម្មវិធី​បង្កើត Arts
+Comment[ko]=Arts 만들기
+Comment[lt]=Arts komponuoklis
+Comment[mk]=Градител на Arts
+Comment[mt]=Bennej Arts
+Comment[nb]=Arts-bygger
+Comment[nds]=Klangfiltern för aRts
+Comment[ne]=कला निर्माता
+Comment[nl]=Arts Bouwprogramma
+Comment[nn]=Arts-byggjar
+Comment[pa]=Arts ਨਿਰਮਾਤਾ
+Comment[pt]=Construtor do Arts
+Comment[pt_BR]=Construtor Arts
+Comment[ru]=Звуковой дизайнер aRts
+Comment[se]=Arts-huksejeaddji
+Comment[sl]=Graditelj Arts
+Comment[sr]=Градитељ Arts-а
+Comment[sr@Latn]=Graditelj Arts-a
+Comment[sv]=Arts-byggare
+Comment[ta]=கலைத்திறன் உருவாக்குபவர்
+Comment[tg]=Созандаи aRts
+Comment[tr]=Arts Oluşturucu
+Comment[ven]=Muiti wa zwavhutsila
+Comment[xh]=Umakhi wemizobo
+Comment[zh_CN]=Arts 构建程序
+Comment[zu]=Umakhi Wezamasiko
+Icon=arts
+Type=MimeType
+Patterns=*.arts;
+OnlyShowIn=KDE;
+X-KDE-AutoEmbed=false