desc: arp!0 - groovy midi arpeggiator - v0.89rc - click [arp!0] for settings/help

/*
see arpbangzero_documentation.pdf in the release zip for a complete 
quick reference and very important credits.  see arpbangzero_changes.txt
for full release notes.
___
0.80beta - final feature creature release - 4 apr 2012
- hilight edited step when showing dropdown
- limit output range of midi note numbers
- scaled, absolute or synchronized tick times
- midi bus setting
- bump max variants to 12
- remove save seq play positions when preset is saved
0.81beta - 14 apr 2012 - very nearly finally release 
- fix prog change dopos/nosave variant logic
- optional control 3/4 seqs
- make slider mid-line visible for 100% opaque slider bar colors
- rightclick in dropdowns to set value w/out closing dropdown
- rework scaled tick time logic to separate tick index and fraction
  into separate automation controls.
- experimental additive contract meta: adds note from contracted step
  to following steps.
- revised dir operations gui to use dirop meta instead of dirop steyp
  type.  dirop meta shows special dirop icons for better intuitition.
- pdf docs with pictures!
0.82rc - 1 may 2012 - line in sand release
- fix initial note logic for downup & down+up orders
- fix single note bug for updown/downup orders
- add global setting for default load notes w/ preset
- only load notes w/ preset if saved notecnt > 0
- fix sortx logic flaw: precompute sortxlen before used in tick logic
- make sortx on/off and update events automatable
- new dirops: on first/on last/on crossover/reset play pos's
- fix tick scaling automation bug
- add missing support for ctl3/4 save/restore play pos's
- save play pos's only when paused, & only for edited seq
- indicate saved play pos's when paused with small cutout at bottom right of step
- use midi cc's for variant changes & other control functions (vs prg changes)
- extended midi cc logic to automate sequence step values
- midi lock global setting: prevents loading midi chan/bus/control from presets
- fix stuck notes when changing midi bus while arp playing
0.83rc - 15 may 2012 - lbl release
- fix extended midi cc to only send all ccs on variant/preset changes if enabled
- add logic to adjust seq len when inserting/deleting steps
- fix logic to set ctl3/4 seq lengths w/ right click
- send midi cc's before notes
- add option for tiny marks to indicate current steps
- fix sortx bug in apply changes to all variants
- optimize skin logic: only compute skin colors when skin changes
0.84rc - 17 may 2012 - lbf release
- change saved step indicators to bottom left
- fix logic for right relative dot highlight widths
- fix bug in dot highlight shadows logic
0.85rc - 24 may 2012 - back to future release
- fix ctl3/4 sequence length bug
- fix left click in tick slider bug
- add true double-click logic to dropdown buttongrid
- fix bug in send midi cc for dir seq edits
- fix bug: don't always send extended midi cc on chans 1-5
- prevent extended midi cc out when arp!0 chan + extended cc chan offset > 16
- fix inverted midi cc do pos reset & save var edits logic
- new default color scheme: clarity
- reorganized & tweaked color schemes; removed a few that seemed redundant
- add left/right-click on "swing" label to go to next/prev color scheme
- documentation updates/edits
- bump max default colors to 32
0.86rc - 28 may 2012 - forward into past release
- fix incompatibility w/ pre-bugfixed Js
- add on host seek dirop: jump to dirop when host seeks
- change subtract/contract metas to prime2/prime (''/') for dirops
- prime/prime2 metas for larger weights in :x4 dirop and remove :x16 dirop
- prime/prime2 metas for sequential sections variants of ?: random section dirop
0.87rc - 31 may 2012 - it lives! mad science release
- experimental subdir dirop: alien dirop substitutes oneshot dir seq from next 
  variant. heart dirop immediately returns to invoking dir seq. alien dirop with
  prime/prime2 metas subs 2nd & 3rd next variants.  
- changed 4x section dirop to 3x section (:4 to 3:), and changed variant 
  values when combined with prime/prime2/section metas to enable musically 
  useful multiples of sequential sections.
- WARNING: in next release, presets saved w/ arp!0 v0.81beta and earlier
  will not load.
0.88rc - 9 june 2012 - almost nearly semi-final thoughts and warnings release
- WARNING: in next release, presets saved w/ arp!0 v0.81beta and earlier
  will not load.
- WARNING: some obscure dirops have been removed or altered.  presets using
  the resortx meta, dir repeat and sequential section dirops will need to
  be manually updated.
- tweak opacity of dirop specific metas to match lighter dirops
- remove resortx meta functionality; replace with "%" resortx dirop
- remove dir repeat dirops; replace with prime/prime2 variants of the 4 
  "on-foo" dirops: on-foo+prime seeks to prior on-foo+prime2; will wrap 
  around to find following on-foo+prime2.
- move sequential section logic from variants of "?:" random section dirop
  to dedicated ",:" sequential section dirop which supports 3 independent
  section sequences.
- allow right-click on [arp!0] logo to show debug info
- a few semi-useful labeled debug infos, including last read preset version
- tweak a few dirop icons for clarity
- temporarily display preset version number
0.89rc - 12 june 2012 - not so fast release
- fix variant dir seq logic broken by prelim dir ui remapping code

  
*///- end release notes

/*  copyright 2012 dan mcmullen bang@bangzero.org

    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 3 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, see <http://www.gnu.org/licenses/>. 
*/

//- sliders: invisible for automation
slider1:0<0,1,1>-pause
slider2:6<-23,23,1>-tick index
slider3:0<0,25,0.001>-swing
slider4:0<0,255,1>-channel
slider5:0<0,2,1>-sort
slider6:0<0,6,1>-order
slider7:0<0,3,1>-octaves
slider8:8<1,32,1>-dir steps
slider9:8<1,32,1>-length steps
slider10:8<1,32,1>-gate steps
slider11:8<1,32,1>-voices steps
slider12:8<1,32,1>-trans steps
slider13:8<1,32,1>-accent steps
slider14:8<1,32,1>-offset steps
slider15:8<1,32,1>-control 1 steps
slider16:8<1,32,1>-control 2 steps
slider17:0<0,1,1>-hold
slider18:16<16,32,8>-maxsteps
slider19:10<0,100,1>-offset %
slider20:2<2,16,1>-swing steps
slider21:0<0,511,1>-sequences: random order
slider22:8<1,32,1>-control 3 steps
slider23:8<1,32,1>-control 4 steps
slider24:-2350081<-2350081,-2350080,1>-spare24
slider25:-2350081<-2350081,-2350080,1>-spare25
slider26:-2350081<-2350081,-2350080,1>-spare26
slider27:-2350081<-2350081,-2350080,1>-spare27
slider28:-2350081<-2350081,-2350080,1>-spare28
slider29:-2350081<-2350081,-2350080,1>-spare29
slider30:0<-1,0,1>-sort transform: enable
slider31:5<0,15,1>-sort transform: updates
slider32:0<0,1,.0000001>-tick scale

//- icon files
filename:0,bangzero_files/step-next.png
filename:1,bangzero_files/conadd.png
filename:2,bangzero_files/step-same.png
filename:3,bangzero_files/ccgrid2.png
filename:4,bangzero_files/tran0.png
filename:5,bangzero_files/tran1.png
filename:6,bangzero_files/tran2.png
filename:7,bangzero_files/tran3.png
filename:8,bangzero_files/tran4.png
filename:9,bangzero_files/tran5.png
filename:10,bangzero_files/tran6.png
filename:11,bangzero_files/tran7.png
filename:12,bangzero_files/tran8.png
filename:13,bangzero_files/tran9.png
filename:14,bangzero_files/tran10.png
filename:15,bangzero_files/tran11.png
filename:16,bangzero_files/tran12.png
filename:17,bangzero_files/sort-time.png
filename:18,bangzero_files/sort-note.png
filename:19,bangzero_files/order-up.png
filename:20,bangzero_files/order-down.png
filename:21,bangzero_files/order-up-down.png
filename:22,bangzero_files/order-updown.png
filename:23,bangzero_files/order-down-up.png
filename:24,bangzero_files/order-downup.png
filename:25,bangzero_files/order-random.png
filename:26,bangzero_files/syncgrid2.png
filename:27,bangzero_files/changrid.png
filename:28,bangzero_files/ccgrid.png
filename:29,bangzero_files/clear.png
filename:30,bangzero_files/hold.png
filename:31,bangzero_data/arpbangzero_settings.txt
filename:32,bangzero_data/arpbangzero_defcolors.txt
filename:33,bangzero_files/len1.png
filename:34,bangzero_files/len2.png
filename:35,bangzero_files/len3.png
filename:36,bangzero_files/len4.png
filename:37,bangzero_files/len5.png
filename:38,bangzero_files/len6.png
filename:39,bangzero_files/len7.png
filename:40,bangzero_files/len8.png
filename:41,bangzero_files/vc0.png
filename:42,bangzero_files/vc1.png
filename:43,bangzero_files/vc2.png
filename:44,bangzero_files/vc3.png
filename:45,bangzero_files/vc4.png
filename:46,bangzero_files/vc5.png
filename:47,bangzero_files/vc6.png
filename:48,bangzero_files/len1b.png
filename:49,bangzero_files/len2b.png
filename:50,bangzero_files/len3b.png
filename:51,bangzero_files/len4b.png
filename:52,bangzero_files/len5b.png
filename:53,bangzero_files/len6b.png
filename:54,bangzero_files/len7b.png
filename:55,bangzero_files/len8b.png
filename:56,bangzero_files/vc0b.png
filename:57,bangzero_files/vc1b.png
filename:58,bangzero_files/vc2b.png
filename:59,bangzero_files/vc3b.png
filename:60,bangzero_files/vc4b.png
filename:61,bangzero_files/vc5b.png
filename:62,bangzero_files/vc6b.png
filename:63,bangzero_data/arpbangzero_sortx.txt
filename:64,bangzero_data/arpbangzero_defsortx.txt
filename:65,bangzero_files/dirtypes.png
filename:66,bangzero_files/dirtypes2.png

in_pin:none;
out_pin:none;

/////- @init
@init

ext_noinit= 1;
ext_midi_bus= 1;

notecnt= notecnt0= lastnotecnt= 0;
playpos= -1;
evcnt= 0;
tickcnt= 0;
lastcnt= 0;
newvnt= -1;

ticklen= 0; //dbg
tickpos= 0;
lasttick= 0;
orderrev= 0;
aareadprever= 0;
jittercnt= 1;
debug1= debug2= debug3= debug4= debug5= debug6= 0;

// limits
maxnotes= 64;
maxevs= 200;
maxmaxsteps= 32; //reserved space per seq in serialized mem
maxvnts= 12;

// value ranges
//dirrng= ???
lenrng= 8;
gaterng= 2.0;
vcrng= 7;
//tranrng= 24.0;
accrng= 100.0;
offrng= 100.0;
ctl1rng= 127.0;
ctl2rng= 127.0;
ctl3rng= 127.0;
ctl4rng= 127.0;
swingrng= 25.0;

// default values
dirdef= 0;
lendef= 0;
gatedef= .5;
vcdef= 1;
trandef= 12;
accdef= 50;
offdef=0;
ctl1def= 0;
ctl2def= 0;
ctl3def= 0;
ctl4def= 0;

// bitmasks
randdir= $x1;
randlen= $x2;
randgate= $x4;
randvc= $x8;
randtran= $x10;
randacc= $x20;
randoff= $x40;
randctl1= $x80;
randctl2= $x100;
randctl3= $x200;
randctl4= $x400;
vntnosave= $x20;
vntdopos=$x10;
vntmask=$xf;
resortxfirst=$x1;
resortxlast=$x2;
resortxoct=$x4;
resortxnote=$x8;
bsleni= 1;
bsgatei= 2;
bsvci= 4;
bstrani= 8;
bslent= 16;
bsgatet= 32;
bsvct= 64;
bstrant= 128;
bsgtic= 256;

//- dir seq values
dirbaserng= 15;
dirmask= $xff;
dirmetabase= $x100;
dirmetamask= $x3f00;
dirtwiddle= $x100;
dirprime2= dirsubtract= $x200;
dirprime= dircontract= $x400;
dirsection= $x800;
dirop= $x1000;
dirconadd= $x2000;

dirnext= 0;
dirlast= 1; //@0,1=1
dirnext2= 2; //@0,2=2
dirnext3= 3; //@0,3=3

dirprev= 4;
dirfirst= 5; //@1,1=5
dirprev2= 6;
dirprev3= 7;

dirsame= 8; //@2,0=8
dirback1= 9;
dirback2= 10;
dirback3= 11;

dirreverse= 12;
dirrand= 13;
dirrand1= 14;

diropfirst=  dirnext | dirop;
diropprevsec= dirlast | dirop;
diropseq=    dirnext2 | dirop; // |<!
diropresortx=  dirnext3 | dirop; // <!

diroprand=   dirprev | dirop; // ?!
diroptoend=  dirfirst | dirop; // >!
diropend=    dirprev2 | dirop; // >|!
diropsx4=      dirprev3 | dirop;

diroponfirst=  dirsame | dirop;
diroponlast= dirback1 | dirop;
diroponxover=  dirback2 | dirop;
diroponseek=     dirback3 | dirop;

diropboom=   dirreverse | dirop; // >|!
diropheart=   dirrand | dirop; // >|!
diropalien=   dirrand1 | dirop; // >|!

// gfx globals

gfx_charw= 8;
ggw= 572; //gui width; overridden in logo code
ggh= gfx_h;

ggt= 5; //top
ggl= 5; //left

gglh= 16; //label height: == icon bar height

ggto= 2; //base text/icon offset
ggslen= 150; //slider length

ggbco= 32; //buttongrid col offset
ggbcw= 31; //buttongrid col width
ggbro= 20; //buttongrid row offset
ggbrh= 16; //buttongrid row height

ggs2co= 17; //cc slidergrid col offset
ggs2cw= 16; //cc slidergrid col width
ggs2h= 127; //cc slidergrid height

ggsco= 17; //slidergrid col offset
ggscw= 16; //slidergrid col width
ggsh= 127; //slidergrid height (was 100)

ggsuph= 64; //slidergrid up height

ggfr= 0; ggfg= .3; ggfb= 0;           //foreground color
ggbr= .82; ggbg= .95; ggbb= .83;      //ctl background color
gghr= .2; gghg= 1; gghb= .1; ggha= .2; //hilite color
ggsr= 0; ggsg= 0; ggsb= 0; ggsa= .2;  //slider bar color
ggdr= 1; ggdg= 1; ggdb= 1; ggda= .7; //dimming color
ggh2r= .2; ggh2g= 1; ggh2b= .1; ggh2a= .3;
ggba= .65; //alpha for black compositing
ggma= .2; //alpha for mouseovers
ggfa2= .6; //2ndary black alpha
ggcr= $xf8/$xff; ggcg= 1; ggcb= ggcr;
gfx_clear= -1;
gdirt= 1;
gdirtx= 0;

//- arrays and "pointer" vars
mem= 1;
dirsserial= mem; mem+= maxmaxsteps+2; //serial dirs
lens= mem;  mem+= maxmaxsteps+2;
gates= mem; mem+= maxmaxsteps+2;
vcs= mem;   mem+= maxmaxsteps+2;
trans= mem; mem+= maxmaxsteps+2;
ctl1s= mem; mem+= maxmaxsteps+2;
ctl2s= mem; mem+= maxmaxsteps+2;
accs= mem;  mem+= maxmaxsteps+2;
offs= mem;  mem+= maxmaxsteps+2;
seriallen= mem; //for @serialize
notes= mem;    mem+= maxnotes*4+2; //4 octaves max
notesort= mem; mem+= maxnotes*4+2;
vels= mem;     mem+= maxnotes*4+2;
noteslen= mem-notes; //for @serialize
dirs= mem; mem+= maxmaxsteps+2; //active dirs
evtimes= mem;  mem+= maxevs+2;
evmsgs= mem;   mem+= maxevs+2;
evmsg23s= mem; mem+= maxevs+2;
zerolen= mem; //for @init
syncfracs= mem;     mem+= 24;
syncfracsgrid= mem; mem+= 24;
notenm= mem;    mem+= 12;
notenm2= mem;   mem+= 12;
lastnotes= mem; mem+= vcrng+2;
gcoords= mem; mem+= 10; //gfx_extblit params
gdchan= mem;  mem+= 1; //id for chan dropdown
gdctl1= mem;   mem+= 1; //id for cc1 dropdown
gdctl2= mem;   mem+= 1; //id for cc2 dropdown
gdctl3= mem;   mem+= 1; //id for cc3 dropdown
gdctl4= mem;   mem+= 1; //id for cc4 dropdown
gdsortx= mem;  mem+= 1; //id for sortx dropdown
gdvarx= mem;  mem+= 1; //id for variant dropdown
gpt= mem;     mem+= 256; //gfx param: text
gptlen= mem-gpt;
gdt= mem;     mem+= 256; //gfx param: text
gdtlen= mem-gdt;
// slider preset vars - ! in slider order !
slvars= mem; //for presets
slbits= 0;
paused= mem;     slbits|= 2^(mem-slvars); mem+= 1; //dbg row 1
tick= mem;       slbits|= 2^(mem-slvars); mem+= 1;
swing= mem;      slbits|= 2^(mem-slvars); mem+= 1;
mem+= 1;         //chan placeholder
sort= mem;       slbits|= 2^(mem-slvars); mem+= 1;
order= mem;      slbits|= 2^(mem-slvars); mem+= 1;
octaves= mem;    slbits|= 2^(mem-slvars); mem+= 1;
cntvars= mem; //for iterating
dircnt= mem;    slbits|= 2^(mem-slvars); mem+= 1;
lencnt= mem;     slbits|= 2^(mem-slvars); mem+= 1;
gatecnt= mem;    slbits|= 2^(mem-slvars); mem+= 1;
vccnt= mem;      slbits|= 2^(mem-slvars); mem+= 1; //dbg row 2
trancnt= mem;    slbits|= 2^(mem-slvars); mem+= 1;
acccnt= mem;     slbits|= 2^(mem-slvars); mem+= 1;
offcnt= mem;     slbits|= 2^(mem-slvars); mem+= 1;
ctl1cnt= mem;    slbits|= 2^(mem-slvars); mem+= 1;
ctl2cnt= mem;    slbits|= 2^(mem-slvars); mem+= 1;
cntvarslen= mem-cntvars;
hold= mem;       slbits|= 2^(mem-slvars); mem+= 1;
maxsteps= mem;   slbits|= 2^(mem-slvars); mem+= 1;
offpct= mem;     slbits|= 2^(mem-slvars); mem+= 1;
swingsteps= mem; slbits|= 2^(mem-slvars); mem+= 1;
randseq= mem;    slbits|= 2^(mem-slvars); mem+= 1; //dbg row 3
slvarslen053= mem-slvars;
ctl34vars= mem;
ctl3cnt= mem;    slbits|= 2^(mem-slvars); ctl34bits= 2^(mem-slvars);  mem+= 1;
ctl4cnt= mem;    slbits|= 2^(mem-slvars); ctl34bits|= 2^(mem-slvars); mem+= 1;
badtickf= mem; mem+= 1;         //spare placeholder
slvarslen081= mem-slvars;
mem+= 1;         //spare placeholder
mem+= 1;         //spare placeholder
mem+= 1;         //spare placeholder
mem+= 1;         //spare placeholder
mem+= 1;         //spare placeholder
sortx= mem;      slbits|= 2^(mem-slvars); mem+= 1;
resortx= mem;    slbits|= 2^(mem-slvars); mem+= 1;
tickf= mem;      slbits|= 2^(mem-slvars); mem+= 1;
slvarslen082= mem-slvars;
slvarslen= 85;
slvarslen050= 85;
mem+= slvarslen-(mem-slvars);
// pre preset vars
posvars= mem; //for iteration
dirpos= mem; mem+=1;  //dbg row 4
lenpos= mem;  mem+=1;
gatepos= mem; mem+=1;
vcpos= mem;   mem+=1;
tranpos= mem; mem+=1;
ctl1pos= mem; mem+=1;
ctl2pos= mem; mem+=1;
accpos= mem;  mem+=1;
offpos= mem;  mem+=1;
posvarslen= mem-posvars;
ctl3pos= mem; mem+=1; //dbg n/a
ctl4pos= mem; mem+=1; //dbg n/a
// preset vars
prevars= mem; //for @serialize & presets
posvars0= mem; mem+= posvarslen;
oldsortx= mem; mem+= 1; //spare
prever= mem; mem+= 1; //dbg row 5 //preset version
ctl1bi= mem;  mem+=1;
ctl2bi= mem;  mem+=1; 
ctl1cc= mem;  mem+=1;
ctl2cc= mem;  mem+=1;
octpos= mem;  mem+=1;
skin= mem;    mem+=1;
sgrow1dn= mem; mem+=1;
sgrow2dn= mem; mem+=1;
dirdn= mem;  mem+=1;
lendn= mem;   mem+=1; //dbg row 6
gatedn= mem;  mem+=1;
vcdn= mem;    mem+=1;
trandn= mem;  mem+=1;
notecnttmp= mem; mem+=1;
notepostmp= mem; mem+=1;
offuni= mem;  mem+=1;
prevarslen050= mem-prevars;
oldresortx= mem; mem+=1; //spare
prevarslen053= mem-prevars;
octmode= mem; mem+=1;
prevarslen071= mem-prevars;
tranbase= mem; mem+=1; //down tran limit in semitones
tranrng= mem; mem+=1; //displayed tran octaves //dbg row 7
prevarslen076= mem-prevars;
ctl34on= mem; mem+=1;
prevarslen081= mem-prevars;
Xspare2= mem; mem+=1; //spares
mem+=1;
mem+=1;
mem+=1;
mem+=1;
mem+=1;
mem+=1;
mem+=1;
mem+=1;
mem+=1;
Xspare2len= mem-Xspare2;
prevarslen= mem-prevars;

prevars2= mem;
sortxpatlen= 120;
sortxpat= mem; mem+= sortxpatlen;
prevars2len071= mem-prevars2;
ctl3s= mem; mem+= maxmaxsteps+2;
ctl4s= mem; mem+= maxmaxsteps+2;
mem+= (maxmaxsteps+2)*8; //spare seqs
ctl3pos0= mem; mem+=1;
ctl4pos0= mem; mem+=1;
ctl3bi= mem;  mem+=1;
ctl4bi= mem;  mem+=1; 
ctl3cc= mem;  mem+=1;
ctl4cc= mem;  mem+=1;
sgrow3dn= mem; mem+=1;
prevars2len081= mem-prevars2;
prevars2len= 1024;
mem+= prevars2len-(mem-prevars2);
prevars2len053= 100;

vntlen= 16+slvarslen+prevarslen+prevars2len+seriallen;
variants= mem; mem+= maxvnts*vntlen;
vntslvars=   16;
vntprevars=  vntslvars+slvarslen;
vntprevars2= vntprevars+prevarslen;
vntserial=   vntprevars2+prevars2len;
vntmap= mem; mem+=maxvnts;
sortxmap= mem; mem+= maxnotes*10+2;
sortxmaplen= mem-sortxmap-2;
sortxpatcopy= mem; mem+= sortxpatlen;
vntcopy= mem; mem+=vntlen;
sortxmenucnt = 36;
sortxmenu= mem; mem+= sortxmenucnt*17+2;
sortxmenumap= mem; mem+= sortxmenucnt;
sortxmenumap2= mem; mem+= sortxmenucnt;
sortxpre= mem; mem+= sortxpatlen*sortxmenucnt;
sortxprelen= mem-sortxpre;
dirssv= mem; mem+= maxmaxsteps+2;

settings= mem;
hostplay= mem; mem+= 1;
midithru= mem; mem+= 1;
seekclear= mem; mem+= 1;
btnstyle= mem; mem+= 1;
loadnotes= mem; mem+= 1;
midilock= mem; mem+= 1;
mccbase= mem; mem+= 1;
mem+= 25; //spares
colors1=mem;
cclear= mem-colors1; mem+= 3;
cf= mem-colors1; mem+= 3;
cb= mem-colors1; mem+= 3;
ch= mem-colors1; mem+= 4;
cs= mem-colors1; mem+= 4;
cd= mem-colors1; mem+= 4;
ch2= mem-colors1; mem+= 4;
cfa2= mem-colors1; mem+= 1;
ckw= mem-colors1; mem+= 1;
ckb= mem-colors1; mem+= 1;
cstep= mem-colors1; mem+= 5;
clen= mem-colors1; mem+= 5;
cgate= mem-colors1; mem+= 5;
cvc= mem-colors1; mem+= 5;
ctran= mem-colors1; mem+= 5;
cacc= mem-colors1; mem+= 5;
coff= mem-colors1; mem+= 5;
cctl1= mem-colors1; mem+= 5;
cctl2= mem-colors1; mem+= 5;
cfade= mem-colors1; mem+= 3;
cctl3= mem-colors1; mem+= 5;
cctl4= mem-colors1; mem+= 5;
mem+=4; //spares
cdotsha= mem-colors1; mem+= 1;
cdot= mem-colors1; mem+= 1;
cname= mem-colors1; mem+= 24;
colorslen= mem-colors1;
mem+= colorslen*11;
settingslen0= mem-settings;
defcolors= mem; mem+= colorslen*32;
defcolorslen= mem-defcolors;
skincnt0= 5;
skincnt= skincnt0 + (mem-colors1)/colorslen;
settingslen= mem-settings;
stepsmemlen= 100;
stepsmemppos= mem; mem+= stepsmemlen;
stepsmemorev= mem; mem+= stepsmemlen;
stepsmemopos= mem; mem+= stepsmemlen;
randdirs= mem; mem+= maxmaxsteps*(16+8+1) + 1;
stepsdelta= 1; //set when steps seq is edited
consteps= mem; mem+= maxmaxsteps*2*4 + 1; //dbg
constepsmax= mem-consteps-4;

mccbasic= 1;
mccext= 2;
mcccnt= 11;
mccsteps= maxmaxsteps;
mccchanmap= mem;
mem[]= 1;  mem+= 1; //dirs
mem[]= 1;  mem+= 1; //lens
mem[]= 2;  mem+= 1; //gates
mem[]= 2;  mem+= 1; //vcs
mem[]= 2;  mem+= 1; //trans
mem[]= 3;  mem+= 1; //accs
mem[]= 3;  mem+= 1; //offs
mem[]= 3;  mem+= 1; //ctl1s
mem[]= 4;  mem+= 1; //ctl2s
mem[]= 4;  mem+= 1; //ctl3s
mem[]= 4;  mem+= 1; //ctl4s
mccrchanmap= mem;
mem+= 1;
mem[]= 0;  mem+= 1;
mem[]= 2;  mem+= 1;
mem[]= 5;  mem+= 1;
mem[]= 8;  mem+= 1;
mccnummap= mem;
mem[]= 24; mem+= 1; //dirs - uses 2x 32
mem[]= 88; mem+= 1; //lens
mem[]= 24; mem+= 1; //gates
mem[]= 56; mem+= 1; //vcs
mem[]= 88; mem+= 1; //trans
mem[]= 24; mem+= 1; //accs
mem[]= 56; mem+= 1; //offs
mem[]= 88; mem+= 1; //ctl1s
mem[]= 24; mem+= 1; //ctl2s
mem[]= 56; mem+= 1; //ctl3s
mem[]= 88;  mem+= 1;//ctl4s
mccseqmap= mem;
mem[]= dirs;  mem+= 1;
mem[]= lens;  mem+= 1;
mem[]= gates; mem+= 1;
mem[]= vcs;   mem+= 1;
mem[]= trans; mem+= 1;
mem[]= accs; mem+= 1;
mem[]= offs; mem+= 1;
mem[]= ctl1s;  mem+= 1;
mem[]= ctl2s;  mem+= 1;
mem[]= ctl3s; mem+= 1;
mem[]= ctl4s; mem+= 1;
mcccntmap= mem;
mem[]= dircnt;  mem+= 1;
mem[]= lencnt;  mem+= 1;
mem[]= gatecnt; mem+= 1;
mem[]= vccnt;   mem+= 1;
mem[]= trancnt; mem+= 1;
mem[]= acccnt; mem+= 1;
mem[]= offcnt; mem+= 1;
mem[]= ctl1cnt; mem+= 1;
mem[]= ctl2cnt; mem+= 1;
mem[]= ctl3cnt; mem+= 1;
mem[]= ctl4cnt; mem+= 1;
mccposmap= mem;
mem[]= dirpos;  mem+= 1;
mem[]= lenpos;  mem+= 1;
mem[]= gatepos; mem+= 1;
mem[]= vcpos;   mem+= 1;
mem[]= tranpos; mem+= 1;
mem[]= accpos; mem+= 1;
mem[]= offpos; mem+= 1;
mem[]= ctl1pos;  mem+= 1;
mem[]= ctl2pos;  mem+= 1;
mem[]= ctl3pos; mem+= 1;
mem[]= ctl4pos; mem+= 1;
mccintmap= mem;
mem[]= -1; mem+= 1; //dirs
mem[]= 1; mem+= 1;  //lens
mem[]= 0; mem+= 1;  //gates
mem[]= 1; mem+= 1; //vcs
mem[]= 1; mem+= 1;  //trans
mem[]= 0; mem+= 1; //accs
mem[]= 0; mem+= 1; //offs
mem[]= 0; mem+= 1; //ctl1s
mem[]= 0; mem+= 1; //ctl2s
mem[]= 0; mem+= 1; //ctl3s
mem[]= 0; mem+= 1; //ctl4s
mccrngmap= mem;
mem[]= 0;  mem+= 1; //dir - n/a
mem[]= lenrng;  mem+= 1;
mem[]= gaterng; mem+= 1;
mem[]= vcrng;   mem+= 1;
mem[]= tranrng; mem+= 1; //tran - mem loc
mem[]= accrng; mem+= 1;
mem[]= offrng; mem+= 1;
mem[]= ctl1rng;  mem+= 1;
mem[]= ctl2rng;  mem+= 1;
mem[]= ctl3rng; mem+= 1;
mem[]= ctl4rng; mem+= 1;

deltaslen= mccsteps * 2 + 4; // max at once is mccsteps; >2 in a row???
deltaseqs= mem; mem+= deltaslen;
deltasteps= mem; mem+= deltaslen;

dbgt=mem; mem+=10000;
dbgtlen= mem-dbgt;
dbgt[]= 0;
dbgp= dbgt;
dbgvis= dbgon= 0;

!vntcnt || !(vntmap[0]) ?(
  vntcnt= 1; vnt= 0;
  vv= 0; loop ( maxvnts, 
    vntmap[vv]= variants+vntlen*vv;
    vv+= 1; 
  );
);

//filename consts
fnstep0= 0; //fn???0
fntran0= 4;
fnsort0= 17;
fnorder0= 19;
fnsync0= 26;
fnchan0= 27;
fncc1= 28;
fncc2= 3;
fnplay= 0;
fnpause= 2;
fnclear= 29;
fnhold= 30;
fnsettings= 31;
fndefcolors= 32;
fnlen0= 33;
fnlenb0= 48;
fnvc0= 41;
fnvcb0= 56;
fnsortxpre= 63;
fnsortxdefpre= 64;
fndirtypes= 65;
fndirtypes2= 66;
fnconadd= 1;

// special chars
uarrow= 24;
darrow= 25;
rarrow= 26;
dtri= 31;

!init1 ?(

  // init slider vars 
  //   also init in @slider, but here to put at top of debug
  chan= 0;
  chanbus= 0;
  maxsteps[]= 16;
  paused[]= 0;
  tick[]= 6;
  tickf[]= 0;
  lasttick= 0;
  swing[]= 0;
  sort[]= 0;
  order[]= 0;
  octaves[]= 0;
  dircnt[]= 8;
  lencnt[]= 8;
  gatecnt[]= 8;
  vccnt[]= 8;
  trancnt[]= 8;
  acccnt[]= 8;
  offcnt[]= 8;
  ctl1cnt[]= 8;
  ctl2cnt[]= 8;
  ctl3cnt[]= 8;
  ctl4cnt[]= 8;
  hold[]= 0;
  offpct[]= 10;
  swingsteps[]= 2;
  randseq[]= 0;
  sortx[]= 0;
  resortx[]= resortxfirst | resortxoct;

  // other serialized vars: init once
  notecnt= notecnt0= lastnotecnt= 0;
  playpos= -1;
  mccenable= mccbasic;
  octpos[]= 0;
  ctl1cc[]= -2;
  ctl2cc[]= -2;
  ctl3cc[]= -2;
  ctl4cc[]= -2;
  skin[]= 0;
  lastskin= -1;
  dirdn[]= 0;
  lendn[]= 0;
  gatedn[]= 0;
  vcdn[]= 0;
  trandn[]= 0;
  sgrow1dn[]= 0;
  sgrow2dn[]= 0;
  sgrow3dn[]= 0;
  dirpos[]= 0;
  lenpos[]= 0;
  gatepos[]= 0;
  vcpos[]= 0;
  tranpos[]= 0;
  accpos[]= 0;
  offpos[]= 0;
  ctl1pos[]= 0;
  ctl2pos[]= 0;
  ctl3pos[]= 0;
  ctl4pos[]= 0;
  offbi= 0;
  ctl1bi[]= 0;
  ctl2bi[]= 0;
  ctl3bi[]= 0;
  ctl4bi[]= 0;
  hostplay[]= 1;
  midithru[]= 1;
  seekclear[]= 1;
  loadnotes[]= 0;
  midilock[]= 0;
  mccbase[]= 32;
  octmode[]= 0;
  tranbase[]= 12;
  tranrng[]= 24;

  memset(0,0,zerolen);
  memset(dirs,dirdef,maxmaxsteps);
  memset(lens,lendef,maxmaxsteps);
  memset(gates,gatedef,maxmaxsteps);
  memset(vcs,vcdef,maxmaxsteps);
  memset(trans,trandef,maxmaxsteps);
  memset(accs,accdef,maxmaxsteps);
  memset(offs,offdef,maxmaxsteps);
  memset(ctl1s,ctl1def,maxmaxsteps);
  memset(ctl2s,ctl2def,maxmaxsteps);
  memset(ctl3s,ctl3def,maxmaxsteps);
  memset(ctl4s,ctl4def,maxmaxsteps);
  
  //calc beat fractions
  syncfracs[0]= .0625; syncfracsgrid[0]= 0; // 1/64
  ii= 0;
  jj= 0;
  loop ( 7,
    syncfracs[ii+1]= syncfracs[ii] * 2 * 2/3; syncfracsgrid[ii+1]= 10+jj; //2x triplet
    syncfracs[ii+2]= syncfracs[ii] * 1.5;     syncfracsgrid[ii+2]= 20+jj; //dotted 
    syncfracs[ii+3]= syncfracs[ii] * 2;       syncfracsgrid[ii+3]= jj+1;
    ii+= 3;
    jj+= 1;
  );
  syncfracs[22]= 3*4; syncfracsgrid[22]= 17;
  syncfracs[23]= 4*4; syncfracsgrid[23]= 27;
  
  //note names
  notenm[0]= $'c'; notenm2[0]= 0;
  notenm[1]= $'c'; notenm2[1]= $'#';
  notenm[2]= $'d'; notenm2[2]= 0;
  notenm[3]= $'d'; notenm2[3]= $'#';
  notenm[4]= $'e'; notenm2[4]= 0;
  notenm[5]= $'f'; notenm2[5]= 0;
  notenm[6]= $'f'; notenm2[6]= $'#';
  notenm[7]= $'g'; notenm2[7]= 0;
  notenm[8]= $'g'; notenm2[8]= $'#';
  notenm[9]= $'a'; notenm2[9]= 0;
  notenm[10]= $'a'; notenm2[10]= $'#';
  notenm[11]= $'b'; notenm2[11]= 0;
    
  dOffset= slvars; //dbg
  
  init1= 1;
);

/////- @slider
@slider

!(midilock[]) ?(
  chan= slider4 & $xf; //not in variants
  chanbusx= (slider4/16) & $xf;
  chanbusx != chanbus ? evclear= 1;
);
paused[]= slider1;
paused[] ?(
  evclear= 1;
  //midithru[] ?( noteclear= 1; );
);
tick[]= slider2;
tickf[]= slider32;
swing[]= slider3;
sort[]= slider5;
order[]= slider6;
octaves[]= slider7;
octpos[]= min(octpos[],octaves[]);
maxsteps[]= slider18; //do this before restoring seq cnts
dircnt[]= min(maxsteps[],slider8);
lencnt[]= min(maxsteps[],slider9);
gatecnt[]= min(maxsteps[],slider10);
vccnt[]= min(maxsteps[],slider11);
trancnt[]= min(maxsteps[],slider12);
acccnt[]= min(maxsteps[],slider13);
offcnt[]= min(maxsteps[],slider14);
ctl1cnt[]= min(maxsteps[],slider15);
ctl2cnt[]= min(maxsteps[],slider16);
hold[]= slider17;
offpct[]= slider19 <= 50 ? slider19 : 100; //allow continuous change up to 50%???
swingsteps[]= min(16,max(2,slider20));
randseq[]= slider21;
ctl3cnt[]= max(min(maxsteps[],slider22),1);
ctl4cnt[]= max(min(maxsteps[],slider23),1);
slider24= slider25= slider26= slider27= slider28= slider29= -2350081; //set spares to odd value
sortx[]= slider30 != -2350081 ? slider30 : 0;
resortx[]= slider31 != -2350081 ? slider31 : resortxfirst | resortxoct;

/////- @serialize
   //    file_avail(0) >= 0 ?( // reading?
@serialize

serialread= (file_avail(0) >= 0);
//serialread ? serialreadcnt+= 1; //dbg

dirsaved ?(
  dirsaved=0;
  memcpy(dirs,dirssv,maxmaxsteps);
  dircnt[]= dircntsv;
  dirpos[]= dirpossv;
); 

// preset versions
prever050= -23420050; //in oldprever
prever053= 2350053; //in prever[]; 23420053 too big for preset mem precision
prever071= 2350071;
prever076= 2350076;
prever081= 2350081;
prever082= 2350082;
serialread ? prever[]= 0 : prever[]= prever082; // reading:writing?

// copy active prevars into serialize copy for write
// primary variant values: seq positions++
notecnttmp[]= notecnt0;
notepostmp[]= notepos;
offuni[]= !offbi;
memset(Xspare2,0,Xspare2len);
//memcpy(posvars0, posvars, posvarslen); //"random" saves make this undesirable

file_mem(0,prevars,prevarslen050); //read older values, including preset version

serialread ? aareadprever= prever[]; //dbg
// based on preset version, read rest of prevars
slvarslen0= slvarslen053;
prever[] < prever053 ?(
  file_mem(0,prevars+prevarslen050,prevarslen-prevarslen050);
  memset(prevars+prevarslen050,0,prevarslen-prevarslen050);
  octmode[]= 1;
  tranbase[]= 12;
  tranrng[]= 24;
): prever[] == prever053 ?(
  file_mem(0,prevars+prevarslen050,prevarslen053-prevarslen050);
  memset(prevars+prevarslen053,0,prevarslen-prevarslen053);
  octmode[]= 1;
  tranbase[]= 12;
  tranrng[]= 24;
  prevarslen0= prevarslen053;
  prevars2len0= prevars2len053;
): prever[] == prever071 ?(
  file_mem(0,prevars+prevarslen050,prevarslen071-prevarslen050);
  memset(prevars+prevarslen071,0,prevarslen-prevarslen071);
  tranbase[]= 12;
  tranrng[]= 24;
  prevarslen0= prevarslen071;
  prevars2len0= prevars2len071;
): prever[] == prever076 ?(
  file_mem(0,prevars+prevarslen050,prevarslen076-prevarslen050);
  memset(prevars+prevarslen076,0,prevarslen-prevarslen076);
  prevarslen0= prevarslen076;
  prevars2len0= prevars2len071;
): prever[] == prever081 || prever[] == prever082 ?(
  file_mem(0,prevars+prevarslen050,prevarslen081-prevarslen050);
  memset(prevars+prevarslen081,0,prevarslen-prevarslen081);
  prevarslen0= prevarslen081;
  prevars2len0= prevars2len081;
  slvarslen0= prever[] == prever081 ? slvarslen081 : slvarslen082;
);

// copy serialize prevars into active after read
serialread ?(
  ctl1def= ctl1bi[]?64:0;
  ctl2def= ctl2bi[]?64:0; 
  octpos[]= min(octpos[],octaves[]);
  loadnotes[] && notecnttmp[] ?( notecnt0= notecnttmp[]; notepos= notepostmp[]; notecnt0x= 1; lastnotecnt= 0; );
  offbi= !(offuni[]);
  offdef= offbi?50:0; 
  memcpy(posvars, posvars0, posvarslen);
);

// seq step values 
memcpy(dirsserial,dirs,maxmaxsteps+2); //copy active dirs into serialize buf
file_mem(0,0,seriallen);
serialread ? memcpy(dirs,dirsserial,maxmaxsteps+2); //copy serialized dirs into active dirs

// current notes
memcpy(mem,notes,maxnotes);
memcpy(mem+maxnotes,notesort,maxnotes);
memcpy(mem+maxnotes+maxnotes,vels,maxnotes);
prever[] < prever071 ?(
  file_mem(0,mem,198);
  loadnotes[] && notecnttmp[] ?(
    memcpy(notes,mem,maxnotes);
    memcpy(notesort,mem+maxnotes+2,maxnotes);
    memcpy(vels,mem+maxnotes+2+maxnotes+2,maxnotes);
  );
):( 
  file_mem(0,mem,maxnotes*3);
  loadnotes[] && notecnttmp[] ?(
    memcpy(notes,mem,maxnotes);
    memcpy(notesort,mem+maxnotes,maxnotes);
    memcpy(vels,mem+maxnotes+maxnotes,maxnotes);
  );
);

serialread ?( // init vntmap if reading?
  vv= 0; loop ( maxvnts, 
    vntmap[vv]= variants+vntlen*vv;
    vv+= 1; 
  );
);

// check version
prever[] < prever053 ?( //only read oldprever if reading preset < v053
  oldprever= 0; // reading
  file_var(0,oldprever);
  aareadprever= oldprever;
);

// 2ndary variant values: sortxpat
prever[] >= prever053 || oldprever == prever050 ?(
  // brave new world:
  prever[] < prever053 ?(
    memset(prevars2,0,prevars2len);
    sortx[]= slider30= 0; slider_automate(slider30);
    resortx[]= slider31= resortxfirst | resortxoct; slider_automate(slider31);
  ):(
    file_mem(0,prevars2,prevars2len0);
    memset(prevars2+prevars2len0,0,prevars2len-prevars2len0);
    ii= -1; while ( sortxpat[ii+=1] || sortxpat[ii+=1] || sortxpat[ii+=1] || sortxpat[ii+=1] || sortxpat[ii+=1] || sortxpat[ii+=1]; );
    sortxpatcnt= ii-5;
    prever[] < prever081 ?(
      ctl3cc[]= ctl4cc[]= -2;
      ctl3cnt[]= slider22= ctl4cnt[]= slider23= 8; 
      slider_automate(slider22); slider_automate(slider23);
      sval= tick[]-(tick[]|0); //backwards compat w/ tick frac in slider2
      sval ?( 
        tick[]= tick[]|0;
        sval < 0 ? tick[]-= 1;
        slider2= tick[];
        tickf[]= slider32= abs(sval);
        slider_automate(slider2); slider_automate(slider32);
      ):(
        tickf[]= slider32= 0; slider_automate(slider32);
      );
      sii= -1; loop ( maxmaxsteps, sii+= 1;
        svv= 0;
        (dirs[sii] & dirmask) == 15 ?( //old dirop 
          dirs[sii] & $x100 ? dirs[sii]= diropend
          : dirs[sii] & $x200 ? dirs[sii]= 1 | dirop //diroptoend
          : dirs[sii] & $x400 ? dirs[sii]= diroprand
          : dirs[sii] & $x800 ? dirs[sii]= diropfirst
          : dirs[sii]= 3 | dirop; //diropprevsec;
        ):(
          dirs[sii] & $x100 ? svv|= dirsubtract;
          dirs[sii] & $x200 ? svv|= dircontract;
          dirs[sii] & $x400 ? svv|= dirtwiddle;
          dirs[sii] & $x800 ? svv|= dirsection;
          dirs[sii]= (dirs[sii] & dirmask) | svv;
        );
      );
    );
    prever[] < prever082 ?(
      sii= -1; loop ( maxmaxsteps, sii+= 1;
        svv= dirs[sii] & dirmask;
          svv==1 ? dirs[sii]= (dirs[sii] & dirmetamask) | dirfirst
        : svv==2 ? dirs[sii]= (dirs[sii] & dirmetamask) | dirsame
        : svv==3 ? dirs[sii]= (dirs[sii] & dirmetamask) | dirlast
        : svv==5 ? dirs[sii]= (dirs[sii] & dirmetamask) | dirnext2
        : svv==8 ? dirs[sii]= (dirs[sii] & dirmetamask) | dirnext3;
      );
      sortx[]= slider30= oldsortx[]; slider_automate(slider30);
      resortx[]= slider31= oldresortx[]; slider_automate(slider31);
    );
  ); 
  serialread ?(
    ctl3pos[]= ctl3pos0[]; ctl4pos[]= ctl4pos0[];
    ctl3def= ctl3bi[]?64:0;
    ctl4def= ctl4bi[]?64:0; 
  );
  
  // non-variant values
  file_var(0,vntcnt);
  file_var(0,vnt);
  mcenable0= mcenable;
  file_var(0,mccenable0);
  serialread && !(midilock[]) ?(
    prever[] < prever082 ?( mccenable= mccenable0 < 0 ? 0 : mccbasic; )
                         : mccenable= mccenable0;
  );
    
  // variants
  prever[] < prever053 ?(
    vv= 0; loop ( vntcnt,
      file_mem(0,vntmap[vv]+vntslvars,slvarslen050);
      file_mem(0,vntmap[vv]+vntprevars,prevarslen);
      file_mem(0,vntmap[vv]+vntprevars2,prevars2len);
      file_mem(0,vntmap[vv]+vntserial,seriallen);
      memset(vntmap[vv]+vntslvars+slvarslen053,0,slvarslen-slvarslen053);
      memset(vntmap[vv]+vntprevars+prevarslen050,0,prevarslen-prevarslen050);
      memset(vntmap[vv]+vntprevars2,0,prevars2len);
      (vntmap[vv]+vntprevars)[octmode-prevars]= 1;
      (vntmap[vv]+vntprevars)[tranbase-prevars]= 12;
      (vntmap[vv]+vntprevars)[tranrng-prevars]= 24;
      (vntmap[vv]+vntprevars2)[ctl3cc-prevars2]= -2;
      (vntmap[vv]+vntprevars2)[ctl4cc-prevars2]= -2;
      (vntmap[vv]+vntslvars)[ctl3cnt-slvars]= 8;
      (vntmap[vv]+vntslvars)[ctl4cnt-slvars]= 8;
      vv+= 1;
    );
  ):(
    vv= 0; loop ( vntcnt,
      file_mem(0,vntmap[vv]+vntslvars,slvarslen0);
      file_mem(0,vntmap[vv]+vntprevars,prevarslen0);
      file_mem(0,vntmap[vv]+vntprevars2,prevars2len0);
      file_mem(0,vntmap[vv]+vntserial,seriallen);
      memset(vntmap[vv]+vntslvars+slvarslen0,0,slvarslen-slvarslen0);
      memset(vntmap[vv]+vntprevars+prevarslen0,0,prevarslen-prevarslen0);
      memset(vntmap[vv]+vntprevars2+prevars2len0,0,prevars2len-prevars2len0);
      prever[] < prever071 ? (vntmap[vv]+vntprevars)[octmode-prevars]= 1;
      prever[] < prever076 ?(
        (vntmap[vv]+vntprevars)[tranbase-prevars]= 12;
        (vntmap[vv]+vntprevars)[tranrng-prevars]= 24; 
      );
      prever[] < prever081 ?(
        (vntmap[vv]+vntprevars2)[ctl3cc-prevars2]= -2;
        (vntmap[vv]+vntprevars2)[ctl4cc-prevars2]= -2;
        (vntmap[vv]+vntslvars)[ctl3cnt-slvars]= 8;
        (vntmap[vv]+vntslvars)[ctl4cnt-slvars]= 8;
        sii= -1; loop ( maxmaxsteps, sii+= 1;
          svv= 0;
          ((vntmap[vv]+vntserial)[dirs+sii] & dirmask) == 15 ?(
            (vntmap[vv]+vntserial)[dirs+sii] & $x100 ? (vntmap[vv]+vntserial)[dirs+sii]= diropend
            : (vntmap[vv]+vntserial)[dirs+sii] & $x200 ? (vntmap[vv]+vntserial)[dirs+sii]= 1 | dirop //diroptoend
            : (vntmap[vv]+vntserial)[dirs+sii] & $x400 ? (vntmap[vv]+vntserial)[dirs+sii]= diroprand
            : (vntmap[vv]+vntserial)[dirs+sii] & $x800 ? (vntmap[vv]+vntserial)[dirs+sii]= diropfirst
            : (vntmap[vv]+vntserial)[dirs+sii]= 3 | dirop; //diropprevsec;
          ):(
            (vntmap[vv]+vntserial)[dirs+sii] & $x100 ? svv|= dirsubtract;
            (vntmap[vv]+vntserial)[dirs+sii] & $x200 ? svv|= dircontract;
            (vntmap[vv]+vntserial)[dirs+sii] & $x400 ? svv|= dirtwiddle;
            (vntmap[vv]+vntserial)[dirs+sii] & $x800 ? svv|= dirsection;
            (vntmap[vv]+vntserial)[dirs+sii]= ((vntmap[vv]+vntserial)[dirs+sii] & dirmask) | svv;
          );
        );
      );
      prever[] < prever082 ?(
        sii= -1; loop ( maxmaxsteps, sii+= 1;
          svv= (vntmap[vv]+vntserial)[dirs+sii] & dirmask;
            svv==1 ? (vntmap[vv]+vntserial)[dirs+sii]= ((vntmap[vv]+vntserial)[dirs+sii] & dirmetamask) | dirfirst
          : svv==2 ? (vntmap[vv]+vntserial)[dirs+sii]= ((vntmap[vv]+vntserial)[dirs+sii] & dirmetamask) | dirsame
          : svv==3 ? (vntmap[vv]+vntserial)[dirs+sii]= ((vntmap[vv]+vntserial)[dirs+sii] & dirmetamask) | dirlast
          : svv==5 ? (vntmap[vv]+vntserial)[dirs+sii]= ((vntmap[vv]+vntserial)[dirs+sii] & dirmetamask) | dirnext2
          : svv==8 ? (vntmap[vv]+vntserial)[dirs+sii]= ((vntmap[vv]+vntserial)[dirs+sii] & dirmetamask) | dirnext3;
        );
        (vntmap[vv]+vntslvars)[tickf-slvars]=   (vntmap[vv]+vntslvars)[badtickf-slvars];
        (vntmap[vv]+vntslvars)[sortx-slvars]=   (vntmap[vv]+vntprevars)[oldsortx-prevars];
        (vntmap[vv]+vntslvars)[resortx-slvars]= (vntmap[vv]+vntprevars)[oldresortx-prevars];
      );
      vv+= 1;
    );
  );
  serialread ? dosortx= sortx[]; //do after loading variants
):(
  // reading < v0.50 preset: use defaults
  sortx[]= slider30= 0; slider_automate(slider30);
  resortx[]= slider31= resortxfirst | resortxoct; slider_automate(slider31);
  vntcnt= 1;
  vnt= 0;
  mccenable= 0;
  offuni[]= !offbi;
  memset(prevars2,0,prevars2len);
  memcpy(vntmap[0]+vntslvars,slvars,slvarslen);
  memcpy(vntmap[0]+vntprevars,prevars,prevarslen);
  memcpy(vntmap[0]+vntprevars2,prevars2,prevars2len);
  memcpy(vntmap[0]+vntserial,0,seriallen);
);
serialread ?( alltomidi= 1; lastskin= -1; );
stepsdelta= gdirtx= 1;

/////- @block
@block

// load global settings
!gotsettings ?(
  memset(settings,0,settingslen);
  hh= file_open(fndefcolors);
  hh >= 0 ?(
    file_mem(hh,defcolors,defcolorslen);
    file_close(hh);
  );
  hh= file_open(fnsettings);
  hh >= 0 ?(
    file_mem(hh,settings,settingslen0);
    file_close(hh);
    midilock[] ?(
      chan= max(min((midilock[] & $x1f) - 1, 15), 0);
      chanbus= max(min((midilock[] / 32 & $x1f) - 1, 15), 0);
      mccenable= midilock[] / 1024 & $x3;
    );
    mccbase[] == 0 ? mccbase[]= 32;
  ):(
    skin[] >= 5 ? skin[]= 0;
    hostplay[]= 1;
    midithru[]= 1;
    seekclear[]= 1;
    loadnotes[]= 0;
    midilock[]= 0;
    mccbase[]= 32;
  );
  gdirtx= 1;
  lastskin= -1;
  gotsettings= 1;
);

// restore saved play positions if playback just started
//   & unpause if hostplay on; before midi so noteons register
playon= playoff= 0;
play_state & 1 && ! lastplaying ?(
  memcpy(posvars, posvars0, posvarslen); ctl3pos[]= ctl3pos0[]; ctl4pos[]= ctl4pos0[];
  hostplay[] ?( slider1= paused[]= 0; slider_automate(slider1); );
  lastplaying= 1;
  playon= 1;
  gdirtx= 1;
  onseekdo= 0; //clear any onseek from prior stop & rewind
);

// clear notes on host seek
sought= 0;
playchg= play_position-lastplaypos;
playchg < -.25 || playchg > .25 ?( //samplesblock varies on seeks, so not: (samplechg < -samplesblock*2.5 || samplechg > samplesblock*2.5) ?(
  seekclear[] ?( 
    notecnt= notecnt0= lastnotecnt= 0; // clear notes on seek 
    evclear= gdirtx= 1;
  );
  sought= 1;
  !playon ? onseekdo= 1;
);
lastplaypos = play_position;

// clear notes on qui request
noteclear ?( noteclear= notecnt= notecnt0= lastnotecnt= 0; );

// clear events if flag set in gfx; before midi so new notes not cleared
evclear ?(
  // send all pending noteoffs
  midi_bus= chanbus;
  ii= 0; loop ( evcnt,
    (evmsgs[ii] & $xf0) == $x80 ?(
      midisend(0,evmsgs[ii],evmsg23s[ii]);
    );
    ii+= 1;
  );
  evcnt= 0;
  lastcnt= 0;
  chanbus != chanbusx ?( chanbus= chanbusx; slider4= chan + chanbus*16; slider_automate(slider4); );
      //only change chanbus after clearing notes
  evclear= 0;
);
  
//- process midi
while (
  midirecv(ts,msg,msg23) ?(
    msgchan= msg & $xf;
    // our channel?
    midi_bus == chanbus && msgchan == chan ?(  
      // note on or off
      (msg & $xe0) == $x80 && !(midithru[] && paused[] && playoffcnt) ?(
        vel= (msg23 / 256) & $xff;
        note= msg23 & $xff;
        
        // hold[]
        holding= hold[];
        holding && notecnt0 && msg&$x10 && vel ?( 
          ii= 0; while (
            notes[ii] == note ?( holding= vel= 0; ii= notecnt0; ); //fake noteoff
            (ii+= 1) < notecnt0;
          );
        );
        
        // note on
        msg & $x10 && vel ?(
          // add to arp notes
          notecnt0 < maxnotes ?(
            notes[notecnt0]= note;
            vels[notecnt0]= vel;
            // add to sorted notes
            ii= notecnt0-1;
            while (
              ii >= 0 && note < notes[notesort[ii]] ?(
                notesort[ii+1]= notesort[ii];
                ii-= 1;
                1;
              ):(
                notesort[ii+1]= notecnt0;
                0;
              );
            );
            notecnt0+= 1; 
            notecnt0x= gdirtx= 1;
          );
  
        // note off
        ): !holding ?(
          // del from arp notes
          notecnt0 > 1 ?(
            copy= ii= 0;
            while (
              !copy && notes[ii] == note ?( 
                notecnt0-= 1;
                // delete matching note from notesort
                jj= 0;
                while (
                  !copy && notesort[jj] == ii ? copy= 1;
                  copy ? notesort[jj]= notesort[jj+1];
                  notesort[jj] > ii ? notesort[jj]-= 1; //fix index value
                  (jj+= 1) < notecnt0;
                );
                playpos > ii ? playpos-= 1;
                copy= 1;
              );
              copy ?(  
                notes[ii]= notes[ii+1]; 
                vels[ii]= vels[ii+1]; 
              );
              (ii+= 1) < notecnt0;
            );
            notecnt0x= gdirtx= 1;
          ): notecnt0 == 1 ?(
            notecnt= notecnt0= lastnotecnt= 0;
          );
        );
        
      // not note off/on
      ):(
        // cc enabled, is cc & in our range?
        mccenable >= mccbasic && (msg & $xf0) == $xb0 ?(
          xx= 1;
          msg2= msg23 & $xff;
          msg3= (msg23/256) & $xff;
          msg2 == mccbase[] ? newvnt= min(msg3, vntcnt-1) | pcnosave | pcdopos
          : msg2 == mccbase[] + 1 ?( pcdopos= msg3 ? vntdopos : 0; ) // set do pos reset
          : msg2 == mccbase[] + 2 ?( pcnosave= msg3 ? vntnosave : 0; ) // set no save prev values
          : msg2 == mccbase[] + 3 && msg3 ?( newvnt= (vnt < vntcnt-1 ? vnt+1 : 0) | pcnosave | pcdopos; ) //next variant
          : msg2 == mccbase[] + 4 && msg3 ?( newvnt= (vnt > 0 ? vnt-1 : vntcnt - 1) | pcnosave | pcdopos; ) //prev variant
          : msg2 == mccbase[] + 5 && msg3 ?( memcpy(posvars, posvars0, posvarslen); ctl3pos[]= ctl3pos0[]; ctl4pos[]= ctl4pos0[]; ) // restore saved play positions
          : msg2 == mccbase[] + 6 && msg3 ?( slider1= paused[]= 0; slider_automate(slider1); ) //play
          : msg2 == mccbase[] + 7 && msg3 ?( slider1= paused[]= 1; slider_automate(slider1); evclear= 1; ) //pause
          : msg2 == mccbase[] + 8 && msg3 ?( noteclear= 1; ) //clear
          : msg2 == mccbase[] + 9 && msg3 ?( slider17= hold[] = !(hold[]); slider_automate(slider17); ) //hold
          : msg2 >= mccbase[] + 16 && msg2 < mccbase[] + 16 + mcccnt ?( //seq play positions
            (mccposmap[msg2-(mccbase[]+16)])[]= min(msg3,(mcccntmap[msg2-(mccbase[]+16)])[] - 1);
          ):( midisend(ts,msg,msg23); xx= 0; );
          xx ? gdirtx= 1;
        ):(
          midisend(ts,msg,msg23);
        );
      );      
    // not our channel
    ):(
      msgtype= msg & $xf0;
      // extended midi cc: base chan + 1-4
      mccenable >= mccext && msgtype == $xb0 && msgchan >= chan+mccchanmap[0] && msgchan <= chan+mccchanmap[mcccnt-1] ?(
        msg2= msg23 & $xff;
        msg3= (msg23/256) & $xff;
        ii= msgchan - chan;
        // dir metas?
        ii == mccchanmap[0] && msg2 >= mccnummap[0]+mccsteps && msg2 < mccnummap[0]+mccsteps+mccsteps ?(
          vv= (msg3*dirmetabase) & dirmetamask;
          vv & dirsubtract ? vv&= $xffffff-dircontract;
          !(vv & dircontract) ? vv&= $xffffff-dirconadd;
          dirs[msg2-(mccnummap[0]+mccsteps)]= vv + (dirs[msg2-(mccnummap[0]+mccsteps)] & dirmask);
          gdirtx= 1;
        ):(
          // seq values?
          jj= mccrchanmap[ii]; while (
            msg2 >= mccnummap[jj] && msg2 < mccnummap[jj]+mccsteps ? 0
            : (jj+= 1) < mcccnt && mccchanmap[jj] == ii;
          );
          jj < mcccnt && mccchanmap[jj] == ii ?(
            ndx= msg2-mccnummap[jj]; //seq ndx
            seq= mccseqmap[jj];
            seq == dirs ?( msg3 < dirbaserng ?( dirs[ndx]= msg3 + (dirs[ndx] & ($xffffff-dirmask)) ); )
            : seq == trans ?( msg3 <= tranrng[] ?( trans[ndx]= msg3; ); )
            : mccintmap[jj] ?( msg3 < mccrngmap[jj] ?( seq[ndx]= msg3; ); )
            :( seq[ndx]= msg3 * mccrngmap[jj] / 127; );
            gdirtx= 1;
          // not our cc's
          ): midisend(ts,msg,msg23);
        );
      // not our cc chan's
      ): midisend(ts,msg,msg23);
    ); 
    1; //loop after all midirecv
  ):0; //noloop if !midirecv
); // while midirecv

// send midi from gfx edits
deltas ?(
  deltas= 0; //quickly: minimize chance of stomping "deltas= 1" in gfx
  mccenable >= mccext ?(
    midi_bus= chanbus;
    kk= 0;
    ii= -1; loop ( deltaslen, ii+= 1;
      vv= deltaseqs[ii];
      vv ?( 
        kk+= 1;
        vv == dirs ?(
          mccchanmap[0]+chan < 16 ?(
            midisend( 0, $xb0+mccchanmap[0]+chan, mccnummap[0]+deltasteps[ii] + (dirs[deltasteps[ii]] & dirmask) * 256 );
            midisend( 0, $xb0+mccchanmap[0]+chan, mccnummap[0]+32+deltasteps[ii] + ((dirs[deltasteps[ii]] & dirmetamask) / dirmetabase) * 256 );
          );
        ):(
          jj= 0; mccchanmap[jj]+chan < 16 ? while ( 
            vv == mccseqmap[jj] ?( 
              mccintmap[jj] ? midisend( 0, $xb0+mccchanmap[jj]+chan, mccnummap[jj]+deltasteps[ii] + vv[deltasteps[ii]] * 256 )
                            : midisend( 0, $xb0+mccchanmap[jj]+chan, mccnummap[jj]+deltasteps[ii] + ((vv[deltasteps[ii]] * 127 / mccrngmap[jj]) | 0) * 256 );
              0;
            ):(
              (jj+= 1) < mcccnt && mccchanmap[jj]+chan < 16;
            );
          );
        );
        deltaseqs[ii]= 0;
      );
    );
    deltasmax < kk ? deltasmax= kk; //dbg
  ):(
    memset(deltaseqs,0,deltaslen);
  );
);

// changed input notes lists
notecnt0x ?(
  // replicate input notes/sorted notes/vels into higher octaves
  !(octmode[]) && octaves[] ?(
    ii= 0; loop ( notecnt0 * octaves[],
      notes[ii+notecnt0]= notes[ii] + 12;
      notesort[ii+notecnt0]= notesort[ii] + notecnt0;
      vels[ii+notecnt0]= vels[ii];
      ii+= 1;
    );
    notecnt = notecnt0 + notecnt0 * octaves[];
  ): notecnt= notecnt0;
  !notecnt ? lastnotecnt= 0;
  notecnt0x= 0;
  dosortx= sortx[];
);

// pause if host stops playing; after midi so final noteoffs register
!(play_state & 1) && lastplaying ?(
  hostplay[] ?( slider1= paused[]= 1; slider_automate(slider1); evclear= 1; );
  lastplaying= 0;
  playoff= 1;
  gdirtx= 1;
  playoffcnt= 0;
): !(play_state & 1) ?(
  playoffcnt= 1; 
      //track 1st @block since playoff because noteoffs after pause arrive
      //  one @block after play_state becomes paused
);

//- do new variant
newvnt >= 0 ?(
  dirsaved ?(
    memcpy(dirs,dirssv,maxmaxsteps);
    dircnt[]= dircntsv;
    dirpos[]= dirpossv;
    dirsaved=0;
  ); 
  !(newvnt & vntnosave) ?(
    offuni[]= !offbi;
    memcpy(dirsserial,dirs,maxmaxsteps+2);
    vntedit ?(
      ii=0; loop ( slvarslen,
        (vntmap[vnt]+vntslvars)[ii] != slvars[ii] ?(
          vv= 0; loop ( vntcnt, (vntmap[vv]+vntslvars)[ii]= slvars[ii]; vv+= 1; );
        );
        ii+= 1;
      );
      ii=0; loop ( prevarslen,
        (vntmap[vnt]+vntprevars)[ii] != prevars[ii] ?(
          vv= 0; loop ( vntcnt, (vntmap[vv]+vntprevars)[ii]= prevars[ii]; vv+= 1; );
        );
        ii+= 1;
      );
      ii=0; loop ( prevars2len,
        (vntmap[vnt]+vntprevars2)[ii] != prevars2[ii] ?(
          vv= 0; loop ( vntcnt, (vntmap[vv]+vntprevars2)[ii]= prevars2[ii]; vv+= 1; );
        );
        ii+= 1;
      );
      ii=0; loop ( seriallen,
        (vntmap[vnt]+vntserial)[ii] != 0[ii] ?(
          vv= 0; loop ( vntcnt, (vntmap[vv]+vntserial)[ii]= 0[ii]; vv+= 1; );
        );
        ii+= 1;
      );
    ):(    
      memcpy(vntmap[vnt]+vntslvars,slvars,slvarslen);
      memcpy(vntmap[vnt]+vntprevars,prevars,prevarslen);
      memcpy(vntmap[vnt]+vntprevars2,prevars2,prevars2len);
      memcpy(vntmap[vnt]+vntserial,0,seriallen);
(vntmap[vnt]+vntserial)[0]= -(vnt+1);//debug
    );
  );
  vnt= newvnt & vntmask;
  memcpy(slvars,vntmap[vnt]+vntslvars,slvarslen);
  memcpy(prevars,vntmap[vnt]+vntprevars,prevarslen);
  memcpy(prevars2,vntmap[vnt]+vntprevars2,prevars2len);
  memcpy(0,vntmap[vnt]+vntserial,seriallen);
(vntmap[vnt]+vntserial)[0]= vnt+1;//debug
  alltomidi= 1;
);
vntedit= 0;

alltomidi ?(
  mccenable >= mccext ?(
    midi_bus= chanbus;
    alltomidi == 1 ?(
      ii= -1; mccchanmap[0]+chan < 16 ? loop ( mccsteps, ii+= 1;
        midisend( 0, $xb0+mccchanmap[0]+chan, mccnummap[0]+ii + (dirs[ii] & dirmask) * 256 );
        midisend( 0, $xb0+mccchanmap[0]+chan, mccnummap[0]+32+ii + ((dirs[ii] & dirmetamask) / dirmetabase) * 256 );
      );
    ):(
      jj= alltomidi-1;
      vv= mccseqmap[jj];
      ii= -1; mccchanmap[jj]+chan < 16 ? loop ( mccsteps, ii+= 1;
        mccintmap[jj] ? midisend( 0, $xb0+mccchanmap[jj]+chan, mccnummap[jj]+ii + vv[ii] * 256 )
                      : midisend( 0, $xb0+mccchanmap[jj]+chan, mccnummap[jj]+ii + ((vv[ii] * 127 / mccrngmap[jj]) | 0) * 256 );
      );
    );
    alltomidi+= 1;
    alltomidi > mcccnt ? alltomidi= 0;
  ):(
    alltomidi= 0;
  );
);

// vnt menu: copy/paste
gdvarx[] == 1 ?( //copy
  offuni[]= !offbi;
  memcpy(dirsserial,dirs,maxmaxsteps+2);
  memcpy(vntcopy+vntslvars,slvars,slvarslen);
  memcpy(vntcopy+vntprevars,prevars,prevarslen);
  memcpy(vntcopy+vntprevars2,prevars2,prevars2len);
  memcpy(vntcopy+vntserial,0,seriallen);
  gdvarx[]= 0;
): gdvarx[] == 2 ?( //paste
  memcpy(slvars,vntcopy+vntslvars,slvarslen);
  memcpy(prevars,vntcopy+vntprevars,prevarslen);
  memcpy(prevars2,vntcopy+vntprevars2,prevars2len);
  memcpy(0,vntcopy+vntserial,seriallen);
  newvnt= maxvnts; //dummy val to trig post newvnt bits
  gdvarx[]= 0;
);

newvnt >= 0 ?(
  memcpy(dirs,dirsserial,maxmaxsteps+2);
  ii= 0; loop ( slvarslen, //update slider automation after vnt load
    (slbits & (2^ii)) ?( slider(ii+1)= slvars[ii]; );    
    ii+= 1;
  );
  slider_automate( slbits );
  ctl1def= ctl1bi[]?64:0;
  ctl2def= ctl2bi[]?64:0; 
  ctl3def= ctl3bi[]?64:0;
  ctl4def= ctl4bi[]?64:0; 
  octpos[]= min(octpos[],octaves[]);
  offbi= !(offuni[]);
  offdef= offbi?50:0; 
  ii= -1; while ( sortxpat[ii+=1] || sortxpat[ii+=1] || sortxpat[ii+=1] || sortxpat[ii+=1] || sortxpat[ii+=1] || sortxpat[ii+=1]; );
  sortxpatcnt= ii-5;
  dosortx= sortx[];
  notecnt0x= 1;
  newvnt & vntdopos ?( memcpy(posvars, posvars0, posvarslen); ctl3pos[]= ctl3pos0[]; ctl4pos[]= ctl4pos0[]; );
  newvnt= -1;
);

//- sortx menu
gdsortx[] ?(
  gdsortx[] == 1 ?( dosortx= sortx[]= slider30= sortx[]?0:-1; slider_automate(slider30); ) //click on cur sortx name
  : gdsortx[] == 2 ?( memcpy( sortxpatcopy, sortxpat, sortxpatlen ); )
  : gdsortx[] == 3 ?( memcpy( sortxpat, sortxpatcopy, sortxpatlen ); dosortx= sortx[]; )
  : gdsortx[] == 4 ?( sortxmenu[0]= 0; ) // reload names if "load:" selected
  : gdsortx[] > 4 ?( dosortx= sortx[]= gdsortx[]-4; slider30= -1; slider_automate(slider30); ); 
  gdsortx[]= 0;
);
// sortx load
sortx[] && dosortx > 0 ?(
    sortxpatcnt= sortxmenumap2[dosortx-1];
    memcpy( sortxpat, sortxmenumap[dosortx-1], sortxpatcnt );
    dosortx= sortx[]= slider30= -1; slider_automate(slider30);
);
// build sortx menu for later
!(sortxmenu[0]) ?(
  ndx= ii= -1;
  memset(sortxpre, 0, sortxprelen);
  ll= 0; loop ( 2,
    hh= file_open(fnsortxpre+ll); ll+= 1;
    hh >= 0 ?(
      file_mem(hh, sortxpre+ii+1, sortxprelen-8-(ii+1));
      file_close(hh);
      while (
        kk= ii + 1;
        while ( sortxpre[ii+= 1]; ); //name
        ii > kk ?( //name not empty?
          while ( sortxpre[ii+= 2]; ); //steps
          while ( sortxpre[ii+= 1]; ); //prefix
          while ( //repeat
            !(sortxpre[ii+= 1]) ?(
              !(xx= sortxpre[ii+= 1]) ?( //end?
                ii+1 - kk < sortxpatlen ?( 
                  // end of sortx; add to menu
                  /*gpt='  ';*/                   (gpt[0]=2; gpt[1]=($' ');gpt[2]=($' '););
                  jj= 1; loop ( gpt[0], sortxmenu[sortxmenu[0]+jj]= gpt[jj]; jj+= 1; ); 
                  sortxmenu[0]+= gpt[0];
                  jj= -1; while ( jj+= 1; (sortxmenu[sortxmenu[0]+jj+1]= sortxpre[kk+jj]) && jj <= 12; ); 
                  sortxmenu[0]+= jj;
                  sortxmenu[sortxmenu[0]+1]= ($'|'); sortxmenu[0]+= 1;
                  sortxmenumap[ndx+=1]= sortxpre+kk; //offset of sortxpat
                  sortxmenumap2[ndx]= ii+1-kk; //len of sortxpat
                );
                0; //end while repeat
              ):(
                xx < 0 ? ii+= 1 //repeat
                : xx == 1 ? ii+= 3 //prob bounded random
                : xx == 2 ? ii+= 2 //prob skip
                : xx == 3 ? ii+= 5; //prob conditional skip
                ii < sortxprelen; //continue while if more in preset buffer
              );
            ):(
              ii < sortxprelen; //continue while if more in preset buffer
            );
          );
          ii < sortxprelen && ndx < sortxmenucnt; //continue while if more in preset buffer
        ): 0; //empty name: end of sortxpres
      );
    ); //... hh >= 0 ?   
  ); //... loop ( 2,
  sortxmenu[sortxmenu[0]+1]= ($'|'); sortxmenu[0]+= 1;
);

!notecnt ? stepsmemndx= 0; //dbg

//play_state: 0=stopped, <0=error, 1=playing, 2=paused, 5=recording, 6=record paused
//play_position: at last @block in seconds
//beat_position: at last @block in beats
//samplesblock: samples before next @block
//tempo: in bpm
//srate: in samples/sec

//- figure next tick
tick[] < 0 ?(
  (tick[]-tickf[])*1000 != lasttick || srate != lastsrate ?( //!= fails for differences <~.00001
    ticklen= tickf[]*100*srate;
    lasttick= (tick[]-tickf[])*1000;
    lastsrate= srate;
  );
):(
  (tick[]+tickf[])*1000 != lasttick ?(
    beatspertick= syncfracs[tick[]];
    (vv= tickf[]) ? beatspertick*= vv*2;
    ticksperbeat= 1/beatspertick;
    lasttick= (tick[]+tickf[])*1000;
  );
  beatlen= srate*60/tempo;
  ticklen= beatlen * beatspertick;
  play_state & 1 ?(
    tickpos= beat_position * ticksperbeat;
    swingcnt= tickpos+1+swingsteps[]-1; //swing for *next* tick;  
      //beat_pos/tickpos zero based; swingcnt==0 for tick after downbeat
    offbi && offpct[] == 100 ? swingcnt+= 1; 
      //100% bi-offset: offset swing +1 tick
    swingcnt= swingcnt % (swingsteps[]) | 0;
    tickpos-= tickpos|0; //fractional part of tickpos
    tickpos= tickpos*ticklen; //cvt to samples
    (sought || playon) && tickpos < 1 ? tickpos= ticklen;
      //special tick if seek/playback w/ tick in previous sample
  );
);

//- process tick in this block
//   process events ahead of time to allow for predelay
tickoff= tickpos - ticklen; //len back from current tick to @block
offbi && offpct[] == 100 ? tickoff-= ticklen; //@ 100% bi-offset: +1 tick back
tickahd= offbi ? -ticklen * offpct[] / 100 : 0; //back in time for bi-offpct
dotick= !(paused[]) && tickahd >= tickoff && tickahd < tickoff + samplesblock && jittercnt;
  dotick2= dotick && (tickcnt-= 1) <= 0;
  dotick2 ?( //length countdown done?
    nexttick= -tickoff|0;
  
    // get current values from all seqs
    lenpos[] >= lencnt[] ? lenpos[]= 0;
    tickcnt= lens[lenpos[]] + 1; //set countdown for next tick based on length seq
    
    gatepos[] >= gatecnt[] ? gatepos[]= 0;
    gatev= gates[gatepos[]];
    
    vcpos[] >= vccnt[] ? vcpos[]= 0;
    vcv= vcs[vcpos[]];
    
    tranpos[] >= trancnt[] ? tranpos[]= 0;
    tranv= trans[tranpos[]] - tranbase[];
    
    accpos[] >= acccnt[] ? accpos[]= 0;
    accv= (accs[accpos[]] - accrng/2) / (accrng/2);
    
    offpos[] >= offcnt[] ? offpos[]= 0;
    offbi ? offv= (offs[offpos[]] - offrng/2) / (offrng/2)
      : offv= offs[offpos[]] / offrng;

    dirpos[] >= dircnt[] ?( // dirpos[]= 0; //prelim dir logic
      dirsaved ?(
        memcpy(dirs,dirssv,maxmaxsteps);
        dircnt[]= dircntsv;
        dirpos[]= dirpossv;
        dirsaved=0;
      ): dirpos[]= 0; 
    );

    ctl2pos[] >= ctl2cnt[] ? ctl2pos[]= 0; //prelim ctl2 logic in case prob
    ctl2v= ctl2s[ctl2pos[]];
    randsubtract= ctl2cc[]==-1 && !(ctl2bi[] && ctl2v < $x40) 
        && rand(1) <= (ctl2bi[] ? (ctl2v-$x40)/$x3f : ctl2v/$x7f);
    ctl34on[] ?(
      ctl3pos[] >= ctl3cnt[] ? ctl3pos[]= 0; //prelim ctl3 logic in case prob
      ctl3v= ctl3s[ctl3pos[]];
      !randsubtract ? randsubtract= ctl3cc[]==-1 && !(ctl3bi[] && ctl3v < $x40) 
          && rand(1) <= (ctl3bi[] ? (ctl3v-$x40)/$x3f : ctl3v/$x7f);
    );
  
  ); dotick2 ?( //workaround limited code size in parens
  
    //- queue note events, using gate, octave and trans values
    ontime= max(0,nexttick + (!swingcnt ? ticklen*swing[]/100 : 0) + ticklen*offv*offpct[]/100)|0;
    playone ?( slider1= paused[]= 1; slider_automate(slider1); playone= 0; );

    notecnt && sortx[] && (dosortx || notecnt != lastnotecnt) ?( 
                     //sortx triggered elsewhere or notecnt delta: precompute new sortxcnt
      // skip name
      ii= -1; while ( sortxpat[ii+=1]; );
      // steps
      sortxcnt= notecnt;
      while (
        xadd= sortxpat[ii+= 1];
        xmul= sortxpat[ii+= 1];
        sortxcnt+= xadd;
        xmul ?( sortxcnt*= xmul; 1; ): 0;
      );
      sortxcnt|= 0;
      sortxcnt < 1 ? sortxcnt= 1;
    );

    notecntx= notecnt && sortx[] ? sortxcnt : notecnt;
    evcnt < maxevs ?( evtimes[evcnt]= nexttick - samplesblock;
        evmsgs[evcnt]= -notes; evmsg23s[evcnt]= -1; evcnt+= 1; ); // reset notes hilite event
        
    //- step steps to be stepped this tick
    stepsdone= 0; 
    dirmetacnt= 0;
    dirpos0= dirpos[];
    stepsbackndx= stepsmemndx;
    octtrans= 0;
    consteps[0]= 0; //dbg
    notecnt && !lastnotecnt ?( //set initial play pos & order direction for new notes
      order[] == 4 ?( //down+up
        playpos= notecntx-1;
        octpos[]= octmode[] ? octaves[] : 0;
      ): order[] == 5 ?( //downup
        playpos= notecntx > 1 ? notecntx-2 : 0;
        octpos[]= octmode[] ? octaves[] : 0;
      ):(
        playpos= -1;
        octpos[]= 0;
      );
       orderrev= 0;
    );
    
    onseekdo ?( //on host seek?
      onseekpos >= dircnt[] ? onseekpos= dircnt[]-1; 
      ii= onseekpos; while (
        (ii+= 1) >= dircnt[] ? ii= 0;
        dirs[ii] != diroponseek && ii != onseekpos; 
      );
      dirs[ii] == diroponseek ?(
        dirpos[]= ii + 1; onseekpos= ii;
      );
      onseekdo= 0;
    );
    
  ); dotick2 ?( //workaround limited code size in parens
    
    while ( 
      // save current playstate
      playpos0= playpos;
      orderrev0= orderrev;
      octpos0= octpos[];
      nextnotes= 1; //default
      
      !stepsdone ?(
        // alter playstate based on current dir val
        dirv= dirs[dirpos[]];
        dirv0= dirv & (dirmask|dirop);
        dirv0 == diropboom ?(
          dirsaved ?(
            memcpy(dirs,dirssv,maxmaxsteps);
            dircnt[]= dircntsv;
            dirsaved=0;
          );
          memcpy(posvars, posvars0, posvarslen); ctl3pos[]= ctl3pos0[]; ctl4pos[]= ctl4pos0[];
          
          // get current values from all seqs
          lenpos[] >= lencnt[] ? lenpos[]= 0;
          tickcnt= lens[lenpos[]] + 1; //set countdown for next tick based on length seq
          gatepos[] >= gatecnt[] ? gatepos[]= 0;
          gatev= gates[gatepos[]];
          vcpos[] >= vccnt[] ? vcpos[]= 0;
          vcv= vcs[vcpos[]];
          tranpos[] >= trancnt[] ? tranpos[]= 0;
          tranv= trans[tranpos[]] - tranbase[];
          accpos[] >= acccnt[] ? accpos[]= 0;
          accv= (accs[accpos[]] - accrng/2) / (accrng/2);
          offpos[] >= offcnt[] ? offpos[]= 0;
          offbi ? offv= (offs[offpos[]] - offrng/2) / (offrng/2)
            : offv= offs[offpos[]] / offrng;
          dirpos[] >= dircnt[] ? dirpos[]= 0; //prelim dir logic
          dirv= dirs[dirpos[]];
          dirv0= dirv & (dirmask|dirop);
          ctl2pos[] >= ctl2cnt[] ? ctl2pos[]= 0; //prelim ctl2 logic in case prob
          ctl2v= ctl2s[ctl2pos[]];
          randsubtract= ctl2cc[]==-1 && !(ctl2bi[] && ctl2v < $x40) 
              && rand(1) <= (ctl2bi[] ? (ctl2v-$x40)/$x3f : ctl2v/$x7f);
          ctl34on[] ?(
            ctl3pos[] >= ctl3cnt[] ? ctl3pos[]= 0; //prelim ctl3 logic in case prob
            ctl3v= ctl3s[ctl3pos[]];
            !randsubtract ? randsubtract= ctl3cc[]==-1 && !(ctl3bi[] && ctl3v < $x40) 
                && rand(1) <= (ctl3bi[] ? (ctl3v-$x40)/$x3f : ctl3v/$x7f);
          );
        );
        orderrevx= 0;
        dirv0 == dirprev ? orderrevx= 1
        : dirv0 == dirrand1 ?( rand(1)>.5 ? orderrevx= 1; )
        : dirv0 == dirnext2 ? nextnotes= 2
        : dirv0 == dirnext3 ? nextnotes= 3
        : dirv0 == dirprev2 ?( orderrevx= 1; nextnotes= 2; )
        : dirv0 == dirprev3 ?( orderrevx= 1; nextnotes= 3; )
        : dirv0 == dirrand || dirv0 == dirback1 || dirv0 == dirback2 || dirv0 == dirback2 
          || dirv & dirop
          ? nextnotes= 0
        ;
        orderrevx ? orderrev= !orderrev; //for up & down orders
        orderrev1= orderrev; //for detecting changed order after next notes
      );
      
      // iterate throught nextnotes notes based on playpos, order[], orderrev, octmode[]/octpos[], 
      notecnt ? loop ( nextnotes, 
        // figure next note based on order[] & octave pos
        //   note: do this *before* queueing note to account for changes notes since last
        //   tick.  this is unlike sequence positions, which are incremented *after*
        //   they are retrieved above, and then indicate the upcoming step.  this is
        //   so saving/restoring positions and manipulating them manually while paused
        //   will operate on the next step, which is more intuitive.
        octavesx= octmode[] ? octaves[] : 0;
        playpos >= notecntx ? playpos= 0; //test first in case notecnt changed by midi/octmode/???
        order[] == 6 ?( //random
          playpos= rand(notecntx)|0; playpos == notecntx ? playpos= 0;
          octpos[]= rand(octavesx+1)|0; octpos[] == octavesx+1 ? octpos[]= 0;
          octmode[] ?(
            resortx[] & resortxnote && !playpos ? dosortx= sortx[]
            : resortx[] & resortxoct && !(octpos[]) && !playpos ? dosortx= sortx[];
          ):(
            resortx[] & resortxnote && !( playpos % notecnt0 ) ? dosortx= sortx[]
            : resortx[] & resortxoct && !playpos ? dosortx= sortx[];
          );
        ): (order[] == 3 || order[] == 5) && !orderrev ?( //updown||downup going up
          (playpos+= 1) >= (octpos[]==octavesx ? notecntx-1 : notecntx) ?(
              //switch octave before hi/low note for hi octave; after for middle octaves
            (octpos[]+= 1) > (notecntx > 1 ? octavesx : octavesx-1) ?(
                //single note seqs change direction sooner
              octpos[]= octavesx; 
              octavesx || notecntx > 1 ? orderrev= 1; 
              order[] == 5 && resortx[] & resortxoct ? dosortx= sortx[];
              notecntx < 2 ? playpos= 0 : playpos != notecntx-1 ? playpos= notecntx-2;
                   //playpos >notecntx-1 to begin with: continue
              octtrans= 1;
            ): playpos= 0; //keep going if not hi octave
            resortx[] & resortxnote ? dosortx= sortx[];
          ):(
            !(octmode[]) && resortx[] & resortxnote ?
              !( playpos % notecnt0 ) ? dosortx= sortx[];
          );
        ): (order[] == 3 || order[] == 5) ?(  //updown||downup going down
          (playpos-= 1) < (octpos[]==0 ? 1 : 0) ?( 
              //switch octave before hi/low note for low octave; after for middle octaves
            (octpos[]-= 1) < (notecntx > 1 ? 0 : 1) ?( 
                //single note seqs change direction sooner
              octpos[]= 0; 
              octavesx || notecntx > 1 ? orderrev= 0; 
              order[] == 3 && resortx[] & resortxoct ? dosortx= sortx[];
              notecntx < 2 ? playpos= 0 : playpos ? playpos= 1; //playpos <1 to begin with: continue
              octtrans= 1;
            ): playpos= notecntx-1; //keep going if not low octave
            resortx[] & resortxnote ? dosortx= sortx[];
          ):(
            !(octmode[]) && resortx[] & resortxnote ?
              playpos % notecnt0 == notecnt0-1 ? dosortx= sortx[];
          );
        ): (order[] == 2 || order[] == 4) && !orderrev ?(  //up-down||down-up going up
          (playpos+= 1) >= notecntx ?(
            (octpos[]+= 1) > octavesx ?( 
              octpos[]= octavesx; orderrev= 1; playpos= notecntx-1;
              order[] == 4 && resortx[] & resortxoct ? dosortx= sortx[];
              octtrans= 1;
            ): playpos= 0;
            resortx[] & resortxnote ? dosortx= sortx[];
          ):(
            !(octmode[]) && resortx[] & resortxnote ?
              !( playpos % notecnt0 ) ? dosortx= sortx[];
          );
        ): (order[] == 2 || order[] == 4) ?(  //up-down||down-up going down
          (playpos-= 1) < 0 ?( 
            (octpos[]-= 1) < 0 ?( 
              octpos[]= 0; orderrev= 0; playpos= 0;
              order[] == 2 && resortx[] & resortxoct ? dosortx= sortx[];
              octtrans= 1;
            ): playpos= notecntx - 1;
            resortx[] & resortxnote ? dosortx= sortx[];
          ):(
            !(octmode[]) && resortx[] & resortxnote ?
              playpos % notecnt0 == notecnt0-1 ? dosortx= sortx[];
          );
        ): (order[] == 1 && !orderrevx) || (order[] == 0 && orderrevx) ?( //down
          (playpos-= 1) < 0 ?( 
            playpos= notecntx - 1; 
            resortx[] & resortxnote ? dosortx= sortx[];
            (octpos[]-= 1) < 0 ?( 
              octpos[]= octavesx; 
              resortx[] & resortxoct ? dosortx= sortx[]; 
              octtrans= 1; 
            );
          ):(
            !(octmode[]) && resortx[] & resortxnote ?
              playpos % notecnt0 == notecnt0-1 ? dosortx= sortx[];
          );
        ):( //up
          (playpos+= 1) >= notecntx ?( 
            playpos= 0; 
            resortx[] & resortxnote ? dosortx= sortx[];
            (octpos[]+= 1) > octavesx ?( 
              octpos[]= 0; 
              resortx[] & resortxoct ? dosortx= sortx[]; 
              octtrans= 1;
            );
          ):(
            !(octmode[]) && resortx[] & resortxnote ?
              !( playpos % notecnt0 ) ? dosortx= sortx[];
          );
        );
      );
      
      !stepsdone ?(
        orderrev= orderrev != orderrev1 ? !orderrev0 : orderrev0; //restore order

        // reset the play pos based on dir seq if not dir=next
        // dir seq overrides, but do after position logic so resortx 
        //   logic is effective
  
        notecnt ?(
          dirv0 == dirfirst ?( playpos= 0; orderrev= 0; )
          : dirv0 == dirlast ?( playpos= notecntx-1; orderrev= 1; )
          : dirv0 == dirreverse ?( 
            !(order[]) ? order[]= 1 : order[]==1 ? order[]= 0 : orderrev0= !orderrev; 
            playpos= playpos0;
            orderrev= orderrev0;
            octpos[]= octpos0;
            )
          : dirv0 == dirrand ?( playpos= min(rand(notecntx)|0,notecntx-1); )
          : dirv0 == dirsame ?( //playpos= lastpos;
            playpos= playpos0;
            orderrev= orderrev0;
            octpos[]= octpos0;
//           ): dirv0 == diropback0 ?(
//             ii= stepsbackndx - 1; ii < 0 ? ii+= stepsmemlen;
//             playpos= stepsmemppos[ii]; playpos >= notecntx ? playpos= 0;
//             orderrev= stepsmemorev[ii];
//             octpos[]= stepsmemopos[ii]; octpos[] > octavesx ? octpos[]= 0;
//             dirv-= dirop;
          ): dirv0 == dirback1 ?(
            ii= stepsbackndx - 2; ii < 0 ? ii+= stepsmemlen;
            playpos= stepsmemppos[ii]; playpos >= notecntx ? playpos= 0;
            orderrev= stepsmemorev[ii];
            octpos[]= stepsmemopos[ii]; octpos[] > octavesx ? octpos[]= 0;
            stepsbackndx= ii+1; 
          ): dirv0 == dirback2 ?( 
            ii= stepsbackndx - 3; ii < 0 ? ii+= stepsmemlen;
            playpos= stepsmemppos[ii]; playpos >= notecntx ? playpos= 0;
            orderrev= stepsmemorev[ii];
            octpos[]= stepsmemopos[ii]; octpos[] > octavesx ? octpos[]= 0;
            stepsbackndx= ii+1; 
          ): dirv0 == dirback3 ?( 
            ii= stepsbackndx - 4; ii < 0 ? ii+= stepsmemlen;
            playpos= stepsmemppos[ii]; playpos >= notecntx ? playpos= 0;
            orderrev= stepsmemorev[ii];
            octpos[]= stepsmemopos[ii]; octpos[] > octavesx ? octpos[]= 0; 
            stepsbackndx= ii+1; 
          );
        );
        
        dirv & dirop ?(
          dirpos1= dirpos[];
          dirv0 == diroprand || dirv0 == diropseq ?( //random/sequential skip
            jj= 0; randlev= 1; (ii= dirpos[] + 1) < dircnt[] ? while (
              dirv1= dirs[ii] & (dirmask|dirop);
              randlev == 1 ?(
                dirs[ii] & dirsection ? randdirs[jj+= 1]= ii;
                dirv1 == diropsx4 ?(
                  dirs[ii] & dircontract ?(
                    loop ( 7, dirsection ? randdirs[jj+= 1]= ii; );
                    dirs[ii] & dirsection ? loop ( 23, dirsection ? randdirs[jj+= 1]= ii; ); //1+7+23=31
                  ): dirs[ii] & dirsubtract ?(
                    loop ( 15, dirsection ? randdirs[jj+= 1]= ii; );
                    dirs[ii] & dirsection ? loop ( 79 , dirsection ? randdirs[jj+= 1]= ii; ); //1+15+79=95
                  ):(
                    loop ( 3, dirsection ? randdirs[jj+= 1]= ii; );
                  );
                );
              );
              dirv1 == diroprand || dirv1 == diropseq ? randlev+= 1;
              (dirv1 != diropend || (randlev-= 1)) && (ii+= 1) < dircnt[];
            );
            jj ?(
              dirv0 == diropseq ?(
                dirv & dirsubtract ?(
                  diropseq3pos >= jj ? diropseq3pos= 0;
                  dirpos[]= randdirs[1+diropseq3pos];
                  diropseq3pos+= 1;
                ): dirv & dircontract ?(
                  diropseq2pos >= jj ? diropseq2pos= 0;
                  dirpos[]= randdirs[1+diropseq2pos];
                  diropseq2pos+= 1;
                ):(
                  diropseqpos >= jj ? diropseqpos= 0;
                  dirpos[]= randdirs[1+diropseqpos];
                  diropseqpos+= 1;
                );
              ): dirpos[]= randdirs[1+min(rand(jj)|0,jj-1)];
            ); //no section marks: do nothing
          ): dirv0 == diroptoend ?( //skip past end mark
            randlev= 1; (ii= dirpos[] + 1) < dircnt[] ? while (
              dirv1= dirs[ii] & (dirmask|dirop);
              dirv1 == diroprand || dirv1 == diropseq ? randlev+= 1;
              (dirv1 != diropend || (randlev-= 1)) && (ii+= 1) < dircnt[];
            );
            dirpos[]= ii+1 < dircnt[] ? ii+1 : 0;
          ): dirv0 == diropfirst ?(
            dirpos[]= 0;
          ): dirv0 == diropprevsec ?(
            ii= dirpos[] - 1; ii > 0 ? while (
              dirv1= dirs[ii] & (dirmask|dirop);
              !(dirs[ii] & dirsection) && (ii-= 1) > 0;
            );
            dirpos[]= ii;
          ): dirv0 == diropresortx ?(
            dosortx= 1;
          ): (dirv & dirprime) && (dirv0==diroponfirst || dirv0==diroponlast || dirv0==diroponxover || dirv0==diroponseek) ?(
            ii= dirpos[]; while (
              (ii-= 1) < 0 ? ii= dircnt[] - 1;
              ii != dirpos[] ?(
                dirv1= dirs[ii] & (dirmask|dirop);
                !(dirv1 == dirv0 && (dirs[ii] & dirprime2));
              );
            );
            dirpos1= dirpos[]= ii;
          ): dirv0 == diropheart && dirsaved ?( 
            dirpos1= dirpos[]= dircnt[]; //force end of dir subseq logic below
            //lasttick= -9999;
          ): dirv0 == diropalien && !dirsaved ?(
            ii = dirv & dirsubtract ? 3 : dirv & dircontract ? 2 : 1;
            vnt < vntcnt-ii ?(
              memcpy(dirssv,dirs,maxmaxsteps);
              dircntsv= dircnt[];
              (dirpossv= dirpos[] + 1) >= dircntsv ? dirpossv= 0;
              dirsaved= 1;
              memcpy(dirs,vntmap[vnt+ii]+vntserial+dirs,maxmaxsteps);
              dirpos[]= 0;
              dirpos1= -1;
              dircnt[]= (vntmap[vnt+ii]+vntslvars+(dircnt-slvars))[];
            );
            //beatspertick > 1/16 ? beatspertick*= .99; ticksperbeat= 1/beatspertick;
          );
          playpos= playpos0;
          orderrev= orderrev0;
          octpos[]= octpos0;
          stepsdelta= 0;
          dirpos[] == dirpos1 ?( 
            (dirpos[]+= 1) >= dircnt[] ?(
              dirsaved ?(
                memcpy(dirs,dirssv,maxmaxsteps);
                dircnt[]= dircntsv;
                dirpos[]= dirpossv;
                dirsaved=0;
              ): dirpos[]= 0; 
            );
          );
          (dirmetacnt+= 1) > dircnt[]*2 ?( stepsdone= 1; dirpos[]= dirpos0; vcv= 0;);
        ): dirv & dircontract ?(
          (dirpos[]+= 1) >= dircnt[] ?( // dirpos[]= 0;
            dirsaved ?(
              memcpy(dirs,dirssv,maxmaxsteps);
              dircnt[]= dircntsv;
              dirpos[]= dirpossv;
              dirsaved=0;
            ): dirpos[]= 0; 
          );
          (dirmetacnt+= 1) > dircnt[]*2 ?( stepsdone= 1; dirpos[]= dirpos0; vcv= 0; );
        ): (ctl2cc[]==-1 && ctl2bi[] && ctl2v < $x40 && rand(1) <= ($x40-ctl2v)/$x40/2)
            || (ctl34on[] && ctl3cc[]==-1 && ctl3bi[] && ctl3v < $x40 && rand(1) <= ($x40-ctl3v)/$x40/2)
        ?( //probable contract
          (dirpos[]+= 1) >= dircnt[] ?( // dirpos[]= 0;
            dirsaved ?(
              memcpy(dirs,dirssv,maxmaxsteps);
              dircnt[]= dircntsv;
              dirpos[]= dirpossv;
              dirsaved=0;
            ): dirpos[]= 0; 
          );
          (lenpos[]+= 1)  >= lencnt[]  ? lenpos[]= 0; //keep other seqs in sync w/ dir
          (gatepos[]+= 1) >= gatecnt[] ? gatepos[]= 0;
          (vcpos[]+= 1)   >= vccnt[]   ? vcpos[]= 0;
          (tranpos[]+= 1) >= trancnt[] ? tranpos[]= 0;
          (accpos[]+= 1)  >= acccnt[]  ? accpos[]= 0;
          (offpos[]+= 1)  >= offcnt[]  ? offpos[]= 0;
          (ctl1pos[]+= 1) >= ctl1cnt[] ? ctl1pos[]= 0;
          (ctl2pos[]+= 1) >= ctl2cnt[] ? ctl2pos[]= 0;
          (ctl3pos[]+= 1) >= ctl3cnt[] ? ctl3pos[]= 0;
          (ctl4pos[]+= 1) >= ctl4cnt[] ? ctl4pos[]= 0;
          (dirmetacnt+= 1) > dircnt[]*2 ?( stepsdone= 1; dirpos[]= dirpos0; vcv= 0; );
        ):(
          stepsdone= 1;
          stepsmemppos[stepsmemndx]= playpos;
          stepsmemorev[stepsmemndx]= orderrev;
          stepsmemopos[stepsmemndx]= octpos[];
          stepsmemndx+= 1; stepsmemndx >= stepsmemlen ? stepsmemndx= 0;
        );
      );
      
      !stepsdone && consteps[0] < constepsmax ?( //dbg: record contracted steps
        consteps[consteps[0]+= 1]= -playpos0; 
        consteps[consteps[0]+= 1]= -orderrev0;
        consteps[consteps[0]+= 1]= playpos;
        consteps[consteps[0]+= 1]= orderrev;
      );
      
      notecnt ?(
        //- do new sort transformation
        newsortx= 0; //dbg
        sortx[] 
          && ( dosortx //sortx triggered elsewhere
            || notecnt != lastnotecnt  //change in number of input notes
            || (dirv0 == dirfirst && resortx[] & resortxfirst) //dir=first & that resort event enabled
            || (dirv0 == dirlast && resortx[] & resortxlast) //dir==last & that resort event enabled
//            || (dirv & dirtwiddle)
          )
        ?(
          newsortx= 1; //dbg
          // skip name
          ii= -1; while ( sortxpat[ii+=1]; );
          // steps
          sortxcnt= notecnt;
          while (
            xadd= sortxpat[ii+= 1];
            xmul= sortxpat[ii+= 1];
            sortxcnt+= xadd;
            xmul ?( sortxcnt*= xmul; 1; ): 0;
          );
          sortxcnt|= 0;
          sortxcnt < 1 ? sortxcnt= 1;
          // prefix
          jj= 0; while (
            xx= sortxpat[ii+= 1]|0;
            xx < 0 ?( sortxmap[jj]= notecnt-1-(-xx-1)%notecnt; jj+= 1; )
            : xx > 0 ?( sortxmap[jj]= (xx-1)%notecnt; jj+= 1; );
            xx && jj < sortxcnt && jj < sortxmaplen;
          );
          // repeat
          ii0= ii; jj0= jj; skipx= 0;
          jj < sortxcnt ? while (
            xx= sortxpat[ii+= 1]|0;
            !xx || ii >= sortxpatcnt ?( //0 == relative or special or end
              xx= sortxpat[ii+= 1]|0;
              //0,0 == end: repeat
              !xx || ii >= sortxpatcnt ?( 
                ii= ii0; 
                jj>jj0 ?( jj0= jj; jj-= 1 ):( sortxmap[jj]= 0; jj0= jj+1; skipx= 0; ); 
              ):(
                // 0,<0 == relative: 
                // 0,<-steps back>,<delta>
                xx < 0 ?(
                  yy= sortxpat[ii+= 1]|0;
                  sortxmap[jj]= ( (jj?sortxmap[min(max(jj+xx,0),jj-1)]:0) + yy ) % notecnt; //wraparound if oor
                // 0,1 == probable bounded random: 
                // 0;1;<probability>;<min step>;<max step>
                ): xx == 1 ?(
                  xx= sortxpat[ii+= 1];
                  xx == 1 || rand(1) < xx ?(
                    yy= sortxpat[ii+= 1]|0;
                    zz= sortxpat[ii+= 1]|0;
                    yy= yy < 0 ? notecnt-1-(-yy-1) : yy-1;
                    zz= zz < 0 ? notecnt-1-(-zz-1) : zz-1;
                    yy > zz ?( xx= yy; yy= zz; zz= xx; );
                    sortxmap[jj]= yy+(rand(zz-yy+1)|0)%notecnt; //wraparound if oor
                  ):(
                    ii+= 2;
                    sortxmap[jj]= jj ? (sortxmap[jj-1]+1)%notecnt : 0;
                  );
                // 0,2 == probable skip: 
                // 0;2;<probability>;<skip count>
                ): xx == 2 ?(
                  skipx ? ii+= 2
                  :(
                    xx= sortxpat[ii+= 1];
                    xx == 1 || rand(1) < xx ?(
                      yy= sortxpat[ii+= 1]|0;
                      skipx= yy + 1;
                    ):(
                      ii+= 1;
                      skipx = 1;
                    );
                    sortxmap[jj]= 0; //in case inf loop
                  );
                // 0,3 == probable conditional skip:
                // 0;3;<probability>;<value specifier>;<min value>;<max value>;<skip count>
                ): xx == 3 ?(
                  skipx ? ii+= 5
                  :(
                    xx= sortxpat[ii+= 1];
                    xx == 1 || rand(1) < xx ?(
                      xx= sortxpat[ii+= 1]|0;
                      yy= sortxpat[ii+= 1]|0;
                      zz= sortxpat[ii+= 1]|0;
                      xx > 0 ?(
                        yy+= notecnt*xx;
                        zz+= notecnt*xx;
                      ):(
                        yy= yy < 0 ? notecnt-1-(-yy-1) : yy-1;
                        zz= zz < 0 ? notecnt-1-(-zz-1) : zz-1;
                      );
                      xx= xx >= 0 ? jj : jj?sortxmap[min(max(jj+xx,0),jj-1)]:0;
                      ww= sortxpat[ii+= 1]|0;
                      xx >= yy && xx <= zz ? skipx= ww + 1 : skipx= 1;
                    ):(
                      ii+= 4;
                      skipx= 1;
                    );
                    sortxmap[jj]= 0; //in case inf loop
                  );
                );
              );
            // <0 == absolute from end
            ): xx < 0 ?(
              sortxmap[jj]= max(notecnt + xx,0);
            // >0 == absolute from beg
            ):( 
              sortxmap[jj]= min(xx-1,notecnt-1);
            );
            // end of rule
            skipx ?(
              skipx-= 1; 1;
            ):(
              (jj+= 1) < sortxcnt && jj < sortxmaplen;
            );
          );
        );
        dosortx= 0;
      
        (vcv && stepsdone) || dirv & dirconadd ?(
          !(dirv & dirsubtract || randsubtract)
          ?( //don't queue new notes if dirsubtract
            // play next note
            sortx[] ?( sort[] ? played= notesort[sortxmap[playpos]] : played= sortxmap[playpos]; )//note sorted or not
            :( sort[] ? played= notesort[playpos] : played= playpos; ); //note sorted or not
            evcnt+2 <= maxevs ?(
              vel= vels[played];
              vel+= accv < 0 ? accv*vel : accv*($x7f-vel);
              vel= max(vel|0, 1);
              note= min(max(notes[played]+tranv+octpos[]*12,0),$x7f);
              evtimes[evcnt]= ontime;
              evmsgs[evcnt]= $x90|chan;
              evmsg23s[evcnt]= note + vel*256;
              evcnt+= 1;
              evtimes[evcnt]= ontime + max(1,ticklen*tickcnt*gatev);
              evmsgs[evcnt]= $x80|chan;
              evmsg23s[evcnt]= note + vel*256;
              evcnt+= 1;
              evcnt < maxevs ?( evtimes[evcnt]= nexttick;
                  evmsgs[evcnt]= -notes; evmsg23s[evcnt]= sortx[]?sortxmap[playpos]:playpos; evcnt+= 1; ); //note hilite event
              maxevcnt < evcnt ? maxevcnt= evcnt;
            );
          );
          stepsdone ? vcv-= 1
          :( //advance transpose seq if meta note from additive contract
            tranpos[] >= trancnt[] ? tranpos[]= 0;
            tranv= trans[tranpos[]] - tranbase[];
            randseq[] & randtran ? tranpos[]= rand(trancnt[])|0 : tranpos[]+= 1;
          );
        );
      ):( //!notecnt
        stepsdone && vcv ? vcv-= 1;
      );
      
      lastnotecnt= notecnt;  //inside while so only resortx first time
      
      !stepsdone || vcv;
    ); //while

  ); dotick2 ?( //workaround limited code size in parens
  
    // queue current seq positions and update positions
    evcnt < maxevs ?( evtimes[evcnt]= nexttick;
        evmsgs[evcnt]= -lens; evmsg23s[evcnt]= lenpos[]; evcnt+= 1; );
    randseq[] & randlen ? lenpos[]= rand(lencnt[])|0 : lenpos[]+= 1;
    evcnt < maxevs ?( evtimes[evcnt]= nexttick;
        evmsgs[evcnt]= -gates; evmsg23s[evcnt]= gatepos[]; evcnt+= 1; );
    randseq[] & randgate ? gatepos[]= rand(gatecnt[])|0 : gatepos[]+= 1;
    evcnt < maxevs ?( evtimes[evcnt]= nexttick;
        evmsgs[evcnt]= -vcs; evmsg23s[evcnt]= vcpos[]; evcnt+= 1; );
    randseq[] & randvc ? vcpos[]= rand(vccnt[])|0 : vcpos[]+= 1;
    evcnt < maxevs ?( evtimes[evcnt]= nexttick;
        evmsgs[evcnt]= -trans; evmsg23s[evcnt]= tranpos[]; evcnt+= 1; );
    randseq[] & randtran ? tranpos[]= rand(trancnt[])|0 : tranpos[]+= 1;
    evcnt < maxevs ?( evtimes[evcnt]= nexttick;
        evmsgs[evcnt]= -accs; evmsg23s[evcnt]= accpos[]; evcnt+= 1; );
    randseq[] & randacc ? accpos[]= rand(acccnt[])|0 : accpos[]+= 1;
    evcnt < maxevs ?( evtimes[evcnt]= nexttick;
        evmsgs[evcnt]= -offs; evmsg23s[evcnt]= offpos[]; evcnt+= 1; );
    randseq[] & randoff ? offpos[]= rand(offcnt[])|0 : offpos[]+= 1;

    // finish up dir seq processing
    evcnt < maxevs ?( evtimes[evcnt]= nexttick;
        evmsgs[evcnt]= -dirs; evmsg23s[evcnt]= dirpos[]; evcnt+= 1; );
    dirposfoo= 1;
    !playpos ?( //on first pos?
      onfirstpos >= dircnt[] ? onfirstpos= dircnt[]-1; 
      ii= onfirstpos; while (
        (ii+= 1) >= dircnt[] ? ii= 0;
        dirs[ii] != diroponfirst && ii != onfirstpos; 
      );
      dirs[ii] == diroponfirst ?(
        dirpos[]= ii + 1; onfirstpos= ii; dirposfoo= 0;
      );
    );
    dirposfoo && playpos == notecntx-1 ?( //on last pos
      onlastpos >= dircnt[] ? onlastpos= dircnt[]-1; 
      ii= onlastpos; while (
        (ii+= 1) >= dircnt[] ? ii= 0;
        dirs[ii] != diroponlast && ii != onlastpos; 
      );
      dirs[ii] == diroponlast ?(
        dirpos[]= ii + 1; onlastpos= ii; dirposfoo= 0;
      );
    );
    dirposfoo && octtrans ?( //on crossoverpos?
      onxoverpos >= dircnt[] ? onxoverpos= dircnt[]-1; 
      ii= onxoverpos; while (
        (ii+= 1) >= dircnt[] ? ii= 0;
        dirs[ii] != diroponxover && ii != onxoverpos; 
      );
      dirs[ii] == diroponxover ?(
        dirpos[]= ii + 1; onxoverpos= ii; dirposfoo= 0;
      );
    );
    dirposfoo ?( //normal next dir step
      randseq[] & randdir 
        ? dirpos[]= rand(dircnt[])|0 
        : !( dirmetacnt > dircnt[]*2 ) ? dirpos[]+= 1; //don't look like progress if thrashing
    );
    
    //- send ctls if enabled
    ii= 0; loop ( ctl34on[] ? 4 : 2, ii+= 1;
        ii == 1 ?( ctls= ctl1s; ctlpos= ctl1pos; ctlcnt= ctl1cnt; ctlcc= ctl1cc; randctl= randctl1; )
      : ii == 2 ?( ctls= ctl2s; ctlpos= ctl2pos; ctlcnt= ctl2cnt; ctlcc= ctl2cc; randctl= randctl2; )
      : ii == 3 ?( ctls= ctl3s; ctlpos= ctl3pos; ctlcnt= ctl3cnt; ctlcc= ctl3cc; randctl= randctl3; )
      :          ( ctls= ctl4s; ctlpos= ctl4pos; ctlcnt= ctl4cnt; ctlcc= ctl4cc; randctl= randctl4; );
      ctlpos[] >= ctlcnt[] ? ctlpos[]= 0;
      ctlv= ctls[ctlpos[]];
      evcnt < maxevs ?( evtimes[evcnt]= nexttick;
          evmsgs[evcnt]= -ctls; evmsg23s[evcnt]= ctlpos[]; evcnt+= 1; ); //cc hilite event
      randseq[] & randctl ? ctlpos[]= rand(ctlcnt[])|0 : ctlpos[]+= 1;
      ctlcc[] >= 0 && evcnt < maxevs ?( //cc
        evtimes[evcnt]= ontime;
        evmsgs[evcnt]= $xb0|chan;
        evmsg23s[evcnt]= ctlcc[] + (ctlv|0)*256;
        evcnt+= 1; maxevcnt < evcnt ? maxevcnt= evcnt;
      ): ii!=2 && ii!=3 && ctlcc[] == -1 && evcnt < maxevs ?( //pitch bend
        evtimes[evcnt]= ontime;
        evmsgs[evcnt]= $xe0|chan;
        ctlv= ctlv <= $x40 ? ctlv * $x80 : $x2000 + (ctlv-$x40) * $x1fff / $x3f | 0;
        evmsg23s[evcnt]= (ctlv & $x3f80) * 2 + (ctlv & $x7f);
        evcnt+= 1; maxevcnt < evcnt ? maxevcnt= evcnt;
      );    
    ); //...loop ( 4,
  );
  
dotick ?(
  swingcnt= (swingcnt+1) % (swingsteps[]); // toggle in case not playing
  jittercnt= 0; //for jitter protection
):(
  paused[] ?(
    jittercnt= 1; //for jitter protection
    dirsaved ?( //revert to saved dirs if paused
      memcpy(dirs,dirssv,maxmaxsteps);
      dircnt[]= dircntsv;
      dirpos[]= dirpossv;
      dirsaved= 0;
    ); 
  ): jittercnt+= 1;
);
tickpos+= samplesblock;
tickpos >= ticklen ? tickpos-= ticklen;

//- process pending events due this @block

// send cc's first so they can affect notes
ii= 0; loop ( evcnt,
  evtimes[ii] < samplesblock ?( //event due this @block
    evmsgs[ii] >= 0 && (evmsgs[ii]&$xf0) == $xb0 ?(
      midisend(evtimes[ii],evmsgs[ii],evmsg23s[ii]);
    );
  );
  ii+= 1; 
);
//   send due noteons before offs to avoid stuck notes
//     also do reset current notes first so new current notes appear
midi_bus= chanbus;
ii= 0; loop ( evcnt,
  evtimes[ii] < samplesblock ?( //event due this @block
    evmsgs[ii] >= 0 && (evmsgs[ii]&$xf0) == $x90 ?(
      midisend(evtimes[ii],evmsgs[ii],evmsg23s[ii]);
    ): evmsgs[ii] == -notes && evmsg23s[ii] < 0 ?( //reset current note hilites
      lastcnt= 0;
    );
  );
  ii+= 1; 
);
ii= 0; loop ( evcnt,
  evtimes[ii] < samplesblock ?( //event due this @block
    evmsgs[ii] < 0 ?( // hilite event
      evmsgs[ii] == -notes ?( //notes hilite
        evmsg23s[ii] >= 0 ?( //add note to hilite lists
          lastnotes[lastcnt]= evmsg23s[ii]; 
          lastcnt+= 1; //remember played notes to hilite
        );
      ): (-evmsgs[ii])[maxmaxsteps]= evmsg23s[ii];
      gdirtx= 1;
    ):( // "real" midi event
      vv= evmsgs[ii]&$xf0;
      vv != $xb0 && vv != $x90 ?(
        midisend(evtimes[ii],evmsgs[ii],evmsg23s[ii]);
      );
    );
    evcnt-= 1; //delete completed event
    evcnt != ii ?( //copy last event to current
      evtimes[ii]= evtimes[evcnt];
      evmsgs[ii]= evmsgs[evcnt];
      evmsg23s[ii]= evmsg23s[evcnt];
    );
    evmsgs[evcnt]= 0;
    evmsg23s[evcnt]= 0;
  ):( //not this @block: dec event countdown
    evtimes[ii]-= samplesblock;
    ii+= 1;
  );
);

/////- @gfx
@gfx 580 600

gfx_a= 1;
gfx_mode= 0;

//- process mouse clicks
//   mouse_x, mouse_y, mouse_cap (1 if left mouse down; 2 if right; 4,8,16 for control,shift,alt)

leftclick= rightclick= release= gdclick= 0;
gclickcnt0+= 1;
gdrop ?(
  mouse_cap & 3 && !(gddown||leftdown||rightdown) ?(
    gdclick= gddown= 1;
    gclickcnt= gclickcnt0; gclickcnt0= 0;
  ): !(mouse_cap & 3) && (gddown||leftdown||rightdown) ?(
    nodown= gddown= leftdown= rightdown= 0;
    gdirt= 1;
    norelease ? norelease= 0 : release= 1;
  );
):(
  mouse_cap & 1 && !(gddown||leftdown||rightdown) ?(
    leftclick= leftdown= 1;
    gclickcnt= gclickcnt0; gclickcnt0= 0;
  ): mouse_cap & 2 && !(gddown||leftdown||rightdown) ?(
    rightclick= rightdown= 1;
    gclickcnt= gclickcnt0; gclickcnt0= 0;
  ): !(mouse_cap & 3) && (gddown||leftdown||rightdown) ?(
    nodown= gddown= leftdown= rightdown= 0;
    gdirt= release= 1;
  );
);
gdirtx ?( gdirt= 1; gdirtx= 0; )
: gddown || leftdown || rightdown || gfx_w != gfx_w0 || gfx_h != gfx_h0 ? gdirt= 1;
gfx_w0= gfx_w; gfx_h0= gfx_h;
// redraw every N @gfx if mouse in gfx win for mouseovers
gdirt ? gdirtcnt= 0 
: ((gdirtcnt+= 1) > 4 && mouse_x >= 0 && mouse_x < gfx_w && mouse_y >= 0 && mouse_y < ggh) || gdirtcnt > 64 ?(
  gdirt= 1; gdirtcnt= 0;
);

//- skin
skin[] != lastskin ?(
  ggcolors= 0;
  ggdotnot= !(ggdot= 0);
  skin[] >= skincnt0 
    && (gcc= colors1 + min(skin[]-skincnt0,skincnt-skincnt0-1)*colorslen)[cname] //&& gotsettings 
    ?( // users
    ggcolors= gcc;
    ggcr= gcc[cclear]; ggcg= gcc[cclear+1]; ggcb= gcc[cclear+2];
    ggfr= gcc[cf]; ggfg= gcc[cf+1]; ggfb= gcc[cf+2];           //foreground color
    ggbr= gcc[cb]; ggbg= gcc[cb+1]; ggbb= gcc[cb+2];      //ctl background color
    gghr= gcc[ch]; gghg= gcc[ch+1]; gghb= gcc[ch+2]; ggha= gcc[ch+3]; //hilite color
    ggsr= gcc[cs]; ggsg= gcc[cs+1]; ggsb= gcc[cs+2]; ggsa= gcc[cs+3];  //slider bar color
    ggdr= gcc[cd];                                   ggda= gcc[cd+3]; //dimming color
    ggdr < 0 ?( ggdr= gcc[cclear]; ggdg= gcc[cclear+1]; ggdb= gcc[cclear+2]; ) //r<0?same rgb as clear
    :( ggdg= gcc[cd+1]; ggdb= gcc[cd+2]; );
    ggh2r= gcc[ch2];                                 ggh2a= gcc[ch2+3]; //2ndary hilite
    ggh2r < 0 ?( ggh2r= gcc[ch]; ggh2g= gcc[ch+1]; ggh2b= gcc[ch+2]; ) //r<0?same rgb as primary hilite
    :( ggh2g= gcc[ch2+1]; ggh2b= gcc[ch2+2]; );
    ggfa2= gcc[cfa2]; //2ndary black alpha
    ggkw= gcc[ckw]; ggkb=gcc[ckb];
    ggdot= gcc[cdot];
    ggdotnot = !ggdot;
    ggdotx= gcc[cdot]&$xf; ggdotx > 11 ? ggdotx= -(ggdotx-11);
    ggdoty= (gcc[cdot]/$x10)&$xf; ggdoty > 11 ? ggdoty= -(ggdoty-11);
    ggdotw= (gcc[cdot]/$x100)&$xf; ggdotw > 11 ? ggdotw= -(ggdotw-11);
    ggdoth= (gcc[cdot]/$x1000)&$xf;
    ggdotx2= (gcc[cdot]/$x10000)&$xf; ggdotx2 > 11 ? ggdotx2= -(ggdotx2-11);
    ggdoty2= (gcc[cdot]/$x100000)&$xf; ggdoty2 > 11 ? ggdoty2= -(ggdoty2-11);
    ggdotw2= (gcc[cdot]/$x1000000)&$xf; ggdotw2 > 11 ? ggdotw2= -(ggdotw2-11);
    ggdoth2= (gcc[cdot]/$x10000000)&$xf;
    ggdotsha= gcc[cdotsha];
    ggdotsha > 1 ?( ggdotshc= 1; ggdotsha-= 1; ): ggdotshc= 0;
  ): skin[] == 1 ?( // sopwith: contrast! not monochrome! not green!
    ggcr= 205/255*1.05; ggcg= 204/255*1.05; ggcb= 194/255*1.05;
    ggfr= .3; ggfg= .4; ggfb= .6;           //foreground color
    ggbr= 130/256*0.95; ggbg= 174/256*0.95; ggbb= 172/256*0.95;      //ctl background color
    gghr= .3; gghg= .3; gghb= .65; ggha= .3; //hilite color
    ggsr= 242/256; ggsg= 215/256; ggsb= 141/256; ggsa= .7;  //slider bar color
    ggdr= .72; ggdg= .71; ggdb= .68; ggda= .6; //dimming color
    ggh2r= gghr; ggh2g= gghg; ggh2b= gghb; ggh2a= .4; //2ndary hilite alpha
    ggfa2= .7; //2ndary black alpha
    ggkw= .08; ggkb=.70;
  ): skin[] == 2 ?( // nightshade: grey++!
    ggcr= ggcg= ggcb= $xbb/$xff; //$xbbbbbb; //$xf8f8f8;
    ggfr= 1; ggfg= 1; ggfb= 1;           //foreground color
    ggbr= .5; ggbg= .5; ggbb= .5;      //ctl background color
    gghr= 1; gghg= .5; gghb= .5; ggha= .4; //hilite color
    ggsr= 1; ggsg= .9; ggsb= .65; ggsa= .8;  //slider bar color
    ggdr= .72; ggdg= .72; ggdb= .72; ggda= .7; //dimming color
    ggh2r= gghr; ggh2g= gghg; ggh2b= gghb; ggh2a= .5; //2ndary hilite alpha
    ggfa2= .8; //2ndary black alpha
    ggkw= .1; ggkb=.6;
  ): skin[] == 3 ?( // viridean: ahhh!
    ggcr= $xf6/$xff; ggcg= $xfa/$xff; ggcb= $xf2/$xff; // $xedf3f1;
    ggfr= .25; ggfg= .4; ggfb= .3;           //foreground color
    ggbr= .790; ggbg= .93; ggbb= .81;      //ctl background color
    gghr= .1; gghg= .95; gghb= .15; ggha= .2;   //hilite color
    ggsr= .05; ggsg= 0; ggsb= .12; ggsa= .24;  //slider bar color
    ggdr= ggcr; ggdg= ggcg; ggdb= ggcb; ggda= .6; //dimming color
    ggh2r= .55; ggh2g= .95; ggh2b= .60; ggh2a= 1; //2ndary hilite alpha - was .4 1 .4 .5 
    ggfa2= .7; //2ndary black alpha
    ggkw= .04; ggkb=.96;
  ): skin[] == 4 ?( // black-light-blue: gray-blue!
    ggcr= ggcg= ggcb= $x55/$xff; // $x555555; //$xf6fcff;
    ggfr= .71; ggfg= .73; ggfb= .75;           //foreground color
    ggbr= .82; ggbg= .88; ggbb= .94;      //ctl background color
    gghr= .2; gghg= .6; gghb= 1; ggha= .2; //hilite color
    ggsr= 0; ggsg= 0; ggsb= 0; ggsa= .4;  //slider bar color
    ggdr= .25; ggdg= .25; ggdb= .25; ggda= .6; //dimming color
    ggh2r= gghr; ggh2g= gghg; ggh2b= gghb; ggh2a= .4; //2ndary hilite alpha
    ggfa2= .7; //2ndary black alpha
    ggkw= .1; ggkb=1;
  ):( // clarity!
    ggcr= $xe8/$xff; ggcg= $xea/$xff; ggcb= $xe4/$xff; // $xedf3f1;
    ggfr= .43; ggfg= .45; ggfb= .42;           //foreground color
    ggbr= .81; ggbg= .81; ggbb= .78;      //ctl background color
    gghr= 1; gghg= .5; gghb= .4; ggha= .38;   //hilite color
    ggsr= .52; ggsg= .57; ggsb= .65; ggsa= 1;  //slider bar color
    ggdr= ggcr; ggdg= ggcg; ggdb= ggcb; ggda= .65; //dimming color
    ggh2r= .1; ggh2g= .5; ggh2b= .15; ggh2a= .32; //2ndary hilite alpha - was .4 1 .4 .5 
    ggfa2= .7; //2ndary black alpha
    ggkw= .07; ggkb=.95;
  );
  lastskin= skin[];
);
gdirt ?(
  gfx_x= gfx_y= 0;
  gfx_r= ggcr; gfx_g= ggcg; gfx_b= ggcb; gfx_a= 1;
  gfx_rectto(gfx_w, gfx_h);
);

///// draw everything
ggy= ggt;
ggx= ggl; 

setdn || gdirt ?(

// transport & settings

//- play/pause/clear
gcc= 0;
loop ( 3,
  gx= ggx+gcc*ggbco+(gcc==2?11:0);
  // click?
  leftclick && mouse_x >= gx && mouse_x < gx+ggbcw && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
    !gcc ?( //play
      slider1= paused[]= 0; slider_automate(slider1);
    ): gcc == 1 ?( //pause
      slider1= paused[]= 1; slider_automate(slider1);
      evclear= 1;
      //midithru[] ?( noteclear= 1; );
    ): gcc == 2 ?( //clear
      noteclear= 1;
    );
  );
  rightclick && mouse_x >= gx && mouse_x < gx+ggbcw && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
    !gcc ?( //rightclick play
      tickpos= ticklen-16; //fake end of tick
      paused[] ? playone= 1;
      slider1= paused[]= 0; slider_automate(slider1);
    );
  );
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= gx; gfx_y= ggy;
  gfx_rectto(gfx_x+ggbcw, gfx_y+ggbrh);
  // hilight selected
  (!gcc && !(paused[])) || (gcc==1 && paused[]) || (gcc==2 && !notecnt) ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= gx; gfx_y= ggy;
    gfx_rectto(gfx_x+ggbcw, gfx_y+ggbrh);
  );
  // icon
  gfx_a= ggba;
  gfx_x= gx; gfx_y= ggy; 
  gfx_blit(gcc==2?fnclear:gcc?fnpause:fnplay,1,0); //???
  // mouseover?
  mouse_x >= gx && mouse_x < gx+ggbcw && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
    gfx_r= gfx_g= gfx_b= 0; gfx_a= .2;
    gfx_x= gx; gfx_y= ggy;
    gfx_rectto(gfx_x+ggbcw, gfx_y+ggbrh);
  );
  gfx_a= 1;
  gcc+= 1;
);
ggx+= 3*ggbco+11+11; //next left pos

//- hold
gxw= ggbcw; gxo= ggbco; gyh= ggbrh; gyo= ggbro; // dimension params
// click?
leftclick && mouse_x >= ggx && mouse_x <= ggx+gxw && mouse_y >= ggy && mouse_y <= ggy+gyh ?(
  slider17= hold[] = !(hold[]); slider_automate(slider17);
  !(hold[]) ? noteclear= 1;
);
// bg rect
gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
gfx_x= ggx; gfx_y= ggy;
gfx_rectto(ggx+gxw, ggy+gyh);
// hilight selected
hold[] ?(
  gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
  gfx_x= ggx; gfx_y= ggy;
  gfx_rectto(ggx+gxw, ggy+gyh);
);
// icon
gfx_a= ggba;
gfx_x= ggx; gfx_y= ggy; 
gfx_blit(fnhold,1,0); //???
// mouseover?
mouse_x >= ggx && mouse_x < ggx+gxw && mouse_y >= ggy && mouse_y < ggy+gyh ?(
  gfx_r= gfx_g= gfx_b= 0; gfx_a= .2;
  gfx_x= ggx; gfx_y= ggy;
  gfx_rectto(ggx+gxw, ggy+gyh);
);

// next left pos
ggx+= gxo+15;

//- tick
syncxmin= .25; syncxmax= 2; //lo-hi limits of tick scaling slider
gxw= 49; gyh= ggbrh; gxo= 50; gyo= ggbro;
gfx_x= ggx; gfx_y= ggy+gyh-gfx_texth-3;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
/*puts('tick');*/                                 (gfx_drawchar($'t');gfx_drawchar($'i');gfx_drawchar($'c');gfx_drawchar($'k'););
// altclick debug
leftclick && mouse_cap & 16 && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh 
?( SHOWDEBUG= dOffset != slvars ? 1 : !SHOWDEBUG; dOffset= slvars; );
// rightclick toggle tick mode
togglesync || (rightclick && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh) 
?(
  // convert between sync and abs tick values
  tick[] < 0 ?( //abs tick?
    gticklen= syncfracs[-tick[]-1] * 60 / tempo; //seconds/synctick
    gval= tickf[] * 100 / gticklen;
    gval= min(max(gval,syncxmin),syncxmax-.0000001);
    gval < 1.00001 && gval > .99999 ? gval= 0;
    tickf[]= gval/2;
  ):( //sync'd tick
    gticklen= syncfracs[tick[]] * 60 / tempo; //seconds/synctick
    tickf[]= gticklen * (tickf[]?tickf[]*2:1) / 100;
  ); 
  tick[]= -tick[] - 1;
  slider2= tick[]; slider_automate(slider2);
  slider32= tickf[]; slider_automate(slider32);
  togglesync= 0;
);
// more label bits after click test
tick[] < 0 ?( gxx= gfx_x; gfx_x-= 4; gfx_y-= 4; gfx_a=ggfa2; gfx_drawchar($'~'); gfx_x= gxx; gfx_y+= 4; );
ggx= gfx_x + 5;
// bg rect
gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
gfx_x= ggx; gfx_y= ggy;
gfx_rectto(ggx+gxw, ggy+gyh);
// tile params
gtrc= 3; gtrh= 17; gtcc= 8; gtcw= 42;
// click?
leftclick && mouse_x >= ggx && mouse_x <= ggx+gxw && mouse_y >= ggy && mouse_y <= ggy+gyh ?(
  gdrop= syncfracs; gdx= ggx-gtcw*2+3; gdy= ggy+gyo;  
  gdtcc= gtcc; gdtcw= gdtco= gtcw; gdtrc= gtrc; gdtrh= gdtro= gtrh;
  gdalt= mouse_cap & 8;
  gdalt ?(
    tick[] < 0 ?( gdbase= .9/2; gdrng= 1.1/2-gdbase; gddef= 1/2; )
    :(
      gval= tickf[]?tickf[]:.5; 
      gdbase= gval*.9; gdrng= gval*1.1-gdbase; gddef= gval; 
    );
  ):( gdbase= syncxmin/2; gdrng= syncxmax/2-gdbase; gddef= 1/2; );

);
tick[] < 0 ?(
  gval= tickf[] * 100;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
  gfx_x= ggx+4; gfx_y= ggy+ggbrh-gfx_texth-3;
  gval+.05 >= 100 ?( gfx_drawchar($' '); gfx_drawnumber(gval+.5,0) )
  : gval+.005 >= 10 ? gfx_drawnumber(gval+.05,1)
  : gval*1000+.5 >= 1000 ? gfx_drawnumber(gval+.005,2)
  :(
    gfx_drawchar($'.');
    gval= gval*1000+.5|0;
    gval < 100 ? gfx_drawchar($'0');
    gval < 10 ? gfx_drawchar($'0');
    gfx_drawnumber(gval,0);
  );
  gfx_drawchar($'s');
):(
  // draw selected tile
  gcoords[0]= (syncfracsgrid[tick[]]%10|0)*gtcw; //source_x;
  gcoords[1]= (syncfracsgrid[tick[]]/10|0)*gtrh; //source_y;
  gcoords[2]= gtcw; gcoords[3]= gtrh; //source_w/h;
  gcoords[4]= ggx+(gxw-gtcw)/2; //dest_x;
  gcoords[5]= ggy+(gyh-gtrh)/2; //dest_y;
  gcoords[6]= gtcw; gcoords[7]= gtrh; //dest_w/h;
  gcoords[8]= gcoords[9]= 0; //rotation_x/y_offset from center of image
  gfx_a= .8;
  gfx_blitext(fnsync0, gcoords, 0);
  gval= tickf[];
  gval ?(
    gval= gval*2;
    gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
    gfx_x= ggx+gxw-gfx_charw-1; gfx_y= ggy;
    gval < 1 ? gfx_drawchar($'-') : gfx_drawchar($'+');;
  );
);
// mouseover?
mouse_x >= ggx && mouse_x < ggx+gxw && mouse_y >= ggy && mouse_y < ggy+gyh ?(
  gfx_r= gfx_g= gfx_b= 0; gfx_a= .2;
  gfx_x= ggx; gfx_y= ggy;
  gfx_rectto(ggx+gxw, ggy+gyh);
);

ggx+= gxo+15; //next left pos

//- schwing
gslen= 100;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
gfx_x= ggx; gfx_y= ggy+ggbrh-gfx_texth-3;
/*puts('swing');*/                                (gfx_drawchar($'s');gfx_drawchar($'w');gfx_drawchar($'i');gfx_drawchar($'n');gfx_drawchar($'g'););
// altclick debug
leftclick && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh ?( 
  mouse_cap & 16 ?( SHOWDEBUG= dOffset != consteps ? 1 : !SHOWDEBUG; dOffset= consteps; )
  :(
    while (
      (skin[]+= 1) > skincnt ? skin[]= 0;
      skin[] >= skincnt0 && !((colors1 + min(skin[]-skincnt0,skincnt-skincnt0-1)*colorslen)[cname]);
    );
  );
);
rightclick && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
  while (
    (skin[]-= 1) < 0 ? skin[]= skincnt-1;
    skin[] >= skincnt0 && !((colors1 + min(skin[]-skincnt0,skincnt-skincnt0-1)*colorslen)[cname]);
  );
);
ggx= gfx_x + 5;

// bg rect
gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
gfx_x= ggx; gfx_y= ggy;
gfx_rectto(ggx+gslen, ggy+ggbrh);
// mouseover?
release ? gswinging= 0;
gval= swing[];
mouse_x >= ggx-3 && mouse_x <= ggx+gslen+3 && mouse_y >= ggy && mouse_y <= ggy+ggbrh ?(
  leftclick || rightclick ? gswinging= 1;
  gswinging ?(
    gval= min( max( mouse_x-ggx-3, 0), gslen-6) * swingrng/(gslen-6);
    leftdown ?( slider3= swing[]= gval; slider_automate(slider3); );
    rightdown ?( slider3= swing[]= gval*2; slider_automate(slider3); );
  );
);
// bar
gfx_r= ggsr; gfx_g= ggsg; gfx_b= ggsb; gfx_a= ggsa;
gfx_x= ggx; gfx_y= ggy;
gfx_rectto(ggx+min(gslen,gslen*gval/swingrng+.499|0), ggy+ggbrh);
// text
gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
gfx_x= ggx+5; gfx_y= ggy+ggbrh-gfx_texth-3;
gfx_drawnumber(gval,0);

// next left pos
ggx+= gslen+15;

//- channel
gxw= ggbcw; gxo= ggbco; gyh= ggbrh; gyo= ggbro; // dimension params
gtrc= 4; gtrh= 14; gtcc= 4; gtcw= 24; // tile params
gfx_x= ggx; gfx_y= ggy+gyh-gfx_texth-3;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
/*puts('chan');*/                                 (gfx_drawchar($'c');gfx_drawchar($'h');gfx_drawchar($'a');gfx_drawchar($'n'););
// rightclick toggle tick mode
rightclick && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh 
? midilock[]= !(midilock[]);
midilock[] ?( gxx= gfx_x; gfx_x-= 4; gfx_y-= 4; gfx_a=ggfa2; gfx_drawchar($'~'); gfx_x= gxx; gfx_y+= 4; );
ggx= gfx_x + 5;
// bg rect
gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
gfx_x= ggx; gfx_y= ggy;
gfx_rectto(ggx+gxw, ggy+gyh);
// click?
leftclick && mouse_x >= ggx && mouse_x <= ggx+gxw && mouse_y >= ggy && mouse_y <= ggy+gyh ?(
  gdrop= gdchan; gdx= ggx; gdy= ggy+gyo; gdtcc= gtcc; gdtcw= gdtco= gtcw; gdtrc= gtrc; gdtrh= gdtro= gtrh;
);
// draw selected tile
gcoords[0]= (chan%4|0)*gtcw; //source_x;
gcoords[1]= (chan/4|0)*gtrh; //source_y;
gcoords[2]= gtcw; gcoords[3]= gtrh; //source_w/h;
gcoords[4]= ggx+(gxw-gtcw)/2; //dest_x;
gcoords[5]= ggy+(gyh-gtrh)/2; //dest_y;
gcoords[6]= gtcw; gcoords[7]= gtrh; //dest_w/h;
gcoords[8]= gcoords[9]= 0; //rotation_x/y_offset from center of image
gfx_a= .8;
gfx_blitext(fnchan0, gcoords, 0);
// mouseover?
mouse_x >= ggx && mouse_x < ggx+gxw && mouse_y >= ggy && mouse_y < ggy+gyh ?(
  gfx_r= gfx_g= gfx_b= 0; gfx_a= .2;
  gfx_x= ggx; gfx_y= ggy;
  gfx_rectto(ggx+gxw, ggy+gyh);
);

// next left pos
ggx+= gxo+15;

//- logo
gfx_x= ggx; gfx_y= ggy+gyh-gfx_texth-3;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
/*puts('[arp!0]');*/                              (gfx_drawchar($'[');gfx_drawchar($'a');gfx_drawchar($'r');gfx_drawchar($'p');gfx_drawchar($'!');gfx_drawchar($'0');gfx_drawchar($']'););
ggw = gfx_x; // right extent of gui
leftclick && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh ?( 
  mouse_cap & 16 ? gotsettings= 0
  : mouse_cap & 4 ?( hostplay[]= !(hostplay[]); midithru[]= !(midithru[]); seekclear[]= !(seekclear[]); )
  : setdn= !setdn;
);
rightclick && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh ?( 
  mouse_cap & 16 ? dbgp= dbgt //alt/option- clears dbg text
  : mouse_cap & 4 ?( dbgvis= !dbgvis; !dbgvis ? dbgon= 0; ) //ctl/command- hides dbg & disables dbg if hidden
  : mouse_cap & 8 ?( //shift- toggles debug & shows dbg if enabled
    dbgon ?( /*dbg('OFF ');*/                     (dbgon?((dbgp+=1)[]=4; (dbgp+=1)[]=($'O');(dbgp+=1)[]=($'F');(dbgp+=1)[]=($'F');(dbgp+=1)[]=($' ');));
    dbgon= 0; ):( dbgvis= dbgon= 1; /*dbg('ON ');*/ (dbgon?((dbgp+=1)[]=3; (dbgp+=1)[]=($'O');(dbgp+=1)[]=($'N');(dbgp+=1)[]=($' ');));
    );
  ): SHOWDEBUG= !SHOWDEBUG;
);

// new row
ggx= ggl; ggy+= ggbro + 5;

/////- normal pane
); !setdn && gdirt ?(

//- sort
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
gfx_x= ggx; gfx_y= ggy+ggbrh-gfx_texth-3;
/*puts('  sort');*/                               (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'o');gfx_drawchar($'r');gfx_drawchar($'t'););
// altclick debug
leftclick && mouse_cap & 16 && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh 
?( SHOWDEBUG= dOffset != sortxpat ? 1 : !SHOWDEBUG; dOffset= sortxpat; );
// rightclick toggle sortx
rightclick && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh 
?( dosortx= sortx[]= slider30= sortx[]?0:-1; slider_automate(slider30); );
// more label bits after click test
sortx[] ?( gxx= gfx_x; gfx_x-= 4; gfx_y-= 4; gfx_a=ggfa2; gfx_drawchar($'~'); gfx_x= gxx; gfx_y+= 4; );
ggx= gfx_x + 6;
gco= ggbco-3; gcw= ggbcw-3;
gcc= 0;
loop ( 2,
  // click?
  rightclick && mouse_x >= ggx+gcc*gco && mouse_x < ggx+gcc*gco+gcw && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
    gdrop= gdsortx; gdx= ggx; gdy= ggy+ggbro;
    /*gdt='~            |copy|paste|load:|';*/    (gdt[0]=31; gdt[1]=($'~');gdt[2]=($' ');gdt[3]=($' ');gdt[4]=($' ');gdt[5]=($' ');gdt[6]=($' ');gdt[7]=($' ');gdt[8]=($' ');gdt[9]=($' ');gdt[10]=($' ');gdt[11]=($' ');gdt[12]=($' ');gdt[13]=($' ');gdt[14]=($'|');gdt[15]=($'c');gdt[16]=($'o');gdt[17]=($'p');gdt[18]=($'y');gdt[19]=($'|');gdt[20]=($'p');gdt[21]=($'a');gdt[22]=($'s');gdt[23]=($'t');gdt[24]=($'e');gdt[25]=($'|');gdt[26]=($'l');gdt[27]=($'o');gdt[28]=($'a');gdt[29]=($'d');gdt[30]=($':');gdt[31]=($'|'););
    gjj= 0; loop ( sortxmenu[0], gdt[gdt[0]+gjj+1]= sortxmenu[gjj+=1]; ); gdt[0]+= gjj;
    gdt[gdt[0]+1]= ($'|'); gdt[0]+= 1;
    gii=-1; while ( sortxpat[gii+=1] && gii < 12 ?( gdt[gii+2]= sortxpat[gii]; 1; ): 0; );
  );
  leftclick && mouse_x >= ggx+gcc*gco && mouse_x < ggx+gcc*gco+gcw && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
    slider5= sort[]= gcc; slider_automate(slider5);
  );
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a=1;
  gfx_x= ggx+gcc*gco; gfx_y= ggy;
  gfx_rectto(ggx+gcc*gco+gcw, ggy+ggbrh);
  // hilight selected
  gcc == sort[] ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx+gcc*gco; gfx_y= ggy;
    gfx_rectto(ggx+gcc*gco+gcw, ggy+ggbrh);
  );
  // icon
  gfx_a= ggba;
  gfx_x= ggx+gcc*gco-((ggbcw-gcw)/2|0); gfx_y= ggy; 
  gfx_blit(fnsort0+gcc,1,0); //???
  // mouseover?
  mouse_x >= ggx+gcc*gco && mouse_x < ggx+gcc*gco+gcw && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
    gfx_r= gfx_g= gfx_b= 0; gfx_a= ggma;
    gfx_x= ggx+gcc*gco; gfx_y= ggy;
    gfx_rectto(ggx+gcc*gco+gcw, ggy+ggbrh);
  );
  gcc+= 1;
);

ggx+= 2*gco+15; 

//- order
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
gfx_x= ggx; gfx_y= ggy+ggbrh-gfx_texth-3;
/*puts('order');*/                                (gfx_drawchar($'o');gfx_drawchar($'r');gfx_drawchar($'d');gfx_drawchar($'e');gfx_drawchar($'r'););
// altclick debug
leftclick && mouse_cap & 16 && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh 
?( SHOWDEBUG= dOffset != sortxmap ? 1 : !SHOWDEBUG; dOffset= sortxmap; );
ggx= gfx_x + 5;
gco= ggbco-2; gcw= ggbcw-2;
gcc= 0;
loop ( 7,
  // click?
  leftclick && mouse_x >= ggx+gcc*gco && mouse_x < ggx+gcc*gco+gcw && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
    slider6= order[]= gcc; slider_automate(slider6);
  );
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx+gcc*gco; gfx_y= ggy;
  gfx_rectto(ggx+gcc*gco+gcw, ggy+ggbrh);
  // hilight selected
  gcc == order[] ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx+gcc*gco; gfx_y= ggy;
    gfx_rectto(ggx+gcc*gco+gcw, ggy+ggbrh);
  );
  // icon
  gfx_x= ggx+gcc*gco-(ggbcw-gcw)/2; gfx_y= ggy; gfx_a= ggba;
  gfx_blit(fnorder0+gcc,1,0); //???
  // mouseover?
  mouse_x >= ggx+gcc*gco && mouse_x < ggx+gcc*gco+gcw && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
    gfx_r= gfx_g= gfx_b= 0; gfx_a= ggma;
    gfx_x= ggx+gcc*gco; gfx_y= ggy;
    gfx_rectto(ggx+gcc*gco+gcw, ggy+ggbrh);
  );
  gcc+= 1;
);

ggx+= 7*gco+15; 

//- octaves
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
gfx_x= ggx; gfx_y= ggy+ggbrh-gfx_texth-3;
/*puts('octaves');*/                              (gfx_drawchar($'o');gfx_drawchar($'c');gfx_drawchar($'t');gfx_drawchar($'a');gfx_drawchar($'v');gfx_drawchar($'e');gfx_drawchar($'s'););
// altclick debug
leftclick && mouse_cap & 16 && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh 
?( SHOWDEBUG= dOffset != stepsmemppos ? 1 : !SHOWDEBUG; dOffset= stepsmemppos; );
// rightclick toggle octmode
rightclick && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh 
?( octmode[]= octmode[]?0:1; notecnt0x= 1; );
// more label bits after click test
octmode[] ?( gxx= gfx_x; gfx_x-= 4; gfx_y-= 4; gfx_a=ggfa2; gfx_drawchar($'~'); gfx_x= gxx; gfx_y+= 4; );
ggx= gfx_x + 5;
gco= ggbco-5; gcw= ggbcw-5;
gcc= 0;
loop ( 4,
  // click?
  leftclick && mouse_x >= ggx+gcc*gco && mouse_x < ggx+gcc*gco+gcw && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
    mouse_cap & 4 ?( octpos[]= min( gcc, octaves[] ) )
      :( slider7= octaves[]= gcc; slider_automate(slider7); octpos[]= min(octpos[],octaves[]); notecnt0x= 1; );
  );
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx+gcc*gco; gfx_y= ggy;
  gfx_rectto(gfx_x+gcw, gfx_y+ggbrh);
  // hilight selected
  gcc == octaves[] ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx+gcc*gco; gfx_y= ggy;
    gfx_rectto(gfx_x+gcw, gfx_y+ggbrh);
  );
  // text
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
  gfx_x= ggx+gcc*gco+ggto+10-(ggbcw-gcw)/2; gfx_y= ggy+ggbrh-gfx_texth-3;
  gfx_drawchar($'0'+gcc);
  // mark octpos[]
  octaves[] && octmode[] && gcc == octpos[] ?( gfx_a= ggba*.7; gfx_drawchar($'.'); );
  // mouseover?
  mouse_x >= ggx+gcc*gco && mouse_x < ggx+gcc*gco+gcw && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
    gfx_r= gfx_g= gfx_b= 0; gfx_a= ggma;
    gfx_x= ggx+gcc*gco; gfx_y= ggy;
    gfx_rectto(ggx+gcc*gco+gcw, ggy+ggbrh);
  );
  gcc+= 1;
);

// new row
ggx= ggl; ggy+= ggbro + 5; 

); !setdn && gdirt ?( //workaround limit on how long ?(...) can be

/////- buttongrids
gndx= 0; loop ( 1, gndx+= 1;

  // buttongrid setup
  gndx == 1 ?( ///// dirs
    gpseq= dirs;   //sequence
    gprng= 16; //seq data range
    gpcnt= dircnt; //seq count
    gppos= dirpos; //seq pos
    gpdef= dirdef; //seq default val
    gpdn = dirdn;
    gpdrc= 20; //down count
    gpdrh= 9; //down row height
    gpdro= 10; //down row offset
    gpc= cstep;
    /*gpt='   dir';*/                             (gpt[0]=6; gpt[1]=($' ');gpt[2]=($' ');gpt[3]=($' ');gpt[4]=($'d');gpt[5]=($'i');gpt[6]=($'r'););
//   ): gndx == 2 ?( ///// lens
//     gpseq= lens;   //sequence
//     gprng= lenrng; //seq data range
//     gpcnt= lencnt; //seq count
//     gppos= lenpos; //seq pos
//     gpdef= lendef; //seq default val
//     gpdn= lendn;
//     gpdrc= lenrng; //down count
//     gpdrh= 9; //down row height
//     gpdro= 10; //down row offset
//     gpc= clen;
//     /*gpt='length';*/                          (gpt[0]=6; gpt[1]=($'l');gpt[2]=($'e');gpt[3]=($'n');gpt[4]=($'g');gpt[5]=($'t');gpt[6]=($'h'););
//   ): gndx == 3 ?( ///// gates
//     gpseq= gates;   //sequence
//     gprng= gaterng; //seq data range
//     gpcnt= gatecnt; //seq count
//     gppos= gatepos; //seq pos
//     gpdef= gatedef; //seq default val
//     gpdn= gatedn;
//     gpdrc= 1; //down count
//     gpdrh= 100; //down row height
//     gpdro= 101; //down row offset
//     gpc= cgate;
//     /*gpt='  gate';*/                          (gpt[0]=6; gpt[1]=($' ');gpt[2]=($' ');gpt[3]=($'g');gpt[4]=($'a');gpt[5]=($'t');gpt[6]=($'e'););
//   ): gndx == 4 ?( ///// vcs
//     gpseq= vcs;   //sequence
//     gprng= vcrng; //seq data range
//     gpcnt= vccnt; //seq count
//     gppos= vcpos; //seq pos
//     gpdef= vcdef; //seq default val
//     gpdn= vcdn;
//     gpdrc= vcrng; //down count
//     gpdrh= 9; //down row height
//     gpdro= 10; //down row offset
//     gpc= cvc;
//     /*gpt='voices';*/                          (gpt[0]=6; gpt[1]=($'v');gpt[2]=($'o');gpt[3]=($'i');gpt[4]=($'c');gpt[5]=($'e');gpt[6]=($'s'););
//   ): gndx == 5 ?( ///// trans
//     gpseq= trans;   //sequence
//     gprng= tranrng[]; //seq data range
//     gpcnt= trancnt; //seq count
//     gppos= tranpos; //seq pos
//     gpdef= trandef; //seq default val
//     gpdn= trandn; //down
//     gpdrc= tranrng[]+1; //down count
//     gpdrh= 9; //down row height
//     gpdro= 10; //down row offset
//     gpc= ctran;
//     /*gpt=' trans';*/                          (gpt[0]=6; gpt[1]=($' ');gpt[2]=($'t');gpt[3]=($'r');gpt[4]=($'a');gpt[5]=($'n');gpt[6]=($'s'););
  );
  
  gpx= ggx;       //ctl x pos
  gpy= ggy;       //ctl y pos
  // next ctl xy
  gpdn[] ? ggy+= gpdrc*gpdro-(gpdro-gpdrh)+(ggbro-ggbrh) : ggy+= ggbro; //next row
  
  // label
  gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
  gfx_x= gpx; gfx_y= gpy+ggbrh-gfx_texth-3;
  gii= 0; loop( gpt[0], gfx_drawchar(gpt[gii+= 1]); );
  leftclick ?( 
    // altclick in row label debug
    mouse_cap & 16 && mouse_x >= gpx && mouse_x < gfx_x && mouse_y >= gpy && mouse_y < gpy+ggbrh ?(
      SHOWDEBUG= dOffset != gpseq ? 1 : !SHOWDEBUG; dOffset= gpseq;
    // click to left of buttongrid cancels down grid
    ): gpdn[] && mouse_x >= gpx && mouse_x < gfx_x && mouse_y >= gpy && mouse_y < gpy+gpdrc*gpdro ?(
      gpdn[]= 0;
      nodown= 1;
    // click in row label reveals down grid
    ): !(gpdn[]) && mouse_x >= gpx && mouse_x < gfx_x && mouse_y >= gpy && mouse_y < gpy+ggbrh ?(
      gpdn[]= 1;
    );
  );
  // rightclick toggles random
  rightclick && mouse_x >= gpx && mouse_x < gfx_x && mouse_y >= gpy && mouse_y < gpy+ggbrh ?(
    randseq[] & (2^(gndx-1)) ? randseq[]&= $xffff-(2^(gndx-1)) : randseq[]|= 2^(gndx-1); 
    slider21= randseq[]; slider_automate(slider21);
  );
  // more label bits after click test
  randseq[] & (2^(gndx-1)) ?( gxx= gfx_x; gfx_x-= 4; gfx_y-= 4; gfx_a=ggfa2; gfx_drawchar($'~'); gfx_x= gxx; gfx_y+= 4; );
  gpdn[] ?(
    gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= ggfa2;
    gfx_x= gpx; gfx_y= gpy+ggbrh-gfx_texth-3+gfx_texth+5;
    gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'[');gfx_drawchar(uarrow);gfx_drawchar($']');
  );
  gpx= gfx_x + 6;

  // draw buttongrid
  paused[] ?( gpp= gppos[]; gpp >= gpcnt[] ? gpp=0; ):( gpp= gpseq[maxmaxsteps]; );
  
  gcc= 0; loop ( maxsteps[],
  
    // buttongrid down?
    gpdn[] ?(
      //- down grid?
      gpdrc > 1 ?(
        grh= gpdrc*gpdro-(gpdro-gpdrh); //ctl heigth for ctl/alt mouse, dimming, etc
        // average horz lines between down grids
        gfx_r= gfx_g= gfx_b= ggkb; gfx_a= .6;
        gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
        gfx_rectto(gfx_x+ggbcw, gfx_y+grh);
        // draw down grid
        grr= 0; loop ( gpdrc,
          // bg rect
          gndx==5 ?(
            gww= grr % 12;
            !(gww==2||gww==4||gww==6||gww==9||gww==11)
            ? gww= ggkw //1.1 //tran light notes
            : gww= 0; //1;
          ): gww= 0;
          ggcolors && ggcolors[gpc] >= 0 ?( 
            (gvv= ggcolors[gpc+4]) != 1 ?(
              gvv > 0 ?(
                gfx_r= ggcolors[cfade]; gfx_g= ggcolors[cfade+1]; gfx_b= ggcolors[cfade+2]; gfx_a= 1;
                gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grr*gpdro;
                gfx_rectto(gfx_x+ggbcw, gfx_y+gpdrh);
              ): gvv= -gvv;
            );
            gfx_r= ggcolors[gpc]; gfx_g= ggcolors[gpc+1]; gfx_b= ggcolors[gpc+2]; gfx_a= gvv; )
          :( gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1; );
          gfx_r+=gww; gfx_g+=gww; gfx_b+=gww;
          gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grr*gpdro;
          gfx_rectto(gfx_x+ggbcw, gfx_y+gpdrh);
          // +/- indices?
          gndx == 5 ? grrv= gpdrc-grr-1 : grrv= grr;
          // mouse?
          leftdown && (!(mouse_cap & (16|4)) || (mouse_cap & 16 && mouse_cap & 4)) && !nodown
              && mouse_x >= gpx+gcc*ggbco && mouse_x < gpx+gcc*ggbco+ggbcw 
              && mouse_y >= gpy+grr*gpdro && mouse_y < gpy+grr*gpdro+gpdrh 
          ?(
            gndx != 1 ?(
              gcc2= gcc; while ( gpseq[gcc2]= grrv; 
                  gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gcc2; deltaseqs[gii]= gpseq; 0; ): (gii+= 1) < deltaslen; );
                  mouse_cap & 8 && (gcc2+= 1) < maxsteps[]; ); deltas= 1;
            ):(
              stepsdelta= 1;
//                 grrv==1 ? gval= dirlast
//               : grrv==2 ? gval= dirnext2
//               : grrv==3 ? gval= dirnext3
//               : grrv==5 ? gval= dirfirst
//               : grrv==8 ? gval= dirsame
//               : 
              grrv>=15 ? gval= dirmetabase * 2^(grrv-15)
              : gval= grrv;
              gval2= gval == dircontract && mouse_cap & 16 && mouse_cap & 4 ? dirconadd : 0;
              gcc2= gcc; 
              gval <= dirmask ?( 
                while ( 
                  gpseq[gcc2]= gval + (gpseq[gcc2] & ($xffffff-dirmask)); 
                  gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gcc2; deltaseqs[gii]= gpseq; 0; ): (gii+= 1) < deltaslen; );
                  mouse_cap & 8 && (gcc2+= 1) < maxsteps[]; 
                ); deltas= 1;
              ): gpseq[gcc2] & gval && leftclick ?(
                while ( 
                  gpseq[gcc2]&= $xffffff-gval-(gval==dircontract?dirconadd:0); 
                  gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gcc2; deltaseqs[gii]= gpseq; 0; ): (gii+= 1) < deltaslen; );
                  mouse_cap & 8 && (gcc2+= 1) < maxsteps[]; 
                ); deltas= 1;
              ): leftclick ?(
                while ( 
                  gpseq[gcc2]|= gval+gval2; 
                  //gval == dirop ? gpseq[gcc2]&= $xffffff-dirsubtract-dircontract-dirtwiddle
                  //gval == dirtwiddle ? gpseq[gcc2]&= $xffffff-dirop
                  gval == dircontract ? gpseq[gcc2]&= $xffffff-dirsubtract
                  : gval == dirsubtract ? gpseq[gcc2]&= $xffffff-dircontract; 
                  gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gcc2; deltaseqs[gii]= gpseq; 0; ): (gii+= 1) < deltaslen; );
                  mouse_cap & 8 && (gcc2+= 1) < maxsteps[]; 
                ); deltas= 1;
              );
            );
          );
          
          // hilite value
          gndx == 1 ?(
            gval= gpseq[gcc] & dirmask;
//               gval==dirlast ? gval= 1
//             : gval==dirnext2 ? gval= 2
//             : gval==dirnext3 ? gval= 3
//             : gval==dirfirst ? gval= 5
//             : gval==dirsame ? gval= 8;
            !( gdirhilite= grrv == gval ) ?(
              gdirhilite=
                (grrv==16 && gpseq[gcc] & dirsubtract)
                || (grrv==17 && gpseq[gcc] & dircontract)
                || (grrv==15 && gpseq[gcc] & dirtwiddle)
                || (grrv==18 && gpseq[gcc] & dirsection)
                || (grrv==19 && gpseq[gcc] & dirop);
            );
          );
          ( gndx == 1 ? gdirhilite : gndx == 5 ? grrv == gpseq[gcc] : grrv <= gpseq[gcc] ) ?(
            gfx_r= ggsr; gfx_g= ggsg; gfx_b= ggsb; gfx_a= ggsa; //+(1-ggsa)*.1;
            gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grr*gpdro;
            gfx_rectto(gfx_x+ggbcw, gfx_y+gpdrh);
          );
          
          // hilite current
          gpp == gcc && ggdotnot ?(
            gfx_r= gghr; gfx_g= gghg; gfx_b= gghb; gfx_a= ggha;
            gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grr*gpdro;
            gfx_rectto(gfx_x+ggbcw, min(gfx_y+gpdro,gpy+grh));
          );
          // icon/text value
          grrv == gpseq[gcc] ?(
            gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
            gfx_x= gpx+gcc*ggbco+ggto; gfx_y= gpy+grr*gpdro+1; //+ggbrh-gfx_texth-3;
            (gndx == 2 || gndx == 4) && grrv == gpseq[gcc] ?( //lens and vcs button
              // text
              gfx_x += 10;
              gfx_drawchar((gndx==2?$'1':$'0')+gpseq[gcc]);
            ): gndx == 5 ?(
              gii= gpseq[gcc]-tranbase[];
              abs(gii) < 10 ? gfx_x+= 5;
              gii >= 0 ? gfx_x+= 5;
              gfx_drawnumber(gii,0);
            );
          );
          // draw icon/value
          gndx == 1 ?( /////- down dirs icon
            // icon
            gfx_a= gdirhilite ? ggba : ggba*.5;
            gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grr*gpdro;
            grr2= grr / 4 | 0; gcc2= grr % 4;
            gcoords[0]= gcc2*32; //source_x;
            //gcoords[0]+= grr<2 ? 4 : grr<4 ? 2 : grr<6 ? 4 : grr<7 ? 0 : grr<8 ? 1 : grr<12 ? 0 : grr<14 ? 4 : 0;
            gcoords[1]= grr2*17; //source_y;
            gcoords[1]+= grr<15 ? 4 : grr<18 ? 0 : grr==18 ? 6 : 7;
            gcoords[2]= 31; gcoords[3]= gpdro; //source_w/h;
            gcoords[4]= gfx_x; //dest_x;
            gcoords[5]= gfx_y; //dest_y;
            gcoords[6]= 31; gcoords[7]= gpdro; //dest_w/h;
            gcoords[8]= gcoords[9]= 0; //rotation_x/y_offset from center of image
            gfx_blitext(gpseq[gcc] & dirop ? fndirtypes2 : fndirtypes, gcoords, 0);
            grr == 17 && gpseq[gcc] & dirconadd ?(
              gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grr*gpdro;
              gfx_a= ggba;
              gfx_blit(fnconadd,1,0);
            );
          );
          // 0 tran label
/***          gndx == 5 && gcc == 0 && grr && grr < gprng && !(grr % 12) ?(
            gxx= (gprng-grr) - tranbase[];
            gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
            gfx_x= gpx - 7 - ( 
              (gxx<0?gfx_charw:0)
              + (gxx==0?1:2)*gfx_charw ); 
            gfx_y= gpy+grr*gpdro+1;
            gfx_drawnumber(gxx,0);
          );***/
          grr+= 1;
        );
      //- down slider
);/***      ):(
        grh= gpdrh; //ctl heigth for ctl/alt mouse, dimming, etc
        ggcolors && ggcolors[gpc] >= 0 ?( 
          (gvv= ggcolors[gpc+4]) != 1 ?(
            gvv > 0 ?(
              gfx_r= ggcolors[cfade]; gfx_g= ggcolors[cfade+1]; gfx_b= ggcolors[cfade+2]; gfx_a= 1;
              gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
              gfx_rectto(gfx_x+ggbcw, gfx_y+(grh*.5|0)-1);
              gfx_x= gpx+gcc*ggbco; gfx_y= gpy+(grh*.5|0);
              gfx_rectto(gpx+gcc*ggbco+ggbcw, gpy+grh);
            ): gvv= -gvv;
          );
          gfx_r= ggcolors[gpc]; gfx_g= ggcolors[gpc+1]; gfx_b= ggcolors[gpc+2]; gfx_a= gvv; )
        :( gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1; );
        gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
        gfx_rectto(gfx_x+ggbcw, gfx_y+(grh*.5|0)-1);
        gmy= gfx_y; // middle yval for bidi sliders
        gfx_x= gpx+gcc*ggbco; gfx_y= gpy+(grh*.5|0);
        gfx_rectto(gpx+gcc*ggbco+ggbcw, gpy+grh);
        // mouse?
        leftdown && !(mouse_cap & (16|4)) && !nodown
            && mouse_x >= gpx+gcc*ggbco && mouse_x < gpx+gcc*ggbco+ggbcw 
            && mouse_y >= gpy && mouse_y < gpy+grh ?(
          gval= min( max( gprng*(gpy+grh-mouse_y-3)/(grh-6), 0), gprng);
          gcc2= gcc; while ( gpseq[gcc2]= gval; 
              gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gcc2; deltaseqs[gii]= gpseq; 0; ): (gii+= 1) < deltaslen; );
              mouse_cap & 8 && (gcc2+= 1) < maxsteps[]; ); deltas= 1;
        );
        // bar
        gfx_r= ggsr; gfx_g= ggsg; gfx_b= ggsb; gfx_a= ggsa;
        gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grh;
        gfx_rectto(gfx_x+ggbcw, gfx_y-(grh*gpseq[gcc]/gprng+.499|0));
        gfx_r= ggcr; gfx_g= ggcg; gfx_b= ggcb; gfx_a= .33;
        gfx_x= gpx+gcc*ggbco; gfx_y= gmy;
        gfx_rectto(gfx_x+ggbcw, gmy+1);
        // hilite current
        gpp == gcc && ggdotnot ?(
          gfx_r= gghr; gfx_g= gghg; gfx_b= gghb; gfx_a= ggha;
          gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
          gfx_rectto(gfx_x+ggbcw, gfx_y+grh);
        );
        // gate text
        gndx == 3 ?(
          gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
          gfx_x= gpx+gcc*ggbco+ggto; gfx_y= gpy+ggbrh-gfx_texth-3;
          //gfx_drawnumber(gpseq[gcc],1);
          gii= gpseq[gcc]; //+.05;
          gjj= (gii-(gii|0))*10|0;
          gii|= 0;
          !gjj ?( gfx_x+= 10; gfx_drawnumber(gii,0); )
            : gii && gjj ?( gfx_x+= 2; gfx_drawnumber(gpseq[gcc]+.05,1); )
            :( gfx_x+= 4; gfx_drawchar($'.'); gfx_drawnumber(gjj,0); );
        );
      );***/
    );
    
    //- buttongrid up
    !(gpdn[]) ?(
      grh= ggbrh; //ctl heigth for ctl/alt mouse, dimming, etc
      gbs= btnstyle[]; !gbs ? gbs= $xfa;
      // bg rect
      ggcolors && ggcolors[gpc] >= 0 ?( //special bg color?
        (gvv= ggcolors[gpc+3]) != 1 ?(
          gww= gndx == 1 ? gpseq[gcc]&dirmask : gpseq[gcc];
          gvv= gvv < 0 ? 1-gww/gprng*(1+gvv) : gvv + gww/gprng*(1-gvv);
          gfx_r= ggcolors[gpc]*gvv + ggcolors[cfade]*(1-gvv); 
          gfx_g= ggcolors[gpc+1]*gvv + ggcolors[cfade+1]*(1-gvv); 
          gfx_b= ggcolors[gpc+2]*gvv + ggcolors[cfade+2]*(1-gvv);        
        ):(
          gfx_r= ggcolors[gpc]; gfx_g= ggcolors[gpc+1]; gfx_b= ggcolors[gpc+2]; 
        );
      ):(
        gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb;
      );
      gfx_a= 1; 
      gbr0= gfx_r; gbg0= gfx_g; gbb0= gfx_b;
      gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
      gfx_rectto(gfx_x+ggbcw, gfx_y+grh);
      // 2nd click in button reveals down grid
      gdclick && gdrop == gpseq && gclickcnt < 15
          && mouse_x >= gpx+gcc*ggbco && mouse_x < gpx+gcc*ggbco+ggbcw 
          && mouse_y >= gpy && mouse_y < gpy+grh ?(
        gpdn[]= 1;
      );
      leftclick && (!(mouse_cap & (16|4)) || (mouse_cap & 16 && mouse_cap & 4))
          && mouse_x >= gpx+gcc*ggbco && mouse_x < gpx+gcc*ggbco+ggbcw 
          && mouse_y >= gpy && mouse_y < gpy+grh 
      ?(
        gdrop= gpseq; gdrng= gprng; gdmax= maxsteps[];
        gdcc= gcc; gdy= gpy+ggbro;
        gndx == 3 ? gdx= min(gpx+gcc*ggbco,gfx_w-ggslen-4)
        : gndx == 5 ? gdx= min(gpx+gcc*ggbco,gfx_w-(tranrng[]==24?ggslen:tranrng[]==36?ggslen*1.5:ggslen*2)-4)
        : gndx == 1 ? gdx= min(gpx+gcc*ggbco,gfx_w-4*ggbco-4)
        : gdx= min(gpx+gcc*ggbco,gfx_w-gdrng*ggbco-4);
                            //min(...: limit slider to right edge of gfx win
        gndx == 1 ?( gdtcc= 4; gdtcw= 31; gdtco= 32; gdtrc= 5; gdtrh= 16; gdtro= 17; );
      );
/***      gndx == 3 ?( /////- gates
        gbs & bsgatei ?( // bar
          gfx_r= ggsr; gfx_g= ggsg; gfx_b= ggsb; gfx_a= ggsa-ggsa*.2;
          gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
          gfx_rectto(gpx+(gcc*ggbco+ggbcw*gpseq[gcc]/gprng+.5|0), gpy+grh);
          !(gbs & bsgtic) && gpseq[gcc] >= gprng*.5 ?( // >= 1 tick
            gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba*.7;
            gfx_x= gpx+(gcc*ggbco+ggbcw*.5+.5|0)-1; gfx_y= gpy;
            gfx_rectto(gfx_x+1, gpy+2);
          );
        );
      );***/
      // hilite edited and current
      gdrop == gpseq && gdcc == gcc ?(    
        gfx_r= gfx_g= gfx_b= 0; gfx_a= .2;
        gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
        gfx_rectto(gfx_x+ggbcw, gfx_y+grh);
      ); 
      gpp == gcc && ggdotnot ?(
        gfx_r= gghr; gfx_g= gghg; gfx_b= gghb; gfx_a= ggha;
        gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
        gfx_rectto(gfx_x+ggbcw, gfx_y+grh);
      );
      
      // draw icon/value
      gndx == 1 ?( /////- dirs button
        // icon
        gval= gpseq[gcc] & dirmask;
        gfx_a= gxx= ggba;
        gii= -1; loop ( 5, gii+= 1;
          gpseq[gcc] & (dirmetabase * 2^gii) ?(
            gcoords[0]= (gii?(gii-1):3)*32; //source_x;
            gcoords[1]= (gii?4:3)*17; //source_y;
            gcoords[2]= 31; gcoords[3]= 16; //source_w/h;
            gcoords[4]= gpx+gcc*ggbco; //dest_x;
            gcoords[5]= gpy; //dest_y;
            gcoords[6]= 31; gcoords[7]= 16; //dest_w/h;
            gcoords[8]= gcoords[9]= 0; //rotation_x/y_offset from center of image
            gfx_blitext(gpseq[gcc] & dirop ? fndirtypes2 : fndirtypes, gcoords, 0);
            gii==2 ? gxx= ggba*.7; //lower central alpha if contracted // or dirop step || gii==4
            gii==4 ? gxx= ggba; //...but not for dirop steps
          );
        );
        gfx_a= gxx;
//         gval==dirlast ?( grr2= 0; gcc2= 1; ) 
//         : gval==dirnext2 ?( grr2= 0; gcc2= 2; ) 
//         : gval==dirnext3 ?( grr2= 0; gcc2= 3; ) 
//         : gval==dirfirst ?( grr2= 1; gcc2= 1; ) 
//         : gval==dirsame ?( grr2= 2; gcc2= 0; ) 
//         :
        ( grr2= gval / 4 | 0; gcc2= gval % 4; );
        gcoords[0]= gcc2*32; //source_x;
        gcoords[1]= grr2*17; //source_y;
        gcoords[2]= 31; gcoords[3]= 16; //source_w/h;
        gcoords[4]= gpx+gcc*ggbco; //dest_x;
        gcoords[5]= gpy; //dest_y;
        gcoords[6]= 31; gcoords[7]= 16; //dest_w/h;
        gcoords[8]= gcoords[9]= 0; //rotation_x/y_offset from center of image
        gfx_blitext(gpseq[gcc] & dirop ? fndirtypes2 : fndirtypes, gcoords, 0);
        gpseq[gcc] & dirconadd ?(
          gfx_x= gpx+gcc*ggbco; gfx_y= gpy; 
          gfx_a= ggba;
          gfx_blit(fnconadd,1,0);
        );
/***      ): (gndx == 2 || gndx == 4) ?( /////- lens and vcs button
        // icon
        gndx == 2 && gbs & bsleni ?(
          gfx_a= gbs & bslent ? .18 : ggba*.8;
          gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
          gii= gpseq[gcc];
          gii >= 12 ? gii-= 12;
          gfx_blit(gii+(gbs & bslent ?fnlen0:fnlenb0),1,0);
        ): gndx == 4 && gbs & bsvci ?(
          gfx_a= gbs & bsvct ? .32 : 1; //ggba;
          gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
          gii= gpseq[gcc];
          gii >= 12 ? gii-= 12;
          gfx_blit(gii+(gbs & bsvct ? fnvc0:fnvcb0),1,0);
        );
        // text
        (gndx==2 && gbs & bslent) || (gndx==4 && gbs & bsvct) ?(
          gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
          gfx_x= gpx+gcc*ggbco+10+ggto; gfx_y= gpy+grh-gfx_texth-3;
          gfx_drawchar((gndx==2?$'1':$'0')+gpseq[gcc]);
        );
      ): gndx == 3 ?( /////- gates button
        // gate text
        gbs & bsgatet ?(
          gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
          gfx_x= gpx+gcc*ggbco+ggto; gfx_y= gpy+grh-gfx_texth-3;
          //gfx_drawnumber(gpseq[gcc],1);
          gii= gpseq[gcc]; //+.05;
          gjj= (gii-(gii|0))*10|0;
          gii|= 0;
          !gjj && gii ?( gfx_x+= 10; gfx_drawnumber(gii,0); )
            : gii && gjj ?( gfx_x+= 2; gfx_drawnumber(gpseq[gcc]+.05,1); )
            :( gfx_x+= 4; gfx_drawchar($'.'); gfx_drawnumber(gjj,0); );
        );
      ): gndx == 5 ?( /////- trans button
        // icon
        gbs & bstrani ?(
          gfx_a= gbs & bstrant ? .32 : ggba*.9;
          gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
          gii= gpseq[gcc];
          gii > tranbase[] && !(gii % 12) ? gii= 12
          : gii >= 12 ? while ( (gii-= 12) >= 12; );
          gfx_blit(gii+fntran0,1,0);
        );
        // text
        gfx_x= gpx+gcc*ggbco+ggto; gfx_y= gpy+grh-gfx_texth-3;
        gii= gpseq[gcc]-tranbase[];
        abs(gii) < 10 ? gfx_x+= 5;
        gii >= 0 ? gfx_x+= 5;
        gbs & bstrant && gcc < gpcnt[] ?( // blur & lighten around text if not dimmed
          gxx= gfx_x; gyy= gfx_y;
          // lighten around num 4x offset +/-1px
          gfx_r= gfx_g= gfx_b= 1; gfx_a= (gbr0+gbg0+gbb0)*.03;
          gfx_x-= 1; gfx_y-= 1; gfx_drawnumber(gii,0);
          gfx_x= gxx+1; gfx_y= gyy-1; gfx_drawnumber(gii,0);
          gfx_x= gxx+1; gfx_y= gyy+1; gfx_drawnumber(gii,0);
          gfx_x= gxx-1; gfx_y= gyy+1; gfx_drawnumber(gii,0);
          // blur & lighten around text if not dimmed
//           gzz= (abs(gii) < 10 ? 1 : 2)*gfx_charw;
//           gii < 0 ? gxx+= gfx_charw;
//           gfx_x= gxx-2; gfx_y= gyy-2;
//           gfx_blurto( gfx_x+gzz+3, gfx_y+gfx_texth+3 );
//           gfx_x= gxx-3; gfx_y= gyy-3;
//           gfx_blurto( gfx_x+gzz+5, gfx_y+gfx_texth+5 );
//           gfx_x= gxx-1; gfx_y= gyy-1;
//           gfx_r= gfx_g= gfx_b= 1; gfx_a= .05;
//           gfx_rectto( gfx_x+gzz+1, gfx_y+gfx_texth+1 );
//           gfx_x= gxx-2; gfx_y= gyy-2;
//           gfx_r= gfx_g= gfx_b= 1; gfx_a= .05;
//           gfx_rectto( gfx_x+gzz+3, gfx_y+gfx_texth+3 );
//           gii < 0 ? gxx-= gfx_charw;
          gfx_x= gxx; gfx_y= gyy;
        );
        gbs & bstrant ?(
          gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
          gfx_drawnumber(gii,0);
        ): gii < 0 ? (
          gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba*.9;
          gfx_x= gpx+gcc*ggbco+ggbcw-gfx_charw-(gii<-2?1:gii==-2?9:8); gfx_y= gpy+1;
          gfx_drawchar($'<');
          //gfx_x= gpx+gcc*ggbco+(gii<-7?4:-10)+(12+gii)*28/12; gfx_y= gpy+1;
          //gfx_drawchar($'-');
        );
***/      );
    );
    
    leftclick && mouse_x >= gpx+gcc*ggbco && mouse_x < gpx+gcc*ggbco+ggbcw && mouse_y >= gpy && mouse_y < gpy+grh ?(
      // set default value on alt/option click
      mouse_cap & 16 && !(mouse_cap & 4) ?(
        gcc2= gcc; while ( gpseq[gcc2]= gpdef; 
            gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gcc2; deltaseqs[gii]= gpseq; 0; ): (gii+= 1) < deltaslen; );
            mouse_cap & 8 && (gcc2+= 1) < maxsteps[]; ); deltas= 1;
      // set seq position on control/command click
      ): mouse_cap & 4 && !(mouse_cap & 16) ?(
        mouse_cap & 8 ?( 
          memset(posvars, gcc, posvarslen); ctl3pos[]= gcc; ctl4pos[]= gcc;
          paused[] ?( memset(posvars0, gcc, posvarslen); ctl3pos0[]= gcc; ctl4pos0[]= gcc; );//save playback positions for start playback
        ):(
          gppos[]= gcc;
          paused[] ? gppos == ctl3pos ? ctl3pos0[]= gcc : gppos == ctl4pos ? ctl4pos0[]= gcc : posvars0[gppos-posvars]= gcc;
        );
      );
    );
    // set seq len on rightclick
    rightclick && mouse_x >= gpx+gcc*ggbco && mouse_x < gpx+gcc*ggbco+ggbcw && mouse_y >= gpy && mouse_y < gpy+grh ?(
      mouse_cap & 4 ?( //control/cmd: insert step
        gcc2= maxsteps[]-1; while ( gpseq[gcc2]= gpseq[gcc2-1]; (gcc2-= 1) > gcc; );
        gpseq[gcc]= gpdef;
        gcc < gpcnt[] ?(
          slider(gpcnt-slvars+1)= gpcnt[]= gpcnt[]+1; slider_automate(2^(gpcnt-slvars));
        );
      ): mouse_cap & 16 ?( //alt/option: delete step
        gcc2= gcc; while ( gpseq[gcc2]= gpseq[gcc2+1]; (gcc2+= 1) < maxsteps[]-1; );
        gpseq[maxsteps[]-1]= gpdef;
        gcc < gpcnt[] ?(
          slider(gpcnt-slvars+1)= gpcnt[]= gpcnt[]-1; slider_automate(2^(gpcnt-slvars));
        );
      ): mouse_cap & 8 ?( //shift: set all seq lens
        memset(cntvars, gcc+1, cntvarslen);
        gii= cntvars-slvars; loop ( cntvarslen, slider(gii+= 1)= gcc+1; slider_automate(2^(gii-1)); );
        memset(ctl34vars, gcc+1, 2); slider22= slider23= gcc+1; slider_automate(ctl34bits);
      ):( //normal: set seq len
        slider(gpcnt-slvars+1)= gpcnt[]= gcc+1; slider_automate(2^(gpcnt-slvars));
      );
    );
      
    // mark saved play positions
    paused[] && gcc == (gppos == ctl3pos ? ctl3pos0[] : gppos == ctl4pos ? ctl4pos0[] : posvars0[gppos-posvars]) ?(
      gfx_r= ggcr; gfx_g= ggcg; gfx_b= ggcb; gfx_a= 1;
      gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grh-2;
      gfx_rectto(gfx_x+1, gfx_y+2);
      gfx_rectto(gfx_x+1, gfx_y-1);
    );
    // dim n/a steps
    gcc >= gpcnt[] ?(
      gfx_r= ggdr; gfx_g= ggdg; gfx_b= ggdb; gfx_a= ggda;
      gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
      gfx_rectto(gpx+gcc*ggbco+ggbcw, gpy+grh);
      //gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
      //gfx_blurto(gpx+gcc*ggbco+ggbcw, gpy+grh);
    );
    // 4th step marks
    gcc && !(gcc & 3) ?(
      gfx_r= ggcr; gfx_g= ggcg; gfx_b= ggcb; gfx_a= 1;
      gfx_x= gpx+gcc*ggbco-3; gfx_y= gpy;
      gfx_rectto(gfx_x+5, gfx_y+1);
      gfx_x= gpx+gcc*ggbco-2; gfx_y= gpy;
      gfx_rectto(gfx_x+3, gfx_y+2);
    );
    gcc+= 1;
    
  ); //end maxsteps loop
  
  // dot hilites
  ggdot ?(
    gcc= 0; loop ( gpcnt[],
      gcc == gpp ?( gfx_r= gghr; gfx_g= gghg; gfx_b= gghb; gfx_a= ggha )
                 :( gfx_r= gfx_g= gfx_b= ggdotshc; gfx_a= ggdotsha; );
      gfx_a ?(
        gfx_x= gxx= gpx+gcc*ggbco+ggdotx; gfx_y= gpy+ggdoty;
        gfx_rectto(ggdotw<0?gxx-ggdotx+ggbcw+ggdotw+1:gfx_x+ggdotw, gfx_y+ggdoth);
        ggdoth2 ?(
          gfx_x= gxx-ggdotx+ggdotx2; gfx_y= gpy+ggdoty2;
          gfx_rectto(ggdotw2<0?gxx-ggdotx+ggbcw+ggdotw2+1:gfx_x+ggdotw2, gfx_y+ggdoth2);
        );
      );
      gcc+= 1;
    );
  );

); //end buttongrids loop  

); !setdn && gdirt ?( //workaround limit on how long ?(...) can be

/////- buttongrids (2)
gndx= 1; loop ( 4, gndx+= 1;

  // buttongrid setup
//   gndx == 1 ?( ///// dirs
//     gpseq= dirs;   //sequence
//     gprng= 16; //seq data range
//     gpcnt= dircnt; //seq count
//     gppos= dirpos; //seq pos
//     gpdef= dirdef; //seq default val
//     gpdn = dirdn;
//     gpdrc= 20; //down count
//     gpdrh= 9; //down row height
//     gpdro= 10; //down row offset
//     gpc= cstep;
//     /*gpt='   dir';*/                          (gpt[0]=6; gpt[1]=($' ');gpt[2]=($' ');gpt[3]=($' ');gpt[4]=($'d');gpt[5]=($'i');gpt[6]=($'r'););
//   ): 
  gndx == 2 ?( ///// lens
    gpseq= lens;   //sequence
    gprng= lenrng; //seq data range
    gpcnt= lencnt; //seq count
    gppos= lenpos; //seq pos
    gpdef= lendef; //seq default val
    gpdn= lendn;
    gpdrc= lenrng; //down count
    gpdrh= 9; //down row height
    gpdro= 10; //down row offset
    gpc= clen;
    /*gpt='length';*/                             (gpt[0]=6; gpt[1]=($'l');gpt[2]=($'e');gpt[3]=($'n');gpt[4]=($'g');gpt[5]=($'t');gpt[6]=($'h'););
  ): gndx == 3 ?( ///// gates
    gpseq= gates;   //sequence
    gprng= gaterng; //seq data range
    gpcnt= gatecnt; //seq count
    gppos= gatepos; //seq pos
    gpdef= gatedef; //seq default val
    gpdn= gatedn;
    gpdrc= 1; //down count
    gpdrh= 100; //down row height
    gpdro= 101; //down row offset
    gpc= cgate;
    /*gpt='  gate';*/                             (gpt[0]=6; gpt[1]=($' ');gpt[2]=($' ');gpt[3]=($'g');gpt[4]=($'a');gpt[5]=($'t');gpt[6]=($'e'););
  ): gndx == 4 ?( ///// vcs
    gpseq= vcs;   //sequence
    gprng= vcrng; //seq data range
    gpcnt= vccnt; //seq count
    gppos= vcpos; //seq pos
    gpdef= vcdef; //seq default val
    gpdn= vcdn;
    gpdrc= vcrng; //down count
    gpdrh= 9; //down row height
    gpdro= 10; //down row offset
    gpc= cvc;
    /*gpt='voices';*/                             (gpt[0]=6; gpt[1]=($'v');gpt[2]=($'o');gpt[3]=($'i');gpt[4]=($'c');gpt[5]=($'e');gpt[6]=($'s'););
  ): gndx == 5 ?( ///// trans
    gpseq= trans;   //sequence
    gprng= tranrng[]; //seq data range
    gpcnt= trancnt; //seq count
    gppos= tranpos; //seq pos
    gpdef= trandef; //seq default val
    gpdn= trandn; //down
    gpdrc= tranrng[]+1; //down count
    gpdrh= 9; //down row height
    gpdro= 10; //down row offset
    gpc= ctran;
    /*gpt=' trans';*/                             (gpt[0]=6; gpt[1]=($' ');gpt[2]=($'t');gpt[3]=($'r');gpt[4]=($'a');gpt[5]=($'n');gpt[6]=($'s'););
  );
  
  gpx= ggx;       //ctl x pos
  gpy= ggy;       //ctl y pos
  // next ctl xy
  gpdn[] ? ggy+= gpdrc*gpdro-(gpdro-gpdrh)+(ggbro-ggbrh) : ggy+= ggbro; //next row
  
  // label
  gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
  gfx_x= gpx; gfx_y= gpy+ggbrh-gfx_texth-3;
  gii= 0; loop( gpt[0], gfx_drawchar(gpt[gii+= 1]); );
  leftclick ?( 
    // altclick in row label debug
    mouse_cap & 16 && mouse_x >= gpx && mouse_x < gfx_x && mouse_y >= gpy && mouse_y < gpy+ggbrh ?(
      SHOWDEBUG= dOffset != gpseq ? 1 : !SHOWDEBUG; dOffset= gpseq;
    // click to left of buttongrid cancels down grid
    ): gpdn[] && mouse_x >= gpx && mouse_x < gfx_x && mouse_y >= gpy && mouse_y < gpy+gpdrc*gpdro ?(
      gpdn[]= 0;
      nodown= 1;
    // click in row label reveals down grid
    ): !(gpdn[]) && mouse_x >= gpx && mouse_x < gfx_x && mouse_y >= gpy && mouse_y < gpy+ggbrh ?(
      gpdn[]= 1;
    );
  );
  // rightclick toggles random
  rightclick && mouse_x >= gpx && mouse_x < gfx_x && mouse_y >= gpy && mouse_y < gpy+ggbrh ?(
    randseq[] & (2^(gndx-1)) ? randseq[]&= $xffff-(2^(gndx-1)) : randseq[]|= 2^(gndx-1); 
    slider21= randseq[]; slider_automate(slider21);
  );
  // more label bits after click test
  randseq[] & (2^(gndx-1)) ?( gxx= gfx_x; gfx_x-= 4; gfx_y-= 4; gfx_a=ggfa2; gfx_drawchar($'~'); gfx_x= gxx; gfx_y+= 4; );
  gpdn[] ?(
    gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= ggfa2;
    gfx_x= gpx; gfx_y= gpy+ggbrh-gfx_texth-3+gfx_texth+5;
    gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'[');gfx_drawchar(uarrow);gfx_drawchar($']');
  );
  gpx= gfx_x + 6;

  // draw buttongrid
  paused[] ?( gpp= gppos[]; gpp >= gpcnt[] ? gpp=0; ):( gpp= gpseq[maxmaxsteps]; );
  
  gcc= 0; loop ( maxsteps[],
  
    // buttongrid down?
    gpdn[] ?(
      // - down grid?
      gpdrc > 1 ?(
        grh= gpdrc*gpdro-(gpdro-gpdrh); //ctl heigth for ctl/alt mouse, dimming, etc
        // average horz lines between down grids
        gfx_r= gfx_g= gfx_b= ggkb; gfx_a= .6;
        gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
        gfx_rectto(gfx_x+ggbcw, gfx_y+grh);
        // draw down grid
        grr= 0; loop ( gpdrc,
          // bg rect
          gndx==5 ?(
            gww= grr % 12;
            !(gww==2||gww==4||gww==6||gww==9||gww==11)
            ? gww= ggkw //1.1 //tran light notes
            : gww= 0; //1;
          ): gww= 0;
          ggcolors && ggcolors[gpc] >= 0 ?( 
            (gvv= ggcolors[gpc+4]) != 1 ?(
              gvv > 0 ?(
                gfx_r= ggcolors[cfade]; gfx_g= ggcolors[cfade+1]; gfx_b= ggcolors[cfade+2]; gfx_a= 1;
                gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grr*gpdro;
                gfx_rectto(gfx_x+ggbcw, gfx_y+gpdrh);
              ): gvv= -gvv;
            );
            gfx_r= ggcolors[gpc]; gfx_g= ggcolors[gpc+1]; gfx_b= ggcolors[gpc+2]; gfx_a= gvv; )
          :( gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1; );
          gfx_r+=gww; gfx_g+=gww; gfx_b+=gww;
          gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grr*gpdro;
          gfx_rectto(gfx_x+ggbcw, gfx_y+gpdrh);
          // +/- indices?
          gndx == 5 ? grrv= gpdrc-grr-1 : grrv= grr;
          // mouse?
          leftdown && (!(mouse_cap & (16|4)) || (mouse_cap & 16 && mouse_cap & 4)) && !nodown
              && mouse_x >= gpx+gcc*ggbco && mouse_x < gpx+gcc*ggbco+ggbcw 
              && mouse_y >= gpy+grr*gpdro && mouse_y < gpy+grr*gpdro+gpdrh 
          ?(
            gndx != 1 ?(
              gcc2= gcc; while ( gpseq[gcc2]= grrv; 
                  gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gcc2; deltaseqs[gii]= gpseq; 0; ): (gii+= 1) < deltaslen; );
                  mouse_cap & 8 && (gcc2+= 1) < maxsteps[]; ); deltas= 1;
);/***            ):(
              stepsdelta= 1;
//                 grrv==1 ? gval= dirlast
//               : grrv==2 ? gval= dirnext2
//               : grrv==3 ? gval= dirnext3
//               : grrv==5 ? gval= dirfirst
//               : grrv==8 ? gval= dirsame
//               : 
              grrv>=15 ? gval= dirtwiddle * 2^(grrv-15)
              : gval= grrv;
              gval2= gval == dircontract && mouse_cap & 16 && mouse_cap & 4 ? dirconadd : 0;
              gcc2= gcc; 
              gval <= dirmask ?( 
                while ( 
                  gpseq[gcc2]= gval + (gpseq[gcc2] & ($xffffff-dirmask));  
                  gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gcc2; deltaseqs[gii]= gpseq; 0; ): (gii+= 1) < deltaslen; );
                  mouse_cap & 8 && (gcc2+= 1) < maxsteps[]; 
                ); deltas= 1;
              ): gpseq[gcc2] & gval && leftclick ?)
                while ( 
                  gpseq[gcc2]&= $xffffff-gval-(gval==dircontract?dirconadd:0); 
                  gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gcc2; deltaseqs[gii]= gpseq; 0; ): (gii+= 1) < deltaslen; );
                  mouse_cap & 8 && (gcc2+= 1) < maxsteps[]; 
                ); deltas= 1;
              ): leftclick ?)
                while ( 
                  gpseq[gcc2]|= gval+gval2; 
                  //gval == dirop ? gpseq[gcc2]&= $xffffff-dirsubtract-dircontract-dirtwiddle
                  //gval == dirtwiddle ? gpseq[gcc2]&= $xffffff-dirop
                  gval == dircontract ? gpseq[gcc2]&= $xffffff-dirsubtract
                  : gval == dirsubtract ? gpseq[gcc2]&= $xffffff-dircontract; 
                  gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gcc2; deltaseqs[gii]= gpseq; 0; ): (gii+= 1) < deltaslen; );
                  mouse_cap & 8 && (gcc2+= 1) < maxsteps[]; 
                ); deltas= 1;
              );
            );***/
          );
          
          // hilite value
/***          gndx == 1 ?(
            gval= gpseq[gcc] & dirmask;
//               gval==dirlast ? gval= 1
//             : gval==dirnext2 ? gval= 2
//             : gval==dirnext3 ? gval= 3
//             : gval==dirfirst ? gval= 5
//             : gval==dirsame ? gval= 8;
            !( gdirhilite= grrv == gval ) ?(
              gdirhilite=
                (grrv==16 && gpseq[gcc] & dirsubtract)
                || (grrv==17 && gpseq[gcc] & dircontract)
                || (grrv==15 && gpseq[gcc] & dirtwiddle)
                || (grrv==18 && gpseq[gcc] & dirsection)
                || (grrv==19 && gpseq[gcc] & dirop);
            );
          );***/
          ( gndx == 1 ? gdirhilite : gndx == 5 ? grrv == gpseq[gcc] : grrv <= gpseq[gcc] ) ?(
            gfx_r= ggsr; gfx_g= ggsg; gfx_b= ggsb; gfx_a= ggsa; //+(1-ggsa)*.1;
            gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grr*gpdro;
            gfx_rectto(gfx_x+ggbcw, gfx_y+gpdrh);
          );
          
          // hilite current
          gpp == gcc && ggdotnot ?(
            gfx_r= gghr; gfx_g= gghg; gfx_b= gghb; gfx_a= ggha;
            gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grr*gpdro;
            gfx_rectto(gfx_x+ggbcw, min(gfx_y+gpdro,gpy+grh));
          );
          // icon/text value
          grrv == gpseq[gcc] ?(
            gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
            gfx_x= gpx+gcc*ggbco+ggto; gfx_y= gpy+grr*gpdro+1; //+ggbrh-gfx_texth-3;
            (gndx == 2 || gndx == 4) && grrv == gpseq[gcc] ?( //lens and vcs button
              // text
              gfx_x += 10;
              gfx_drawchar((gndx==2?$'1':$'0')+gpseq[gcc]);
            ): gndx == 5 ?(
              gii= gpseq[gcc]-tranbase[];
              abs(gii) < 10 ? gfx_x+= 5;
              gii >= 0 ? gfx_x+= 5;
              gfx_drawnumber(gii,0);
            );
          );
          // draw icon/value
/***          gndx == 1 ?( ///// - down dirs icon
            // icon
            gfx_a= gdirhilite ? ggba : ggba*.5;
            gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grr*gpdro;
            grr2= grr / 4 | 0; gcc2= grr % 4;
            gcoords[0]= gcc2*32; //source_x;
            //gcoords[0]+= grr<2 ? 4 : grr<4 ? 2 : grr<6 ? 4 : grr<7 ? 0 : grr<8 ? 1 : grr<12 ? 0 : grr<14 ? 4 : 0;
            gcoords[1]= grr2*17; //source_y;
            gcoords[1]+= grr<15 ? 4 : grr<18 ? 0 : grr==18 ? 6 : 7;
            gcoords[2]= 31; gcoords[3]= gpdro; //source_w/h;
            gcoords[4]= gfx_x; //dest_x;
            gcoords[5]= gfx_y; //dest_y;
            gcoords[6]= 31; gcoords[7]= gpdro; //dest_w/h;
            gcoords[8]= gcoords[9]= 0; //rotation_x/y_offset from center of image
            gfx_blitext(gpseq[gcc] & dirop ? fndirtypes2 : fndirtypes, gcoords, 0);
            grr == 17 && gpseq[gcc] & dirconadd ?(
              gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grr*gpdro;
              gfx_a= ggba;
              gfx_blit(fnconadd,1,0);
            );
          );***/
          // 0 tran label
          gndx == 5 && gcc == 0 && grr && grr < gprng && !(grr % 12) ?(
            gxx= (gprng-grr) - tranbase[];
            gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
            gfx_x= gpx - 7 - ( 
              (gxx<0?gfx_charw:0)
              + (gxx==0?1:2)*gfx_charw ); 
            gfx_y= gpy+grr*gpdro+1;
            gfx_drawnumber(gxx,0);
          );
          grr+= 1;
        );
      // - down slider
      ):(
        grh= gpdrh; //ctl heigth for ctl/alt mouse, dimming, etc
        ggcolors && ggcolors[gpc] >= 0 ?( 
          (gvv= ggcolors[gpc+4]) != 1 ?(
            gvv > 0 ?(
              gfx_r= ggcolors[cfade]; gfx_g= ggcolors[cfade+1]; gfx_b= ggcolors[cfade+2]; gfx_a= 1;
              gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
              gfx_rectto(gfx_x+ggbcw, gfx_y+(grh*.5|0)-1);
              gfx_x= gpx+gcc*ggbco; gfx_y= gpy+(grh*.5|0);
              gfx_rectto(gpx+gcc*ggbco+ggbcw, gpy+grh);
            ): gvv= -gvv;
          );
          gfx_r= ggcolors[gpc]; gfx_g= ggcolors[gpc+1]; gfx_b= ggcolors[gpc+2]; gfx_a= gvv; )
        :( gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1; );
        gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
        gfx_rectto(gfx_x+ggbcw, gfx_y+(grh*.5|0)-1);
        gmy= gfx_y; // middle yval for bidi sliders
        gfx_x= gpx+gcc*ggbco; gfx_y= gpy+(grh*.5|0);
        gfx_rectto(gpx+gcc*ggbco+ggbcw, gpy+grh);
        // mouse?
        leftdown && !(mouse_cap & (16|4)) && !nodown
            && mouse_x >= gpx+gcc*ggbco && mouse_x < gpx+gcc*ggbco+ggbcw 
            && mouse_y >= gpy && mouse_y < gpy+grh ?(
          gval= min( max( gprng*(gpy+grh-mouse_y-3)/(grh-6), 0), gprng);
          gcc2= gcc; while ( gpseq[gcc2]= gval;  
              gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gcc2; deltaseqs[gii]= gpseq; 0; ): (gii+= 1) < deltaslen; );
              mouse_cap & 8 && (gcc2+= 1) < maxsteps[]; ); deltas= 1;
        );
        // bar
        gfx_r= ggsr; gfx_g= ggsg; gfx_b= ggsb; gfx_a= ggsa;
        gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grh;
        gfx_rectto(gfx_x+ggbcw, gfx_y-(grh*gpseq[gcc]/gprng+.499|0));
        gfx_r= ggcr; gfx_g= ggcg; gfx_b= ggcb; gfx_a= .33;
        gfx_x= gpx+gcc*ggbco; gfx_y= gmy;
        gfx_rectto(gfx_x+ggbcw, gmy+1);
        // hilite current
        gpp == gcc && ggdotnot ?(
          gfx_r= gghr; gfx_g= gghg; gfx_b= gghb; gfx_a= ggha;
          gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
          gfx_rectto(gfx_x+ggbcw, gfx_y+grh);
        );
        // gate text
        gndx == 3 ?(
          gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
          gfx_x= gpx+gcc*ggbco+ggto; gfx_y= gpy+ggbrh-gfx_texth-3;
          //gfx_drawnumber(gpseq[gcc],1);
          gii= gpseq[gcc]; //+.05;
          gjj= (gii-(gii|0))*10|0;
          gii|= 0;
          !gjj ?( gfx_x+= 10; gfx_drawnumber(gii,0); )
            : gii && gjj ?( gfx_x+= 2; gfx_drawnumber(gpseq[gcc]+.05,1); )
            :( gfx_x+= 4; gfx_drawchar($'.'); gfx_drawnumber(gjj,0); );
        );
      );
    );
    
    // - buttongrid up
    !(gpdn[]) ?(
      grh= ggbrh; //ctl heigth for ctl/alt mouse, dimming, etc
      gbs= btnstyle[]; !gbs ? gbs= $xfa;
      // bg rect
      ggcolors && ggcolors[gpc] >= 0 ?( //special bg color?
        (gvv= ggcolors[gpc+3]) != 1 ?(
          gww= gndx == 1 ? gpseq[gcc]&dirmask : gpseq[gcc];
          gvv= gvv < 0 ? 1-gww/gprng*(1+gvv) : gvv + gww/gprng*(1-gvv);
          gfx_r= ggcolors[gpc]*gvv + ggcolors[cfade]*(1-gvv); 
          gfx_g= ggcolors[gpc+1]*gvv + ggcolors[cfade+1]*(1-gvv); 
          gfx_b= ggcolors[gpc+2]*gvv + ggcolors[cfade+2]*(1-gvv);        
        ):(
          gfx_r= ggcolors[gpc]; gfx_g= ggcolors[gpc+1]; gfx_b= ggcolors[gpc+2]; 
        );
      ):(
        gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb;
      );
      gfx_a= 1; 
      gbr0= gfx_r; gbg0= gfx_g; gbb0= gfx_b;
      gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
      gfx_rectto(gfx_x+ggbcw, gfx_y+grh);
      // 2nd click in button reveals down grid
      gdclick && gdrop == gpseq && gclickcnt < 15
          && mouse_x >= gpx+gcc*ggbco && mouse_x < gpx+gcc*ggbco+ggbcw 
          && mouse_y >= gpy && mouse_y < gpy+grh ?(
        gpdn[]= 1;
      );
      leftclick && (!(mouse_cap & (16|4)) || (mouse_cap & 16 && mouse_cap & 4))
          && mouse_x >= gpx+gcc*ggbco && mouse_x < gpx+gcc*ggbco+ggbcw 
          && mouse_y >= gpy && mouse_y < gpy+grh 
      ?(
        gdrop= gpseq; gdrng= gprng; gdmax= maxsteps[];
        gdcc= gcc; gdy= gpy+ggbro;
        gndx == 3 ? gdx= min(gpx+gcc*ggbco,gfx_w-ggslen-4)
        : gndx == 5 ? gdx= min(gpx+gcc*ggbco,gfx_w-(tranrng[]==24?ggslen:tranrng[]==36?ggslen*1.5:ggslen*2)-4)
/***        : gndx == 1 ? gdx= min(gpx+gcc*ggbco,gfx_w-4*ggbco-4) ***/
        : gdx= min(gpx+gcc*ggbco,gfx_w-gdrng*ggbco-4);
                            //min(...: limit slider to right edge of gfx win
/***        gndx == 1 ?( gdtcc= 4; gdtcw= 31; gdtco= 32; gdtrc= 5; gdtrh= 16; gdtro= 17; );***/
      );
      gndx == 3 ?( ///// - gates
        gbs & bsgatei ?( // bar
          gfx_r= ggsr; gfx_g= ggsg; gfx_b= ggsb; gfx_a= ggsa-ggsa*.2;
          gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
          gfx_rectto(gpx+(gcc*ggbco+ggbcw*gpseq[gcc]/gprng+.5|0), gpy+grh);
          !(gbs & bsgtic) && gpseq[gcc] >= gprng*.5 ?( // >= 1 tick
            gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba*.7;
            gfx_x= gpx+(gcc*ggbco+ggbcw*.5+.5|0)-1; gfx_y= gpy;
            gfx_rectto(gfx_x+1, gpy+2);
          );
        );
      );
      // hilite edited and current
      gdrop == gpseq && gdcc == gcc ?(    
        gfx_r= gfx_g= gfx_b= 0; gfx_a= .2;
        gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
        gfx_rectto(gfx_x+ggbcw, gfx_y+grh);
      );
      gpp == gcc && ggdotnot ?(
        gfx_r= gghr; gfx_g= gghg; gfx_b= gghb; gfx_a= ggha;
        gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
        gfx_rectto(gfx_x+ggbcw, gfx_y+grh);
      );
      
      // draw icon/value
/***      gndx == 1 ?( ///// - dirs button
        // icon
        gval= gpseq[gcc] & dirmask;
        gfx_a= gxx= ggba;
        gii= -1; loop ( 5, gii+= 1;
          gpseq[gcc] & (dirmetabase * 2^gii) ?(
            gcoords[0]= (gii?(gii-1):3)*32; //source_x;
            gcoords[1]= (gii?4:3)*17; //source_y;
            gcoords[2]= 31; gcoords[3]= 16; //source_w/h;
            gcoords[4]= gpx+gcc*ggbco; //dest_x;
            gcoords[5]= gpy; //dest_y;
            gcoords[6]= 31; gcoords[7]= 16; //dest_w/h;
            gcoords[8]= gcoords[9]= 0; //rotation_x/y_offset from center of image
            gfx_blitext(gpseq[gcc] & dirop ? fndirtypes2 : fndirtypes, gcoords, 0);
            gii==2 ? gxx= ggba*.7; //lower central alpha if contracted // or dirop step || gii==4
            gii==4 ? gxx= ggba; //...but not for dirop steps
          );
        );
        gfx_a= gxx;
//        gval==dirlast ?( grr2= 0; gcc2= 1; ) 
//         : gval==dirnext2 ?( grr2= 0; gcc2= 2; ) 
//         : gval==dirnext3 ?( grr2= 0; gcc2= 3; ) 
//         : gval==dirfirst ?( grr2= 1; gcc2= 1; ) 
//         : gval==dirsame ?( grr2= 2; gcc2= 0; ) 
//         :
        ( grr2= gval / 4 | 0; gcc2= gval % 4; );
        gcoords[0]= gcc2*32; //source_x;
        gcoords[1]= grr2*17; //source_y;
        gcoords[2]= 31; gcoords[3]= 16; //source_w/h;
        gcoords[4]= gpx+gcc*ggbco; //dest_x;
        gcoords[5]= gpy; //dest_y;
        gcoords[6]= 31; gcoords[7]= 16; //dest_w/h;
        gcoords[8]= gcoords[9]= 0; //rotation_x/y_offset from center of image
        gfx_blitext(gpseq[gcc] & dirop ? fndirtypes2 : fndirtypes, gcoords, 0);
        gpseq[gcc] & dirconadd ?(
          gfx_x= gpx+gcc*ggbco; gfx_y= gpy; 
          gfx_a= ggba;
          gfx_blit(fnconadd,1,0);
        );
      ):***/ (gndx == 2 || gndx == 4) ?( ///// - lens and vcs button
        // icon
        gndx == 2 && gbs & bsleni ?(
          gfx_a= gbs & bslent ? .18 : ggba*.8;
          gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
          gii= gpseq[gcc];
          gii >= 12 ? gii-= 12;
          gfx_blit(gii+(gbs & bslent ?fnlen0:fnlenb0),1,0);
        ): gndx == 4 && gbs & bsvci ?(
          gfx_a= gbs & bsvct ? .32 : 1; //ggba;
          gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
          gii= gpseq[gcc];
          gii >= 12 ? gii-= 12;
          gfx_blit(gii+(gbs & bsvct ? fnvc0:fnvcb0),1,0);
        );
        // text
        (gndx==2 && gbs & bslent) || (gndx==4 && gbs & bsvct) ?(
          gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
          gfx_x= gpx+gcc*ggbco+10+ggto; gfx_y= gpy+grh-gfx_texth-3;
          gfx_drawchar((gndx==2?$'1':$'0')+gpseq[gcc]);
        );
      ): gndx == 3 ?( ///// - gates button
        // gate text
        gbs & bsgatet ?(
          gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
          gfx_x= gpx+gcc*ggbco+ggto; gfx_y= gpy+grh-gfx_texth-3;
          //gfx_drawnumber(gpseq[gcc],1);
          gii= gpseq[gcc]; //+.05;
          gjj= (gii-(gii|0))*10|0;
          gii|= 0;
          !gjj && gii ?( gfx_x+= 10; gfx_drawnumber(gii,0); )
            : gii && gjj ?( gfx_x+= 2; gfx_drawnumber(gpseq[gcc]+.05,1); )
            :( gfx_x+= 4; gfx_drawchar($'.'); gfx_drawnumber(gjj,0); );
        );
      ): gndx == 5 ?( ///// - trans button
        // icon
        gbs & bstrani ?(
          gfx_a= gbs & bstrant ? .32 : ggba*.9;
          gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
          gii= gpseq[gcc];
          gii > tranbase[] && !(gii % 12) ? gii= 12
          : gii >= 12 ? while ( (gii-= 12) >= 12; );
          gfx_blit(gii+fntran0,1,0);
        );
        // text
        gfx_x= gpx+gcc*ggbco+ggto; gfx_y= gpy+grh-gfx_texth-3;
        gii= gpseq[gcc]-tranbase[];
        abs(gii) < 10 ? gfx_x+= 5;
        gii >= 0 ? gfx_x+= 5;
        gbs & bstrant && gcc < gpcnt[] ?( // blur & lighten around text if not dimmed
          gxx= gfx_x; gyy= gfx_y;
          // lighten around num 4x offset +/-1px
          gfx_r= gfx_g= gfx_b= 1; gfx_a= (gbr0+gbg0+gbb0)*.03;
          gfx_x-= 1; gfx_y-= 1; gfx_drawnumber(gii,0);
          gfx_x= gxx+1; gfx_y= gyy-1; gfx_drawnumber(gii,0);
          gfx_x= gxx+1; gfx_y= gyy+1; gfx_drawnumber(gii,0);
          gfx_x= gxx-1; gfx_y= gyy+1; gfx_drawnumber(gii,0);
          /*** // blur & lighten around text if not dimmed
          gzz= (abs(gii) < 10 ? 1 : 2)*gfx_charw;
          gii < 0 ? gxx+= gfx_charw;
          gfx_x= gxx-2; gfx_y= gyy-2;
          gfx_blurto( gfx_x+gzz+3, gfx_y+gfx_texth+3 );
          gfx_x= gxx-3; gfx_y= gyy-3;
          gfx_blurto( gfx_x+gzz+5, gfx_y+gfx_texth+5 );
          gfx_x= gxx-1; gfx_y= gyy-1;
          gfx_r= gfx_g= gfx_b= 1; gfx_a= .05;
          gfx_rectto( gfx_x+gzz+1, gfx_y+gfx_texth+1 );
          gfx_x= gxx-2; gfx_y= gyy-2;
          gfx_r= gfx_g= gfx_b= 1; gfx_a= .05;
          gfx_rectto( gfx_x+gzz+3, gfx_y+gfx_texth+3 );
          gii < 0 ? gxx-= gfx_charw; //***/
          gfx_x= gxx; gfx_y= gyy;
        );
        gbs & bstrant ?(
          gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
          gfx_drawnumber(gii,0);
        ): gii < 0 ? (
          gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba*.9;
          gfx_x= gpx+gcc*ggbco+ggbcw-gfx_charw-(gii<-2?1:gii==-2?9:8); gfx_y= gpy+1;
          gfx_drawchar($'<');
          //gfx_x= gpx+gcc*ggbco+(gii<-7?4:-10)+(12+gii)*28/12; gfx_y= gpy+1;
          //gfx_drawchar($'-');
        );
      );
    );
    
    leftclick && mouse_x >= gpx+gcc*ggbco && mouse_x < gpx+gcc*ggbco+ggbcw && mouse_y >= gpy && mouse_y < gpy+grh ?(
      // set default value on alt/option click
      mouse_cap & 16 && !(mouse_cap & 4) ?(
        gcc2= gcc; while ( gpseq[gcc2]= gpdef;  
            gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gcc2; deltaseqs[gii]= gpseq; 0; ): (gii+= 1) < deltaslen; );
            mouse_cap & 8 && (gcc2+= 1) < maxsteps[]; ); deltas= 1;
      // set seq position on control/command click
      ): mouse_cap & 4 && !(mouse_cap & 16) ?(
        mouse_cap & 8 ?( 
          memset(posvars, gcc, posvarslen); ctl3pos[]= gcc; ctl4pos[]= gcc;
          paused[] ?( memset(posvars0, gcc, posvarslen); ctl3pos0[]= gcc; ctl4pos0[]= gcc; );//save playback positions for start playback
        ):(
          gppos[]= gcc;
          paused[] ? gppos == ctl3pos ? ctl3pos0[]= gcc : gppos == ctl4pos ? ctl4pos0[]= gcc : posvars0[gppos-posvars]= gcc;
        );
      );
    );
    // set seq len on rightclick
    rightclick && mouse_x >= gpx+gcc*ggbco && mouse_x < gpx+gcc*ggbco+ggbcw && mouse_y >= gpy && mouse_y < gpy+grh ?(
      mouse_cap & 4 ?( //control/cmd: insert step
        gcc2= maxsteps[]-1; while ( gpseq[gcc2]= gpseq[gcc2-1]; (gcc2-= 1) > gcc; );
        gpseq[gcc]= gpdef;
        gcc < gpcnt[] ?(
          slider(gpcnt-slvars+1)= gpcnt[]= gpcnt[]+1; slider_automate(2^(gpcnt-slvars));
        );
      ): mouse_cap & 16 ?( //alt/option: delete step
        gcc2= gcc; while ( gpseq[gcc2]= gpseq[gcc2+1]; (gcc2+= 1) < maxsteps[]-1; );
        gpseq[maxsteps[]-1]= gpdef;
        gcc < gpcnt[] ?(
          slider(gpcnt-slvars+1)= gpcnt[]= gpcnt[]-1; slider_automate(2^(gpcnt-slvars));
        );
      ): mouse_cap & 8 ?( //shift: set all seq lens
        memset(cntvars, gcc+1, cntvarslen);
        gii= cntvars-slvars; loop ( cntvarslen, slider(gii+= 1)= gcc+1; slider_automate(2^(gii-1)); );
        memset(ctl34vars, gcc+1, 2); slider22= slider23= gcc+1; slider_automate(ctl34bits);
      ):( //normal: set seq len
        slider(gpcnt-slvars+1)= gpcnt[]= gcc+1; slider_automate(2^(gpcnt-slvars));
      );
    );
      
    // mark saved play positions
    paused[] && gcc == (gppos == ctl3pos ? ctl3pos0[] : gppos == ctl4pos ? ctl4pos0[] : posvars0[gppos-posvars]) ?(
      gfx_r= ggcr; gfx_g= ggcg; gfx_b= ggcb; gfx_a= 1;
      gfx_x= gpx+gcc*ggbco; gfx_y= gpy+grh-2;
      gfx_rectto(gfx_x+1, gfx_y+2);
      gfx_rectto(gfx_x+1, gfx_y-1);
    );
    // dim n/a steps
    gcc >= gpcnt[] ?(
      gfx_r= ggdr; gfx_g= ggdg; gfx_b= ggdb; gfx_a= ggda;
      gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
      gfx_rectto(gpx+gcc*ggbco+ggbcw, gpy+grh);
      //gfx_x= gpx+gcc*ggbco; gfx_y= gpy;
      //gfx_blurto(gpx+gcc*ggbco+ggbcw, gpy+grh);
    );
    // 4th step marks
    gcc && !(gcc & 3) ?(
      gfx_r= ggcr; gfx_g= ggcg; gfx_b= ggcb; gfx_a= 1;
      gfx_x= gpx+gcc*ggbco-3; gfx_y= gpy;
      gfx_rectto(gfx_x+5, gfx_y+1);
      gfx_x= gpx+gcc*ggbco-2; gfx_y= gpy;
      gfx_rectto(gfx_x+3, gfx_y+2);
    );
    gcc+= 1;
    
  ); //end maxsteps loop
  
  // dot hilites
  ggdot ?(
    gcc= 0; loop ( gpcnt[],
      gcc == gpp ?( gfx_r= gghr; gfx_g= gghg; gfx_b= gghb; gfx_a= ggha )
                 :( gfx_r= gfx_g= gfx_b= ggdotshc; gfx_a= ggdotsha; );
      gfx_a ?(
        gfx_x= gxx= gpx+gcc*ggbco+ggdotx; gfx_y= gpy+ggdoty;
        gfx_rectto(ggdotw<0?gxx-ggdotx+ggbcw+ggdotw+1:gfx_x+ggdotw, gfx_y+ggdoth);
        ggdoth2 ?(
          gfx_x= gxx-ggdotx+ggdotx2; gfx_y= gpy+ggdoty2;
          gfx_rectto(ggdotw2<0?gxx-ggdotx+ggbcw+ggdotw2+1:gfx_x+ggdotw2, gfx_y+ggdoth2);
        );
      );
      gcc+= 1;
    );
  );
  
); //end buttongrids loop  

); !setdn && gdirt ?( //workaround limit on how long ?(...) can be

/////- slidergrids
gndx0= 0; loop ( ctl34on[] ? 6 : 4, gndx0+= 1;
  
  // slidergrid setup
  gndx0 == 1 ?( ///// acc
    gndx= 1;
    // new ctl row
    ggx= ggl+5; 
    // params
    gpx= ggx;      //ctl x pos
    gpy= ggy;      //ctl y pos
    gplh= gglh;    //label height
    gpseq= accs;   //sequence
    gprng= accrng; //seq data range
    gpcnt= acccnt; //seq count
    gppos= accpos; //seq pos
    gpdef= accdef; //seq default val
    gpcw= ggscw;   //col width
    gpco= ggsco;   //col offset
    gph= ggsh;     //slider height
    gpbi= 1;       //bidirectional
    gpc= cacc;
    /*gpt='accent';*/                             (gpt[0]=6; gpt[1]=($'a');gpt[2]=($'c');gpt[3]=($'c');gpt[4]=($'e');gpt[5]=($'n');gpt[6]=($'t'););
  ): gndx0 == 3 ?( ///// off
    gndx= 2;
    // new ctl row
    ggy+= gplh + gph+5; //next row
    ggx= ggl+5; 
    // params
    gpx= ggx;      //ctl x pos
    gpy= ggy;      //ctl y pos
    gplh= gglh;    //label height
    gpseq= offs;   //sequence
    gprng= offrng; //seq data range
    gpcnt= offcnt; //seq count
    gppos= offpos; //seq pos
    gpdef= offdef; //seq default val
    gpcw= ggscw;   //col width
    gpco= ggsco;   //col offset
    gph= ggsh;     //slider height
    gpbi= offbi;       //bidirectional
    gpc= coff;
    /*gpt='offset';*/                             (gpt[0]=6; gpt[1]=($'o');gpt[2]=($'f');gpt[3]=($'f');gpt[4]=($'s');gpt[5]=($'e');gpt[6]=($'t'););
  ): gndx0 == 2 ?( ///// ctl1
    gndx= 3;
    // next ctl col
    ggx+= (maxsteps[]+1)*gpco; //next col
    // params
    gpx= ggx;      //ctl x pos
    gpy= ggy;      //ctl y pos
    gplh= gglh;    //label height
    gpseq= ctl1s;   //sequence
    gprng= ctl1rng; //seq data range
    gpcnt= ctl1cnt; //seq count
    gppos= ctl1pos; //seq pos
    gpdef= ctl1def; //seq default val
    gpcw= ggs2cw;   //col width
    gpco= ggs2co;   //col offset
    gph= ggs2h;     //slider height
    gpbi= ctl1bi[];  //bidirectional
    gpc= cctl1;
    /*gpt='control 1';*/                          (gpt[0]=9; gpt[1]=($'c');gpt[2]=($'o');gpt[3]=($'n');gpt[4]=($'t');gpt[5]=($'r');gpt[6]=($'o');gpt[7]=($'l');gpt[8]=($' ');gpt[9]=($'1'););
  ): gndx0 == 4 ?( ///// ctl2
    gndx= 4;
    // next ctl col
    ggx+= (maxsteps[]+1)*gpco; //next col
    // params
    gpx= ggx;      //ctl x pos
    gpy= ggy;      //ctl y pos
    gplh= gglh;    //label height
    gpseq= ctl2s;   //sequence
    gprng= ctl2rng; //seq data range
    gpcnt= ctl2cnt; //seq count
    gppos= ctl2pos; //seq pos
    gpdef= ctl2def; //seq default val
    gpcw= ggs2cw;   //col width
    gpco= ggs2co;   //col offset
    gph= ggs2h;     //slider height
    gpbi= ctl2bi[];  //bidirectional
    gpc= cctl2;
    /*gpt='control 2';*/                          (gpt[0]=9; gpt[1]=($'c');gpt[2]=($'o');gpt[3]=($'n');gpt[4]=($'t');gpt[5]=($'r');gpt[6]=($'o');gpt[7]=($'l');gpt[8]=($' ');gpt[9]=($'2'););
  ): gndx0 == 5 ?( ///// ctl3
    gndx= 5;
    // new ctl row
    ggy+= gplh + gph+5; //next row
    ggx= ggl+5; 
    // params
    gpx= ggx;      //ctl x pos
    gpy= ggy;      //ctl y pos
    gplh= gglh;    //label height
    gpseq= ctl3s;   //sequence
    gprng= ctl3rng; //seq data range
    gpcnt= ctl3cnt; //seq count
    gppos= ctl3pos; //seq pos
    gpdef= ctl3def; //seq default val
    gpcw= ggs2cw;   //col width
    gpco= ggs2co;   //col offset
    gph= ggs2h;     //slider height
    gpbi= ctl3bi[];  //bidirectional
    gpc= cctl3;
    /*gpt='control 3';*/                          (gpt[0]=9; gpt[1]=($'c');gpt[2]=($'o');gpt[3]=($'n');gpt[4]=($'t');gpt[5]=($'r');gpt[6]=($'o');gpt[7]=($'l');gpt[8]=($' ');gpt[9]=($'3'););
  ): gndx0 == 6 ?( ///// ctl4
    gndx= 6;
    // next ctl col
    ggx+= (maxsteps[]+1)*gpco; //next col
    // params
    gpx= ggx;      //ctl x pos
    gpy= ggy;      //ctl y pos
    gplh= gglh;    //label height
    gpseq= ctl4s;   //sequence
    gprng= ctl4rng; //seq data range
    gpcnt= ctl4cnt; //seq count
    gppos= ctl4pos; //seq pos
    gpdef= ctl4def; //seq default val
    gpcw= ggs2cw;   //col width
    gpco= ggs2co;   //col offset
    gph= ggs2h;     //slider height
    gpbi= ctl4bi[];  //bidirectional
    gpc= cctl4;
    /*gpt='control 4';*/                          (gpt[0]=9; gpt[1]=($'c');gpt[2]=($'o');gpt[3]=($'n');gpt[4]=($'t');gpt[5]=($'r');gpt[6]=($'o');gpt[7]=($'l');gpt[8]=($' ');gpt[9]=($'4'););
  );
  
  // label
  gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1; //text color
  gfx_x= gpx; gfx_y= gpy+gplh-gfx_texth-3;
  gii= 0; loop( gpt[0], gfx_drawchar(gpt[gii+= 1]); );
  // right-click in row label toggles random
  rightclick && mouse_x >= gpx && mouse_x < gfx_x && mouse_y >= gpy && mouse_y < gpy+gplh ?(
    randseq[] & (2^(gndx+4)) ? randseq[]&= $xffff-(2^(gndx+4)) : randseq[]|= 2^(gndx+4); 
    slider21= randseq[]; slider_automate(slider21);
  );
  // altclick debug
  leftclick && mouse_x >= gpx && mouse_x < gfx_x && mouse_y >= gpy && mouse_y < gpy+gplh ?(
    mouse_cap & 16 ?( SHOWDEBUG= dOffset != gpseq ? 1 : !SHOWDEBUG; dOffset= gpseq; ) ///debug array
    :( 
      gndx0==1 || gndx0==2 ? sgrow1dn[]= !(sgrow1dn[]) 
      : gndx0==3 || gndx0==4 ? sgrow2dn[]= !(sgrow2dn[]) 
      : sgrow3dn[]= !(sgrow3dn[]); 
    );
  );
  
  randseq[] & (2^(gndx+4)) ?( gfx_a=ggfa2; gfx_drawchar($'~'); ):  gfx_drawchar($' '); 
  // unique label stuff per gndx 
  gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= ggfa2; //2ndary text color
  paused[] ?( gpp= gppos[]; gpp >= gpcnt[] ? gpp=0; ):( gpp= gpseq[maxmaxsteps]; ); 
      //set current pos here to allow overrides
  gndx == 2 ?( /////- offset text
    // offset pct
    gfx_drawchar($' ');
    gll= gfx_x;
    offpct[] ?( 
      gfx_drawchar($'['); gfx_drawnumber(offpct[],0); gfx_drawchar($'%'); gfx_drawchar($']');
    //):( 
    //  gpp= -1; 
    //  /*puts('[off]');*/                        (gfx_drawchar($'[');gfx_drawchar($'o');gfx_drawchar($'f');gfx_drawchar($'f');gfx_drawchar($']'););
    );
    leftclick && mouse_x >= gll && mouse_x < gfx_x && mouse_y >= gpy && mouse_y < gpy+gglh ?( 
      offpct[] == 0 ? offpct[]= 10 : offpct[] == 10 ? offpct[]= 25 : offpct[] == 25 ? offpct[]= 50 
        : offpct[] == 50 ? offpct[]= 100 : offpct[]= 10; 
      slider19= offpct[]; slider_automate(slider19);
    );
  );
  gndx == 3 || gndx == 4 || gndx == 5 || gndx == 6 ?( /////- cc# text
    // cc# text/ctl
    gfx_drawchar($' '); gfx_drawchar($' ');
    gll= gfx_x;
    gpccc= (gndx==3 ? ctl1cc[] : gndx==4 ? ctl2cc[] : gndx==5 ? ctl3cc[] : ctl4cc[]);
    gpccc >= 0 ?( 
      /*puts('[cc#');*/                           (gfx_drawchar($'[');gfx_drawchar($'c');gfx_drawchar($'c');gfx_drawchar($'#'););
      gfx_drawnumber(gpccc,0);
      /*puts(']');*/                              (gfx_drawchar($']'););
    ): gpccc == -1 ?(
      gndx == 3 || gndx == 6 ?( /*puts('[pitch]'); )*/ (gfx_drawchar($'[');gfx_drawchar($'p');gfx_drawchar($'i');gfx_drawchar($'t');gfx_drawchar($'c');gfx_drawchar($'h');gfx_drawchar($']');); )
      :( /*puts('[improb]'); );*/                 (gfx_drawchar($'[');gfx_drawchar($'i');gfx_drawchar($'m');gfx_drawchar($'p');gfx_drawchar($'r');gfx_drawchar($'o');gfx_drawchar($'b');gfx_drawchar($']');); );
    ):( 
      gpp= -1; 
      /*puts('[off]');*/                          (gfx_drawchar($'[');gfx_drawchar($'o');gfx_drawchar($'f');gfx_drawchar($'f');gfx_drawchar($']'););
    );
    leftclick && mouse_x >= gll && mouse_x < gfx_x && mouse_y >= gpy && mouse_y < gpy+gglh ?(
      gdrop= (gndx==3?gdctl1:gndx==4?gdctl2:gndx==5?gdctl3:gdctl4); gdx= ggl; gdy= ggt; gdtcc= 8; gdtcw= gdtco= 56; gdtrc= 16; gdtrh= gdtro= 14;
    );
  );
  gndx == 2 || gndx == 3 || gndx == 4 || gndx == 5 || gndx == 6 ?( /////- dir text
    // bidi text/ctl
    gfx_drawchar($' '); gfx_drawchar($' ');
    gll= gfx_x;
    gpbi ?( 
      /*puts('[+/-]');*/                          (gfx_drawchar($'[');gfx_drawchar($'+');gfx_drawchar($'/');gfx_drawchar($'-');gfx_drawchar($']'););
    ):( 
      /*puts('[+++]');*/                          (gfx_drawchar($'[');gfx_drawchar($'+');gfx_drawchar($'+');gfx_drawchar($'+');gfx_drawchar($']'););
    );
    leftclick && mouse_x >= gll && mouse_x < gfx_x && mouse_y >= gpy && mouse_y < gpy+gglh ?( 
      gndx == 2 ?( 
        gpbi= offbi= !offbi; gpdef= offdef= offbi?50:0;
        gii= 0; loop ( maxsteps[],
          offs[gii]= offbi ? min(offrng,offs[gii]/2+50) : max(0,(offs[gii]-50)*2); gii+= 1; );
      ): gndx == 3 ?( 
        gpbi= ctl1bi[]= !(ctl1bi[]); gpdef= ctl1def= ctl1bi[]?64:0;
      ): gndx == 4 ?( 
        gpbi= ctl2bi[]= !(ctl2bi[]); gpdef= ctl2def= ctl2bi[]?64:0;
      ): gndx == 5 ?( 
        gpbi= ctl3bi[]= !(ctl3bi[]); gpdef= ctl3def= ctl3bi[]?64:0;
      ):( 
        gpbi= ctl4bi[]= !(ctl4bi[]); gpdef= ctl4def= ctl4bi[]?64:0; 
      );
    );
  );
  
  // big/small label-ctl
  gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= ggfa2; //text color
  gfx_x= gpx+(maxsteps[]-2)*gpco+4; gfx_y= gpy+gplh-gfx_texth-3;
  gll= gfx_x;
  gpdn= gndx0==1 || gndx0== 2 ? sgrow1dn[] : gndx0==3 || gndx0== 4 ? sgrow2dn[] : sgrow3dn[];
  gpdn ?( 
    gfx_drawchar($'[');gfx_drawchar(uarrow);gfx_drawchar($']');
  ):( 
    gph= ggsuph;
    gfx_drawchar($'[');gfx_drawchar(darrow);gfx_drawchar($']');
  );
  leftclick && mouse_x >= gll && mouse_x < gfx_x && mouse_y >= gpy && mouse_y < gpy+gglh ?(
    gndx0==1 || gndx0==2 ? sgrow1dn[]= !(sgrow1dn[]) 
    : gndx0==3 || gndx0==4 ? sgrow2dn[]= !(sgrow2dn[]) 
    : sgrow3dn[]= !(sgrow3dn[]);
  );
  
  // draw slidergrid
  gpy= gpy + gfx_texth + 8;
  gcc= 0; loop ( maxsteps[],
    // bg rect
    ggcolors && ggcolors[gpc+4] && ggcolors[gpc] >= 0 ?( 
      gfx_r= ggcolors[gpc]; gfx_g= ggcolors[gpc+1]; gfx_b= ggcolors[gpc+2]; gfx_a= 1; )
    :( gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1; );
    gfx_x= gpx+gcc*gpco; gfx_y= gpy;
    gfx_rectto(gpx+gcc*gpco+gpcw, gpy+(gph/2|0)-1);
    gmy= gfx_y; // middle yval for bidi sliders
    gfx_x= gpx+gcc*gpco; gfx_y= gpy+(gph/2|0);
    gfx_rectto(gpx+gcc*gpco+gpcw, gpy+gph);
    // do mouse
    gfx_x= gpx+gcc*gpco; gfx_y= gpy+gph; //preset gfx_x/y for use in mousebits
    // set value if leftdown down and no dropdowns
    leftdown && !nodown ?( // !gdrop && 
      mouse_x >= gfx_x && mouse_x < gfx_x+gpcw && mouse_y < gfx_y+2 && mouse_y >= gfx_y-gph-2
      ?( 
        // set default value on alt/option click
        mouse_cap & 16 && !(mouse_cap & 4) ?(
          gcc2= gcc; while ( gpseq[gcc2]= gpdef;  
              gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gcc2; deltaseqs[gii]= gpseq; 0; ): (gii+= 1) < deltaslen; );
              mouse_cap & 8 && (gcc2+= 1) < maxsteps[]; ); deltas= 1;
        // set seq position on control/command click
        ): mouse_cap & 4 && !(mouse_cap & 16) ?(
          mouse_cap & 8 ?( 
            memset(posvars, gcc, posvarslen); ctl3pos[]= gcc; ctl4pos[]= gcc;
            paused[] ?( memset(posvars0, gcc, posvarslen); ctl3pos0[]= gcc; ctl4pos0[]= gcc; );//save playback positions for start playback
          ):(
            gppos[]= gcc;
            paused[] ? gppos == ctl3pos ? ctl3pos0[]= gcc : gppos == ctl4pos ? ctl4pos0[]= gcc : posvars0[gppos-posvars]= gcc;
          );
        // set value on normal click
        ):(
          gcc2= gcc;
          while (
            gpseq[gcc2]= min( max( gfx_y-mouse_y, 0), gph) * gprng / gph; 
                gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gcc2; deltaseqs[gii]= gpseq; 0; ): (gii+= 1) < deltaslen; );
                mouse_cap & 8 && (gcc2+= 1) < maxsteps[];
          ); deltas= 1;
        );
      );
    );
    // set seq len on rightclick
    rightclick && mouse_x >= gfx_x && mouse_x < gfx_x+gpcw && mouse_y < gfx_y+2 && mouse_y >= gfx_y-gph-2 ?( 
      mouse_cap & 4 ?( //control/cmd: insert step
        gcc2= maxsteps[]-1; while ( gpseq[gcc2]= gpseq[gcc2-1]; (gcc2-= 1) > gcc; );
        gpseq[gcc]= gpdef;
        gcc < gpcnt[] ?(
            gndx == 5 ?( slider22= gpcnt[]= gpcnt[]+1; slider_automate(slider22); )
          : gndx == 6 ?( slider23= gpcnt[]= gpcnt[]+1; slider_automate(slider23); )
          : slider(gpcnt-slvars+1)= gpcnt[]= gpcnt[]+1; slider_automate(2^(gpcnt-slvars));
        );
      ): mouse_cap & 16 ?( //alt/option: delete step
        gcc2= gcc; while ( gpseq[gcc2]= gpseq[gcc2+1]; (gcc2+= 1) < maxsteps[]-1; );
        gpseq[maxsteps[]-1]= gpdef;
        gcc < gpcnt[] ?(
            gndx == 5 ?( slider22= gpcnt[]= gpcnt[]-1; slider_automate(slider22); )
          : gndx == 6 ?( slider23= gpcnt[]= gpcnt[]-1; slider_automate(slider23); )
          : slider(gpcnt-slvars+1)= gpcnt[]= gpcnt[]-1; slider_automate(2^(gpcnt-slvars));
        );
      ): mouse_cap & 8 ?( //shift: set all seq lens
        memset(cntvars, gcc+1, cntvarslen);
        gii= cntvars-slvars; loop ( cntvarslen, slider(gii+= 1)= gcc+1; slider_automate(2^(gii-1)); );
        memset(ctl34vars, gcc+1, 2); slider22= slider23= gcc+1; slider_automate(ctl34bits);
      ):( //normal: set seq len
        gndx == 5 ?( slider22= gpcnt[]= gcc+1; slider_automate(slider22); )
        : gndx == 6 ?( slider23= gpcnt[]= gcc+1; slider_automate(slider23); )
        : ( slider(gpcnt-slvars+1)= gpcnt[]= gcc+1; slider_automate(2^(gpcnt-slvars)); );
      );
    );
    // bar
    gfx_r= ggsr; gfx_g= ggsg; gfx_b= ggsb; gfx_a= ggsa;
    gpbi ?(
      gval= gpseq[gcc] - gpdef;
      gval > 0 ?(
        gval= gval/(gprng-gpdef);
        gfx_y= gmy;
        gfx_rectto(gfx_x+gpcw, gfx_y-((gfx_y-gpy)*gval+.499|0));
      ):(
        gval= gval/gpdef;
        gfx_y= gmy+1;
        gfx_rectto(gfx_x+gpcw, gfx_y+((gpy+gph-gfx_y)*(-gval)+.499|0));
      );
    ):(
      gfx_rectto(gfx_x+gpcw, gpy+gph-(gph*gpseq[gcc]/gprng+.499|0));
      gfx_r= ggcr; gfx_g= ggcg; gfx_b= ggcb; gfx_a= .33;
      gfx_x= gpx+gcc*gpco; gfx_y= gmy;
      gfx_rectto(gfx_x+gpcw, gmy+1);
    );
    gpp == gcc && ggdotnot ?(
      // hilite current bg rect
      gfx_r= gghr; gfx_g= gghg; gfx_b= gghb; gfx_a= ggha;
      gfx_x= gpx+gcc*gpco; gfx_y= gpy;
      gfx_rectto(gpx+gcc*gpco+gpcw, gpy+(gph/2|0)-1);
      gfx_x= gpx+gcc*gpco; gfx_y+= 1;
      gfx_rectto(gpx+gcc*gpco+gpcw, gpy+gph);
      gfx_a= 1;
    );

    // mark saved play positions
    paused[] && gcc == (gppos == ctl3pos ? ctl3pos0[] : gppos == ctl4pos ? ctl4pos0[] : posvars0[gppos-posvars]) ?(
      gfx_r= ggcr; gfx_g= ggcg; gfx_b= ggcb; gfx_a= 1;
      gfx_x= gpx+gcc*gpco; gfx_y= gpy+gph-2;
      gfx_rectto(gfx_x+1, gfx_y+2);
      gfx_rectto(gfx_x+1, gfx_y-1);
    );    
    // dim n/a steps
    gcc >= gpcnt[] ?(
      gfx_r= ggdr; gfx_g= ggdg; gfx_b= ggdb; gfx_a= ggda;
      gfx_x= gpx+gcc*gpco; gfx_y= gpy;
      gfx_rectto(gpx+gcc*gpco+gpcw, gpy+gph);
      //gfx_x= gpx+gcc*gpco; gfx_y= gpy;
      //gfx_blurto(gpx+gcc*gpco+gpcw, gpy+gph);
    );
    // 4th step marks
    gcc && !(gcc & 3) ?(
      gfx_r= ggcr; gfx_g= ggcg; gfx_b= ggcb; gfx_a= 1;
      gfx_x= gpx+gcc*gpco-3; gfx_y= gpy;
      gfx_rectto(gfx_x+5, gfx_y+1);
      gfx_x= gpx+gcc*gpco-2; gfx_y= gpy;
      gfx_rectto(gfx_x+3, gfx_y+2);
    );
    gcc+= 1;
  );

  // dot hilites
  ggdot && gpp >= 0 ?(
    gcc= 0; loop ( gpcnt[],
      gcc == gpp ?( gfx_r= gghr; gfx_g= gghg; gfx_b= gghb; gfx_a= ggha )
                 :( gfx_r= gfx_g= gfx_b= ggdotshc; gfx_a= ggdotsha; );
      gfx_a ?(
        gfx_x= gxx= gpx+gcc*gpco+ggdotx; gfx_y= gpy+ggdoty;
        gfx_rectto((ggdotw<0?gpx+gcc*gpco+gpcw+ggdotw+1:gfx_x+ggdotw), gfx_y+ggdoth);
        ggdoth2 ?(
          gfx_x= gxx-ggdotx+ggdotx2; gfx_y= gpy+ggdoty2;
          gfx_rectto(ggdotw2<0?gpx+gcc*gpco+gpcw+ggdotw2+1:gfx_x+ggdotw2, gfx_y+ggdoth2);
        );
      );
      gcc+= 1;
    );
  );

); // end slidergrids loop

// new row
ggx = ggl; ggy+= gplh + gph+10; //next row

); !setdn && gdirt ?( //workaround limit on how long ?(...) can be

//- variants
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
gfx_x= ggx; gfx_y= ggy+ggbrh-gfx_texth-3;
/*puts('  vars');*/                               (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'v');gfx_drawchar($'a');gfx_drawchar($'r');gfx_drawchar($'s'););
leftclick && mouse_cap & 16 && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
  !(mouse_cap & 8) ?( SHOWDEBUG= dOffset != vntmap ? 1 : !SHOWDEBUG; dOffset= vntmap; dvo= trans; )
  :( dvo==dirs ? dvo= lens : dvo==lens ? dvo= gates : dvo==gates ? dvo= vcs 
    : dvo==vcs ? dvo= trans : dvo==trans ? dvo= accs 
    : dvo==accs ? dvo= offs : dvo==offs ? dvo= ctl1s : dvo==ctl1s ? dvo= ctl2s 
    : dvo==ctl2s ? dvo= ctl3s : dvo==ctl3s ? dvo= ctl4s : dvo= dirs; 
););
ggx= gfx_x + 6;
gco= ggbco; gcw= ggbcw;
gcc= 0; loop ( vntcnt,
  // click?
  (leftclick||rightclick) && mouse_x >= ggx+gcc*gco && mouse_x < ggx+gcc*gco+gcw && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
    gww= mouse_cap & 8 ? vntnosave : 0; //save changes to current unless shift-click
    gww|= rightclick ? vntdopos : 0;
    newvnt= gcc|gww;
    nodown= 1;
  );
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx+gcc*gco; gfx_y= ggy;
  gfx_rectto(ggx+gcc*gco+gcw, ggy+ggbrh);
  // hilight selected
  gcc == vnt ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx+gcc*gco; gfx_y= ggy;
    gfx_rectto(ggx+gcc*gco+gcw, ggy+ggbrh);
  );
  // text
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
  gfx_x= ggx+gcc*gco+ggto+9-(ggbcw-gcw)/2; gfx_y= ggy+ggbrh-gfx_texth-3;
  gcc > 8 ? gfx_x-= gfx_charw/2;
  gfx_drawnumber( gcc+1, 0 );
  // mouseover?
  mouse_x >= ggx+gcc*gco && mouse_x < ggx+gcc*gco+gcw && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
    gfx_r= gfx_g= gfx_b= 0; gfx_a= ggma;
    gfx_x= ggx+gcc*gco; gfx_y= ggy;
    gfx_rectto(ggx+gcc*gco+gcw, ggy+ggbrh);
  );
  gcc+= 1;
);
ggx+= vntcnt*gco+10;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= ggfa2;
!(vntcnt < maxvnts) ? gfx_a=.42;
gfx_x= ggx; gfx_y= ggy+ggbrh-gfx_texth-3;
/*puts('[+]');*/                                  (gfx_drawchar($'[');gfx_drawchar($'+');gfx_drawchar($']'););
ggx0= gfx_x;
vntcnt < maxvnts ?(
  leftclick && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
    // init new vnt as copy of current
    offuni[]= !offbi;
    memcpy(dirsserial,dirs,maxmaxsteps+2);
    memcpy(vntmap[vntcnt]+vntslvars,slvars,slvarslen);
    memcpy(vntmap[vntcnt]+vntprevars,prevars,prevarslen);
    memcpy(vntmap[vntcnt]+vntprevars2,prevars2,prevars2len);
    memcpy(vntmap[vntcnt]+vntserial,0,seriallen);
(vntmap[vntcnt]+vntserial)[0]= (vntcnt+1.5);//debug
    gww= mouse_cap & 8 ? vntnosave : 0 ; //save changes to current unless shift-click
    newvnt= vntcnt|gww;
    vntcnt+= 1;
  );
);
ggx= ggx0+10;
ggdelvnt ?( gfx_r= 1; gfx_g= 0; gfx_b= 0; gfx_a= 1; )
:( gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= ggfa2; );
!(vntcnt > 1) ? gfx_a=.42;
gfx_x= ggx; gfx_y= ggy+ggbrh-gfx_texth-3;
/*puts('[-]');*/                                  (gfx_drawchar($'[');gfx_drawchar($'-');gfx_drawchar($']'););
ggx0= gfx_x;
vntcnt > 1 ?(
  leftclick||rightclick ?(
    mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
      ggdelvnt ?(
        gww= vntmap[vnt];
        gvv= vnt; loop ( vntcnt - vnt - 1,
          vntmap[gvv] = vntmap[gvv+1];
          gvv+= 1;
        );
        vntmap[gvv]= gww;
        vntcnt-= 1;
(vntmap[vntcnt]+vntserial)[0]= -.5;//debug
        gww= rightclick ? vntdopos : 0;
        newvnt= (vnt < vntcnt ? vnt : 0)|vntnosave|gww;
        ggdelvnt= 0; 
        nodown= 1;
      ): ggdelvnt= 1;
    ): ggdelvnt= 0;
  );
);
ggx= ggx0+10;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= ggfa2;
gfx_x= ggx; gfx_y= ggy+ggbrh-gfx_texth-3;
//vntedit ?( /*puts('[edit ALL]'); )*/            (gfx_drawchar($'[');gfx_drawchar($'e');gfx_drawchar($'d');gfx_drawchar($'i');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'A');gfx_drawchar($'L');gfx_drawchar($'L');gfx_drawchar($']');); )
//:( /*puts('[edit one]'); );*/                   (gfx_drawchar($'[');gfx_drawchar($'e');gfx_drawchar($'d');gfx_drawchar($'i');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'o');gfx_drawchar($'n');gfx_drawchar($'e');gfx_drawchar($']');); );
gfx_drawchar($'[');gfx_drawchar(dtri);gfx_drawchar($']');
leftclick && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh ?(
//  vntedit= !vntedit;
  gdrop= gdvarx; gdx= ggx; gdy= ggy+ggbro;
  /*gdt='copy|paste|apply changes to ALL variants||';*/ (gdt[0]=42; gdt[1]=($'c');gdt[2]=($'o');gdt[3]=($'p');gdt[4]=($'y');gdt[5]=($'|');gdt[6]=($'p');gdt[7]=($'a');gdt[8]=($'s');gdt[9]=($'t');gdt[10]=($'e');gdt[11]=($'|');gdt[12]=($'a');gdt[13]=($'p');gdt[14]=($'p');gdt[15]=($'l');gdt[16]=($'y');gdt[17]=($' ');gdt[18]=($'c');gdt[19]=($'h');gdt[20]=($'a');gdt[21]=($'n');gdt[22]=($'g');gdt[23]=($'e');gdt[24]=($'s');gdt[25]=($' ');gdt[26]=($'t');gdt[27]=($'o');gdt[28]=($' ');gdt[29]=($'A');gdt[30]=($'L');gdt[31]=($'L');gdt[32]=($' ');gdt[33]=($'v');gdt[34]=($'a');gdt[35]=($'r');gdt[36]=($'i');gdt[37]=($'a');gdt[38]=($'n');gdt[39]=($'t');gdt[40]=($'s');gdt[41]=($'|');gdt[42]=($'|'););
);
gdvarx[] == 3 ?( //apply deltas
  vntedit= 1;
  newvnt= vnt;
  gdvarx[]= 0;
);
  
// new row
ggx = ggl; ggy+= ggbro+5;

//- notes
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
gfx_x= ggx; gfx_y= ggy+ggbrh-gfx_texth-3;
loadnotes[] ?( gfx_a=ggfa2; gfx_drawchar(rarrow); gfx_a= 1; ): gfx_drawchar($' ');
/*puts('notes');*/                                (gfx_drawchar($'n');gfx_drawchar($'o');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($'s'););
leftclick && mouse_cap & 16 && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh 
?( SHOWDEBUG= dOffset != evmsgs ? 1 : !SHOWDEBUG; dOffset= evmsgs; );
rightclick && mouse_x >= ggx && mouse_x < gfx_x && mouse_y >= ggy && mouse_y < ggy+ggbrh 
?( loadnotes[]= !(loadnotes[]); );
ggx= gfx_x + 6;
// backgrounds
gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= .7; //.6;
gcc= 0;
loop ( maxsteps[],
  // bg rect
  gfx_x= ggx+gcc*ggbco; gfx_y= ggy;
  gfx_rectto(ggx+gcc*ggbco+ggbcw, ggy+ggbrh);
  gcc+= 1;
);
gfx_a= 1;
// hilite current notes
notecnt && lastcnt && ggdotnot ?(
  gii= 0;
  gfx_r= gghr; gfx_g= gghg; gfx_b= gghb; gfx_a= ggha; //min(ggha+.2,1);
  while (
    gcc= lastnotes[gii];
    gcc < maxsteps[] && gcc < notecnt ?(
      gfx_x= ggx+gcc*ggbco; gfx_y= ggy;
      gfx_rectto(ggx+gcc*ggbco+ggbcw, ggy+ggbrh);
    );
    (gii+= 1) < lastcnt;
  );
);
// note names
gcc= 0;
loop ( min(notecnt,maxsteps[]),
  // note text
  gfx_r= gfx_g= gfx_b= 0; gfx_a= .6;
  gfx_x= ggx+gcc*ggbco+3; gfx_y= ggy+ggbrh-gfx_texth-3;
  gcc2= sort[] ? notesort[gcc] : gcc;
  gfx_drawchar(notenm[notes[gcc2]%12]);
  notenm2[notes[gcc2]%12] ? gfx_drawchar(notenm2[notes[gcc2]%12]);
  gfx_drawnumber(notes[gcc2]/12|0,0);
  // velocity bar
  gfx_r= gfx_g= gfx_b= 0; gfx_a= .1;
  gfx_x= ggx+gcc*ggbco; gfx_y= ggy;
  gfx_rectto(ggx+gcc*ggbco+ggbcw*vels[gcc2]/$x7f, ggy+ggbrh);
  gfx_a= 1; 
  ggdot ?(
    gii= 0; while ( gcc != lastnotes[gii] && (gii+= 1) < lastcnt );
    gii < lastcnt ?( gfx_r= gghr; gfx_g= gghg; gfx_b= gghb; gfx_a= ggha )
                  :( gfx_r= gfx_g= gfx_b= ggdotshc; gfx_a= ggdotsha; );
    gfx_a ?(
      gfx_x= gxx= ggx+gcc*ggbco+ggdotx; gfx_y= ggy+ggdoty;
      gfx_rectto(ggdotw<0?gxx-ggdotx+ggbcw+ggdotw+1:gfx_x+ggdotw, gfx_y+ggdoth);
      ggdoth2 ?(
        gfx_x= gxx-ggdotx+ggdotx2; gfx_y= ggy+ggdoty2;
        gfx_rectto(ggdotw2<0?gxx-ggdotx+ggbcw+ggdotw2+1:gfx_x+ggdotw2, gfx_y+ggdoth2);
      );
    );
  );
  gcc+= 1;
);

// new row
ggx = ggl; ggy+= ggbro;

// dirty logic
gdirt ? ggh= ggy; //remember last y extent for mouseover logic, debug
gdirt= 0;

); 

!setdn && !gdirt ? ggy= ggh; // set y extent as if last draw was done

/////- settings pane
setdn ?(

ggy+= 5;

gro= gfx_texth+3;
gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('max steps: ');*/                          (gfx_drawchar($'m');gfx_drawchar($'a');gfx_drawchar($'x');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($'p');gfx_drawchar($'s');gfx_drawchar($':');gfx_drawchar($' '););
ggx= gfx_x;
gii= 0; loop ( 3,
    gii==0 ? /*gpt='16'*/                         (gpt[0]=2; gpt[1]=($'1');gpt[2]=($'6');)
  : gii==1 ? /*gpt='24'*/                         (gpt[0]=2; gpt[1]=($'2');gpt[2]=($'4');)
  : gii==2 ? /*gpt='32';*/                        (gpt[0]=2; gpt[1]=($'3');gpt[2]=($'2'););
  gsel= maxsteps[]==gii*8+16;
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  );
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x+2 && mouse_y >= ggy-2 && mouse_y < ggy+gro ?( 
    slider18= maxsteps[]= gii*8+16;
    gjj= 0; loop ( cntvarslen, cntvars[gjj]= min(maxsteps[], cntvars[gjj]); gjj+= 1; );
    ctl3cnt[]= min(maxsteps[],ctl3cnt[]); ctl4cnt[]= min(maxsteps[],ctl4cnt[]); 
     slider_automate(slbits);
  );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);

ggx= ggl + 35*gfx_charw; 
gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('control 3/4: ');*/                        (gfx_drawchar($'c');gfx_drawchar($'o');gfx_drawchar($'n');gfx_drawchar($'t');gfx_drawchar($'r');gfx_drawchar($'o');gfx_drawchar($'l');gfx_drawchar($' ');gfx_drawchar($'3');gfx_drawchar($'/');gfx_drawchar($'4');gfx_drawchar($':');gfx_drawchar($' '););
ggx= gfx_x;
gii= 0; loop ( 2,
    gii==0 ? /*gpt='no'*/                         (gpt[0]=2; gpt[1]=($'n');gpt[2]=($'o');)
  : gii==1 ? /*gpt='yes';*/                       (gpt[0]=3; gpt[1]=($'y');gpt[2]=($'e');gpt[3]=($'s'););
  gsel= !(ctl34on[]) == !gii;
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  );
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x+2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
  ?( ctl34on[]= gii; );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);

// new row
ggx= ggl; ggy= gfx_y + gro*1.5;

gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('midi bus: ');*/                           (gfx_drawchar($'m');gfx_drawchar($'i');gfx_drawchar($'d');gfx_drawchar($'i');gfx_drawchar($' ');gfx_drawchar($'b');gfx_drawchar($'u');gfx_drawchar($'s');gfx_drawchar($':');gfx_drawchar($' '););
ggx= gfx_x;
gii= 1; loop ( 16,
  gsel= gii == chanbus+1;
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+(gii<10?1:2)*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+(gii<10?1:2)*gfx_charw+4, gfx_y+gro);
  );
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gfx_drawnumber(gii,0); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x+2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
  ?( chanbusx= gii-1; chanbusx != chanbus ? evclear= 1; );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);

// new row
ggx= ggl; ggy= gfx_y + gro*1.5;

gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('midi control: ');*/                       (gfx_drawchar($'m');gfx_drawchar($'i');gfx_drawchar($'d');gfx_drawchar($'i');gfx_drawchar($' ');gfx_drawchar($'c');gfx_drawchar($'o');gfx_drawchar($'n');gfx_drawchar($'t');gfx_drawchar($'r');gfx_drawchar($'o');gfx_drawchar($'l');gfx_drawchar($':');gfx_drawchar($' '););
//ggx= ggl; ggy+= gro+2;
//gfx_x= ggx; gfx_y= ggy;
///*puts('  ');*/                                 (gfx_drawchar($' ');gfx_drawchar($' '););
ggx= gfx_x;
gii= 0; loop ( 3,
  gii==0 ? /*gpt='off'*/                          (gpt[0]=3; gpt[1]=($'o');gpt[2]=($'f');gpt[3]=($'f');)
  : gii==1 ? /*gpt='basic'*/                      (gpt[0]=5; gpt[1]=($'b');gpt[2]=($'a');gpt[3]=($'s');gpt[4]=($'i');gpt[5]=($'c');)
  : gii==2 ? /*gpt='extended';*/                  (gpt[0]=8; gpt[1]=($'e');gpt[2]=($'x');gpt[3]=($'t');gpt[4]=($'e');gpt[5]=($'n');gpt[6]=($'d');gpt[7]=($'e');gpt[8]=($'d'););
  gsel= gii == mccenable;
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  );
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x-2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
  ? mccenable= gii;
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);

ggx= ggl + 35*gfx_charw; 
gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('midi lock: ');*/                          (gfx_drawchar($'m');gfx_drawchar($'i');gfx_drawchar($'d');gfx_drawchar($'i');gfx_drawchar($' ');gfx_drawchar($'l');gfx_drawchar($'o');gfx_drawchar($'c');gfx_drawchar($'k');gfx_drawchar($':');gfx_drawchar($' '););
ggx= gfx_x;
gii= 0; loop ( 2,
    gii==0 ? /*gpt='no'*/                         (gpt[0]=2; gpt[1]=($'n');gpt[2]=($'o');)
  : gii==1 ? /*gpt='yes';*/                       (gpt[0]=3; gpt[1]=($'y');gpt[2]=($'e');gpt[3]=($'s'););
  gsel= !(midilock[]) == !gii;
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  );
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x+2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
  ?( midilock[]= gii; );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);

// new row
ggx= ggl; ggy= gfx_y + gro*1.5;

gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('tick mode: ');*/                          (gfx_drawchar($'t');gfx_drawchar($'i');gfx_drawchar($'c');gfx_drawchar($'k');gfx_drawchar($' ');gfx_drawchar($'m');gfx_drawchar($'o');gfx_drawchar($'d');gfx_drawchar($'e');gfx_drawchar($':');gfx_drawchar($' '););
ggx= gfx_x;
gii= 0; loop ( 2,
    gii==0 ? /*gpt='synchronized'*/               (gpt[0]=12; gpt[1]=($'s');gpt[2]=($'y');gpt[3]=($'n');gpt[4]=($'c');gpt[5]=($'h');gpt[6]=($'r');gpt[7]=($'o');gpt[8]=($'n');gpt[9]=($'i');gpt[10]=($'z');gpt[11]=($'e');gpt[12]=($'d');)
  : gii==1 ? /*gpt='absolute';*/                  (gpt[0]=8; gpt[1]=($'a');gpt[2]=($'b');gpt[3]=($'s');gpt[4]=($'o');gpt[5]=($'l');gpt[6]=($'u');gpt[7]=($'t');gpt[8]=($'e'););
  gsel= !(tick[] < 0) == !gii;
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  );
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  !gsel && leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x+2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
  ?( togglesync= 1; );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);

ggx= ggl + 35*gfx_charw; 

gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('octaves mode: ');*/                       (gfx_drawchar($'o');gfx_drawchar($'c');gfx_drawchar($'t');gfx_drawchar($'a');gfx_drawchar($'v');gfx_drawchar($'e');gfx_drawchar($'s');gfx_drawchar($' ');gfx_drawchar($'m');gfx_drawchar($'o');gfx_drawchar($'d');gfx_drawchar($'e');gfx_drawchar($':');gfx_drawchar($' '););
ggx= gfx_x;
gii= 0; loop ( 2,
    gii==0 ? /*gpt='replicant'*/                  (gpt[0]=9; gpt[1]=($'r');gpt[2]=($'e');gpt[3]=($'p');gpt[4]=($'l');gpt[5]=($'i');gpt[6]=($'c');gpt[7]=($'a');gpt[8]=($'n');gpt[9]=($'t');)
  : gii==1 ? /*gpt='heuristic';*/                 (gpt[0]=9; gpt[1]=($'h');gpt[2]=($'e');gpt[3]=($'u');gpt[4]=($'r');gpt[5]=($'i');gpt[6]=($'s');gpt[7]=($'t');gpt[8]=($'i');gpt[9]=($'c'););
  gsel= !(octmode[]) == !gii;
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  );
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x+2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
  ?( octmode[]= gii; );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);

// new row
ggx= ggl; ggy= gfx_y + gro*1.5;

); setdn ?( //workaround max ?(...) len

gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('swing steps: ');*/                        (gfx_drawchar($'s');gfx_drawchar($'w');gfx_drawchar($'i');gfx_drawchar($'n');gfx_drawchar($'g');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($'p');gfx_drawchar($'s');gfx_drawchar($':');gfx_drawchar($' '););
ggx= gfx_x;
gii= 2; loop ( 15,
  gsel= gii == swingsteps[];
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+(gii<10?1:2)*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+(gii<10?1:2)*gfx_charw+4, gfx_y+gro);
  );
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gfx_drawnumber(gii,0); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x+2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
  ?( slider20= swingsteps[]= gii; slider_automate(slider20); );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);

// new row
ggx= ggl; ggy= gfx_y + gro*1.5;

gro= gfx_texth+3;
gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('trans range: ');*/                        (gfx_drawchar($'t');gfx_drawchar($'r');gfx_drawchar($'a');gfx_drawchar($'n');gfx_drawchar($'s');gfx_drawchar($' ');gfx_drawchar($'r');gfx_drawchar($'a');gfx_drawchar($'n');gfx_drawchar($'g');gfx_drawchar($'e');gfx_drawchar($':');gfx_drawchar($' '););
ggx= gfx_x;
gii= 0; loop ( 3,
    gii==0 ? /*gpt='24'*/                         (gpt[0]=2; gpt[1]=($'2');gpt[2]=($'4');)
  : gii==1 ? /*gpt='36'*/                         (gpt[0]=2; gpt[1]=($'3');gpt[2]=($'6');)
  : gii==2 ? /*gpt='48';*/                        (gpt[0]=2; gpt[1]=($'4');gpt[2]=($'8'););
  gsel= tranrng[]==gii*12+24;
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  );
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x+2 && mouse_y >= ggy-2 && mouse_y < ggy+gro ?( 
    tranrng[]= gii*12+24; //slider_automate(slider18);
  );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);

ggx= ggl + 35*gfx_charw; 
gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('trans base: ');*/                         (gfx_drawchar($'t');gfx_drawchar($'r');gfx_drawchar($'a');gfx_drawchar($'n');gfx_drawchar($'s');gfx_drawchar($' ');gfx_drawchar($'b');gfx_drawchar($'a');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($':');gfx_drawchar($' '););
ggx= gfx_x;
gii= 0; loop ( 3,
    gii==0 ? /*gpt='-24'*/                        (gpt[0]=3; gpt[1]=($'-');gpt[2]=($'2');gpt[3]=($'4');)
  : gii==1 ? /*gpt='-12'*/                        (gpt[0]=3; gpt[1]=($'-');gpt[2]=($'1');gpt[3]=($'2');)
  : gii==2 ? /*gpt='0';*/                         (gpt[0]=1; gpt[1]=($'0'););
  gsel= tranbase[]==24-gii*12;
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  );
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x+2 && mouse_y >= ggy-2 && mouse_y < ggy+gro ?( 
    tranbase[]= 24-gii*12; //slider_automate(slider18);
  );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);

// new row
ggx= ggl; ggy= gfx_y + gro*1.5;

gfx_x=ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('random sequence (dis)order: ');*/         (gfx_drawchar($'r');gfx_drawchar($'a');gfx_drawchar($'n');gfx_drawchar($'d');gfx_drawchar($'o');gfx_drawchar($'m');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'q');gfx_drawchar($'u');gfx_drawchar($'e');gfx_drawchar($'n');gfx_drawchar($'c');gfx_drawchar($'e');gfx_drawchar($' ');gfx_drawchar($'(');gfx_drawchar($'d');gfx_drawchar($'i');gfx_drawchar($'s');gfx_drawchar($')');gfx_drawchar($'o');gfx_drawchar($'r');gfx_drawchar($'d');gfx_drawchar($'e');gfx_drawchar($'r');gfx_drawchar($':');gfx_drawchar($' '););
gfx_x= ggl; gfx_y= (ggy+= gro+2);
/*puts('  ');*/                                   (gfx_drawchar($' ');gfx_drawchar($' '););
ggx= gfx_x;
gii= 0; loop ( 11,
    gii==0 ? /*gpt='dir'*/                        (gpt[0]=3; gpt[1]=($'d');gpt[2]=($'i');gpt[3]=($'r');)
  : gii==1 ? /*gpt='length'*/                     (gpt[0]=6; gpt[1]=($'l');gpt[2]=($'e');gpt[3]=($'n');gpt[4]=($'g');gpt[5]=($'t');gpt[6]=($'h');)
  : gii==2 ? /*gpt='gate'*/                       (gpt[0]=4; gpt[1]=($'g');gpt[2]=($'a');gpt[3]=($'t');gpt[4]=($'e');)
  : gii==3 ? /*gpt='voices'*/                     (gpt[0]=6; gpt[1]=($'v');gpt[2]=($'o');gpt[3]=($'i');gpt[4]=($'c');gpt[5]=($'e');gpt[6]=($'s');)
  : gii==4 ? /*gpt='trans'*/                      (gpt[0]=5; gpt[1]=($'t');gpt[2]=($'r');gpt[3]=($'a');gpt[4]=($'n');gpt[5]=($'s');)
  : gii==5 ? /*gpt='accent'*/                     (gpt[0]=6; gpt[1]=($'a');gpt[2]=($'c');gpt[3]=($'c');gpt[4]=($'e');gpt[5]=($'n');gpt[6]=($'t');)
  : gii==6 ? /*gpt='offset'*/                     (gpt[0]=6; gpt[1]=($'o');gpt[2]=($'f');gpt[3]=($'f');gpt[4]=($'s');gpt[5]=($'e');gpt[6]=($'t');)
  : gii==7 ? /*gpt='ctl1'*/                       (gpt[0]=4; gpt[1]=($'c');gpt[2]=($'t');gpt[3]=($'l');gpt[4]=($'1');)
  : gii==8 ? /*gpt='ctl2'*/                       (gpt[0]=4; gpt[1]=($'c');gpt[2]=($'t');gpt[3]=($'l');gpt[4]=($'2');)
  : gii==9 ? /*gpt='ctl3'*/                       (gpt[0]=4; gpt[1]=($'c');gpt[2]=($'t');gpt[3]=($'l');gpt[4]=($'3');)
  : gii==10 ? /*gpt='ctl4';*/                     (gpt[0]=4; gpt[1]=($'c');gpt[2]=($'t');gpt[3]=($'l');gpt[4]=($'4'););
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel= randseq[] & 2^gii;
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  );
  // text
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x-2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
  ?( randseq[] & (2^gii) ? randseq[]&= $xffff-(2^gii) : randseq[]|= 2^gii; );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);

// new row
ggx= ggl; ggy= gfx_y + gro*1.5;

); setdn ?( //workaround max ?(...) len

//- sortx settings
gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('sort transform: ');*/                     (gfx_drawchar($'s');gfx_drawchar($'o');gfx_drawchar($'r');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'r');gfx_drawchar($'a');gfx_drawchar($'n');gfx_drawchar($'s');gfx_drawchar($'f');gfx_drawchar($'o');gfx_drawchar($'r');gfx_drawchar($'m');gfx_drawchar($':');gfx_drawchar($' '););
ggx= gfx_x;
gii= 0; loop ( 2,
    gii==0 ? /*gpt='off'*/                        (gpt[0]=3; gpt[1]=($'o');gpt[2]=($'f');gpt[3]=($'f');)
  : gii==1 ? /*gpt='on';*/                        (gpt[0]=2; gpt[1]=($'o');gpt[2]=($'n'););
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel= !(sortx[]) == !gii;
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  );
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x-2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
  ?( dosortx= sortx[]= slider30= gii?-1:0; slider_automate(slider30); );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);
// sortx name
ggx= ggl; ggy= gfx_y + gro;
gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('    name: ');*/                           (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'n');gfx_drawchar($'a');gfx_drawchar($'m');gfx_drawchar($'e');gfx_drawchar($':');gfx_drawchar($' '););
ggx= gfx_x;
gjj= -1; while ( gvv= sortxpat[gjj+= 1]; gvv ?( gfx_drawchar(gvv); 1; ): 0; );
// sortx pat
ggx= ggl; ggy= gfx_y + gro;
gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
ggx= gfx_x;
/*puts('   steps: ');*/                           (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($'p');gfx_drawchar($'s');gfx_drawchar($':');gfx_drawchar($' '););
while ( sortxpat[gjj+= 1]>=0?gfx_drawchar($'+');gfx_drawnumber(sortxpat[gjj],1);gfx_drawchar($',');gvv= sortxpat[gjj+= 1]; gfx_drawchar($'*');gvv>0 && gvv<.1 ?( gfx_drawchar($'~');gfx_drawchar($'0');): gfx_drawnumber(gvv,1); gvv ? gfx_drawchar($','); );
ggx= ggl; ggy= gfx_y + gro;
gfx_x= ggx; gfx_y= ggy;
/*puts('  prefix: ');*/                           (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'p');gfx_drawchar($'r');gfx_drawchar($'e');gfx_drawchar($'f');gfx_drawchar($'i');gfx_drawchar($'x');gfx_drawchar($':');gfx_drawchar($' '););
while ( gvv= sortxpat[gjj+= 1]; gfx_drawnumber(gvv,0); gvv ? gfx_drawchar($','); );
ggx= ggl; ggy= gfx_y + gro;
gfx_x= ggx; gfx_y= ggy;
/*puts('  repeat: ');*/                           (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'r');gfx_drawchar($'e');gfx_drawchar($'p');gfx_drawchar($'e');gfx_drawchar($'a');gfx_drawchar($'t');gfx_drawchar($':');gfx_drawchar($' '););
gvv= 0; while ( 
  gvv ? gfx_drawchar($','); 
  gvv= sortxpat[gjj+= 1]; 
  gvv ?(
    gfx_x + (2+1)*gfx_charw > ggw ?(
      gfx_x= ggl; gfx_y+= gro;
      /*puts('          ');*/                     (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' '););
    );
    gfx_drawnumber(gvv,0);
  ):( 
    gvv= sortxpat[gjj+= 1]; 
    gfx_x + (1+(gvv<0?10:gvv==0?3:gvv==1?17:gvv==2?14:gvv==3?22))*gfx_charw > ggw ?(
      gfx_x= ggl; gfx_y+= gro;
      /*puts('          ');*/                     (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' '););
    );
    gvv ?(
      gvv < 0 ?( gfx_drawchar($'(');gfx_drawchar($'0');gfx_drawchar($','); gfx_drawnumber(gvv,0);gfx_drawchar($',');gfx_drawnumber(sortxpat[gjj+= 1],0);gfx_drawchar($')'); 
      ): gvv > 0 ?( 
        gfx_drawchar($'(');gfx_drawchar($'0');gfx_drawchar($','); gfx_drawnumber(gvv,0); gfx_drawchar($',');gfx_drawnumber(sortxpat[gjj+= 1],2);
        loop ( gvv==1 ? 2 : gvv==2 ? 1 : gvv==3 ? 4,
          gfx_drawchar($',');gfx_drawnumber(sortxpat[gjj+= 1],0);
        );
        gfx_drawchar($')'); 
      );
    ):( 
      gfx_drawchar($'0');gfx_drawchar($',');gfx_drawchar($'0');
    );
  );
  gvv;
);
// sortx redo
ggx= ggl; ggy= gfx_y + gro + 5;
gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('  update transform on: ');*/              (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'u');gfx_drawchar($'p');gfx_drawchar($'d');gfx_drawchar($'a');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'r');gfx_drawchar($'a');gfx_drawchar($'n');gfx_drawchar($'s');gfx_drawchar($'f');gfx_drawchar($'o');gfx_drawchar($'r');gfx_drawchar($'m');gfx_drawchar($' ');gfx_drawchar($'o');gfx_drawchar($'n');gfx_drawchar($':');gfx_drawchar($' '););
//ggx= ggl; ggy= gfx_y + gro;
//gfx_x= ggx; gfx_y= ggy;
///*puts('          ');*/                         (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' '););
ggx= gfx_x;
gii= 1; loop ( 4,
    gii==1 ? /*gpt='dir | '*/                     (gpt[0]=6; gpt[1]=($'d');gpt[2]=($'i');gpt[3]=($'r');gpt[4]=($' ');gpt[5]=($'|');gpt[6]=($' ');)
  : gii==2 ? /*gpt='dir  |'*/                     (gpt[0]=6; gpt[1]=($'d');gpt[2]=($'i');gpt[3]=($'r');gpt[4]=($' ');gpt[5]=($' ');gpt[6]=($'|');)
  : gii==3 ? /*gpt='octave cycles'*/              (gpt[0]=13; gpt[1]=($'o');gpt[2]=($'c');gpt[3]=($'t');gpt[4]=($'a');gpt[5]=($'v');gpt[6]=($'e');gpt[7]=($' ');gpt[8]=($'c');gpt[9]=($'y');gpt[10]=($'c');gpt[11]=($'l');gpt[12]=($'e');gpt[13]=($'s');)
  : gii==4 ? /*gpt='note cycles';*/               (gpt[0]=11; gpt[1]=($'n');gpt[2]=($'o');gpt[3]=($'t');gpt[4]=($'e');gpt[5]=($' ');gpt[6]=($'c');gpt[7]=($'y');gpt[8]=($'c');gpt[9]=($'l');gpt[10]=($'e');gpt[11]=($'s'););
  gii==1 ? gpt[6] = 17 : gii==2 ? gpt[5] = 16;
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel= resortx[] & 2^(gii-1);
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  );
  // text
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x-2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
  ?( resortx[] & (2^(gii-1)) ? resortx[]&= $xffff-(2^(gii-1)) : resortx[]|= 2^(gii-1); slider31= resortx[]; slider_automate(slider31); );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);
// sortx load file
ggx= ggl; ggy= gfx_y + gro + 5;
gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('    load: ');*/                           (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'l');gfx_drawchar($'o');gfx_drawchar($'a');gfx_drawchar($'d');gfx_drawchar($':');gfx_drawchar($' '););
leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x-2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
?( sortxmenu[0]= 0; );
ggx= gfx_x;
gndx= 0;
gii= 1; sortxmenu[0] > 1 ? while (
  // load from sortxmenu if possible
  gndx+= 2;
  gjj= 0; while ( (gpt[gjj+=1]= sortxmenu[gndx+=1]) != ($'|') ); gpt[0]= gjj-1; 
  // wrap if this item extends past right edge of gfx window
  ggx + (gpt[0]+1)*gfx_charw > ggw ?(
    ggx= ggl; ggy= gfx_y + gro+3;
    gfx_x= ggx; gfx_y= ggy;
    /*puts('          ');*/                       (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' '););
    ggx= gfx_x;
  );
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // text
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * .8;
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x-2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
  ?( dosortx= sortx[]= gii; );//sortxmenumap[gii-1]; );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
  sortxmenu[gndx+1] != ($'|');
);

// new row
ggx= ggl; ggy= gfx_y + gro*2;

); setdn ?( //workaround max ?(...) len

gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('play/pause with host: ');*/               (gfx_drawchar($'p');gfx_drawchar($'l');gfx_drawchar($'a');gfx_drawchar($'y');gfx_drawchar($'/');gfx_drawchar($'p');gfx_drawchar($'a');gfx_drawchar($'u');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($' ');gfx_drawchar($'w');gfx_drawchar($'i');gfx_drawchar($'t');gfx_drawchar($'h');gfx_drawchar($' ');gfx_drawchar($'h');gfx_drawchar($'o');gfx_drawchar($'s');gfx_drawchar($'t');gfx_drawchar($':');gfx_drawchar($' '););
ggx= gfx_x;
gii= 0; loop ( 2,
    gii==0 ? /*gpt='no'*/                         (gpt[0]=2; gpt[1]=($'n');gpt[2]=($'o');)
  : gii==1 ? /*gpt='yes';*/                       (gpt[0]=3; gpt[1]=($'y');gpt[2]=($'e');gpt[3]=($'s'););
  gsel= !(hostplay[]) == !gii;
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  );
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x+2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
  ?( hostplay[]= gii; );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);

ggx= ggl + 35*gfx_charw; 
gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('midi through when paused: ');*/           (gfx_drawchar($'m');gfx_drawchar($'i');gfx_drawchar($'d');gfx_drawchar($'i');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'h');gfx_drawchar($'r');gfx_drawchar($'o');gfx_drawchar($'u');gfx_drawchar($'g');gfx_drawchar($'h');gfx_drawchar($' ');gfx_drawchar($'w');gfx_drawchar($'h');gfx_drawchar($'e');gfx_drawchar($'n');gfx_drawchar($' ');gfx_drawchar($'p');gfx_drawchar($'a');gfx_drawchar($'u');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'d');gfx_drawchar($':');gfx_drawchar($' '););
ggx= gfx_x;
gii= 0; loop ( 2,
    gii==0 ? /*gpt='no'*/                         (gpt[0]=2; gpt[1]=($'n');gpt[2]=($'o');)
  : gii==1 ? /*gpt='yes';*/                       (gpt[0]=3; gpt[1]=($'y');gpt[2]=($'e');gpt[3]=($'s'););
  gsel= !(midithru[]) == !gii;
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  );
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x+2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
  ?( midithru[]= gii; );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);

// new row
ggx= ggl; ggy= gfx_y + gro*1.5;

gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('clear notes on host seek: ');*/           (gfx_drawchar($'c');gfx_drawchar($'l');gfx_drawchar($'e');gfx_drawchar($'a');gfx_drawchar($'r');gfx_drawchar($' ');gfx_drawchar($'n');gfx_drawchar($'o');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($'s');gfx_drawchar($' ');gfx_drawchar($'o');gfx_drawchar($'n');gfx_drawchar($' ');gfx_drawchar($'h');gfx_drawchar($'o');gfx_drawchar($'s');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'e');gfx_drawchar($'k');gfx_drawchar($':');gfx_drawchar($' '););
ggx= gfx_x;
gii= 0; loop ( 2,
    gii==0 ? /*gpt='no'*/                         (gpt[0]=2; gpt[1]=($'n');gpt[2]=($'o');)
  : gii==1 ? /*gpt='yes';*/                       (gpt[0]=3; gpt[1]=($'y');gpt[2]=($'e');gpt[3]=($'s'););
  gsel= !(seekclear[]) == !gii;
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  );
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x+2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
  ?( seekclear[]= gii; );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);

ggx= ggl + 35*gfx_charw; 
gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('load preset notes: ');*/                  (gfx_drawchar($'l');gfx_drawchar($'o');gfx_drawchar($'a');gfx_drawchar($'d');gfx_drawchar($' ');gfx_drawchar($'p');gfx_drawchar($'r');gfx_drawchar($'e');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'n');gfx_drawchar($'o');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($'s');gfx_drawchar($':');gfx_drawchar($' '););
ggx= gfx_x;
gii= 0; loop ( 2,
    gii==0 ? /*gpt='no'*/                         (gpt[0]=2; gpt[1]=($'n');gpt[2]=($'o');)
  : gii==1 ? /*gpt='yes';*/                       (gpt[0]=3; gpt[1]=($'y');gpt[2]=($'e');gpt[3]=($'s'););
  gsel= !(loadnotes[]) == !gii;
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= ggx-2; gfx_y= ggy-2;
  gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  // hilight selected
  gsel ?(
    gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
  );
  gfx_x= ggx; gfx_y= ggy;
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
  gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
  leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x+2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
  ?( loadnotes[]= gii; );
  /*puts(' ');*/                                  (gfx_drawchar($' '););
  ggx= gfx_x+3;
  gii+= 1;
);

// new row
ggx= ggl; ggy= gfx_y + gro*2;

); setdn ?( //workaround max ?(...) len

gfx_x= ggx; gfx_y= ggy;
gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
/*puts('colors: ');*/                             (gfx_drawchar($'c');gfx_drawchar($'o');gfx_drawchar($'l');gfx_drawchar($'o');gfx_drawchar($'r');gfx_drawchar($'s');gfx_drawchar($':');gfx_drawchar($' '););
leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x+2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
?( gotsettings= 0; );
ggx0= ggx= gfx_x;
gii= 0; loop ( skincnt,
    gii==0 ? /*gpt='clarity'*/                    (gpt[0]=7; gpt[1]=($'c');gpt[2]=($'l');gpt[3]=($'a');gpt[4]=($'r');gpt[5]=($'i');gpt[6]=($'t');gpt[7]=($'y');)
  : gii==1 ? /*gpt='sopwith'*/                    (gpt[0]=7; gpt[1]=($'s');gpt[2]=($'o');gpt[3]=($'p');gpt[4]=($'w');gpt[5]=($'i');gpt[6]=($'t');gpt[7]=($'h');)
  : gii==2 ? /*gpt='nightshade'*/                 (gpt[0]=10; gpt[1]=($'n');gpt[2]=($'i');gpt[3]=($'g');gpt[4]=($'h');gpt[5]=($'t');gpt[6]=($'s');gpt[7]=($'h');gpt[8]=($'a');gpt[9]=($'d');gpt[10]=($'e');)
  : gii==3 ? /*gpt='viridian'*/                   (gpt[0]=8; gpt[1]=($'v');gpt[2]=($'i');gpt[3]=($'r');gpt[4]=($'i');gpt[5]=($'d');gpt[6]=($'i');gpt[7]=($'a');gpt[8]=($'n');)
  : gii==4 ? /*gpt='black-light-blue'*/           (gpt[0]=16; gpt[1]=($'b');gpt[2]=($'l');gpt[3]=($'a');gpt[4]=($'c');gpt[5]=($'k');gpt[6]=($'-');gpt[7]=($'l');gpt[8]=($'i');gpt[9]=($'g');gpt[10]=($'h');gpt[11]=($'t');gpt[12]=($'-');gpt[13]=($'b');gpt[14]=($'l');gpt[15]=($'u');gpt[16]=($'e');)
  :( gjj= 0; gcc= colors1+(gii-5)*colorslen; while ( gpt[gjj+= 1]= gcc[cname+gjj-1]; ); gpt[0]= gjj-1; );
  
  gpt[0] ?(
    // wrap if this item extends past right edge of gfx window
    ggx + (gpt[0]+1)*gfx_charw > ggw ?(
      ggx= ggl; ggy= gfx_y + gro+3;
      gfx_x= ggx; gfx_y= ggy;
      /*puts('        ');*/                       (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' '););
      ggx= gfx_x;
    );
    gsel= skin[]==gii;
    // bg rect
    gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
    gfx_x= ggx-2; gfx_y= ggy-2;
    gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
    // hilight selected
    gsel ?(
      gfx_r= ggh2r; gfx_g= ggh2g; gfx_b= ggh2b; gfx_a= ggh2a;
      gfx_x= ggx-2; gfx_y= ggy-2;
      gfx_rectto(gfx_x+gpt[0]*gfx_charw+4, gfx_y+gro);
    );
    gfx_x= ggx; gfx_y= ggy;
    gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba * (gsel?1:.8);
    gjj= 0; loop( gpt[0], gfx_drawchar(gpt[gjj+= 1]); ); 
    leftclick && mouse_x >= ggx-2 && mouse_x < gfx_x+2 && mouse_y >= ggy-2 && mouse_y < ggy+gro 
    ?( skin[]= gii; lastskin= -1; );
    /*puts(' ');*/                                (gfx_drawchar($' '););
    ggx= gfx_x+3;
  ):(
    ggx > ggx0 ?(
      ggx= ggl; ggy= gfx_y + gro+3;
      gfx_x= ggx; gfx_y= ggy;
      /*puts('        ');*/                       (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($' '););
      ggx= gfx_x;
    );
  );
  gii+= 1;
);

// new row
ggx= ggl; ggy= gfx_y + gro*1.5;

); setdn ?(

gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a=1;
gfx_x= ggx; gfx_y= ggy;
                         /*puts('complete quick reference in arpbangzero_documentation.pdf.');*/ (gfx_drawchar($'c');gfx_drawchar($'o');gfx_drawchar($'m');gfx_drawchar($'p');gfx_drawchar($'l');gfx_drawchar($'e');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($' ');gfx_drawchar($'q');gfx_drawchar($'u');gfx_drawchar($'i');gfx_drawchar($'c');gfx_drawchar($'k');gfx_drawchar($' ');gfx_drawchar($'r');gfx_drawchar($'e');gfx_drawchar($'f');gfx_drawchar($'e');gfx_drawchar($'r');gfx_drawchar($'e');gfx_drawchar($'n');gfx_drawchar($'c');gfx_drawchar($'e');gfx_drawchar($' ');gfx_drawchar($'i');gfx_drawchar($'n');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($'r');gfx_drawchar($'p');gfx_drawchar($'b');gfx_drawchar($'a');gfx_drawchar($'n');gfx_drawchar($'g');gfx_drawchar($'z');gfx_drawchar($'e');gfx_drawchar($'r');gfx_drawchar($'o');gfx_drawchar($'_');gfx_drawchar($'d');gfx_drawchar($'o');gfx_drawchar($'c');gfx_drawchar($'u');gfx_drawchar($'m');gfx_drawchar($'e');gfx_drawchar($'n');gfx_drawchar($'t');gfx_drawchar($'a');gfx_drawchar($'t');gfx_drawchar($'i');gfx_drawchar($'o');gfx_drawchar($'n');gfx_drawchar($'.');gfx_drawchar($'p');gfx_drawchar($'d');gfx_drawchar($'f');gfx_drawchar($'.'););
gfx_y+= gro; 
gfx_x= ggx; gfx_y+= gro; /*puts('- click sequence steps to set values.  add shift when selecting a new');*/ (gfx_drawchar($'-');gfx_drawchar($' ');gfx_drawchar($'c');gfx_drawchar($'l');gfx_drawchar($'i');gfx_drawchar($'c');gfx_drawchar($'k');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'q');gfx_drawchar($'u');gfx_drawchar($'e');gfx_drawchar($'n');gfx_drawchar($'c');gfx_drawchar($'e');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($'p');gfx_drawchar($'s');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'o');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'v');gfx_drawchar($'a');gfx_drawchar($'l');gfx_drawchar($'u');gfx_drawchar($'e');gfx_drawchar($'s');gfx_drawchar($'.');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($'d');gfx_drawchar($'d');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'h');gfx_drawchar($'i');gfx_drawchar($'f');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'w');gfx_drawchar($'h');gfx_drawchar($'e');gfx_drawchar($'n');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'l');gfx_drawchar($'e');gfx_drawchar($'c');gfx_drawchar($'t');gfx_drawchar($'i');gfx_drawchar($'n');gfx_drawchar($'g');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($' ');gfx_drawchar($'n');gfx_drawchar($'e');gfx_drawchar($'w'););
gfx_x= ggx; gfx_y+= gro; /*puts('  value to also set all steps to the right.');*/ (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'v');gfx_drawchar($'a');gfx_drawchar($'l');gfx_drawchar($'u');gfx_drawchar($'e');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'o');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($'l');gfx_drawchar($'s');gfx_drawchar($'o');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($'l');gfx_drawchar($'l');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($'p');gfx_drawchar($'s');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'o');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'h');gfx_drawchar($'e');gfx_drawchar($' ');gfx_drawchar($'r');gfx_drawchar($'i');gfx_drawchar($'g');gfx_drawchar($'h');gfx_drawchar($'t');gfx_drawchar($'.'););
gfx_x= ggx; gfx_y+= gro; /*puts('- right-click to set sequence length.  add shift to set all sequence');*/ (gfx_drawchar($'-');gfx_drawchar($' ');gfx_drawchar($'r');gfx_drawchar($'i');gfx_drawchar($'g');gfx_drawchar($'h');gfx_drawchar($'t');gfx_drawchar($'-');gfx_drawchar($'c');gfx_drawchar($'l');gfx_drawchar($'i');gfx_drawchar($'c');gfx_drawchar($'k');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'o');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'q');gfx_drawchar($'u');gfx_drawchar($'e');gfx_drawchar($'n');gfx_drawchar($'c');gfx_drawchar($'e');gfx_drawchar($' ');gfx_drawchar($'l');gfx_drawchar($'e');gfx_drawchar($'n');gfx_drawchar($'g');gfx_drawchar($'t');gfx_drawchar($'h');gfx_drawchar($'.');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($'d');gfx_drawchar($'d');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'h');gfx_drawchar($'i');gfx_drawchar($'f');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'o');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($'l');gfx_drawchar($'l');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'q');gfx_drawchar($'u');gfx_drawchar($'e');gfx_drawchar($'n');gfx_drawchar($'c');gfx_drawchar($'e'););
gfx_x= ggx; gfx_y+= gro; /*puts('  lengths.');*/  (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'l');gfx_drawchar($'e');gfx_drawchar($'n');gfx_drawchar($'g');gfx_drawchar($'t');gfx_drawchar($'h');gfx_drawchar($'s');gfx_drawchar($'.'););
gfx_x= ggx; gfx_y+= gro; /*puts('- alt/option-click to set default values.  add shift to set all steps.');*/ (gfx_drawchar($'-');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($'l');gfx_drawchar($'t');gfx_drawchar($'/');gfx_drawchar($'o');gfx_drawchar($'p');gfx_drawchar($'t');gfx_drawchar($'i');gfx_drawchar($'o');gfx_drawchar($'n');gfx_drawchar($'-');gfx_drawchar($'c');gfx_drawchar($'l');gfx_drawchar($'i');gfx_drawchar($'c');gfx_drawchar($'k');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'o');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'d');gfx_drawchar($'e');gfx_drawchar($'f');gfx_drawchar($'a');gfx_drawchar($'u');gfx_drawchar($'l');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'v');gfx_drawchar($'a');gfx_drawchar($'l');gfx_drawchar($'u');gfx_drawchar($'e');gfx_drawchar($'s');gfx_drawchar($'.');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($'d');gfx_drawchar($'d');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'h');gfx_drawchar($'i');gfx_drawchar($'f');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'o');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($'l');gfx_drawchar($'l');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($'p');gfx_drawchar($'s');gfx_drawchar($'.'););
gfx_x= ggx; gfx_y+= gro; /*puts('  to the right.');*/ (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'o');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'h');gfx_drawchar($'e');gfx_drawchar($' ');gfx_drawchar($'r');gfx_drawchar($'i');gfx_drawchar($'g');gfx_drawchar($'h');gfx_drawchar($'t');gfx_drawchar($'.'););
gfx_x= ggx; gfx_y+= gro; /*puts('- control/command-click to set current step.  add shift for all');*/ (gfx_drawchar($'-');gfx_drawchar($' ');gfx_drawchar($'c');gfx_drawchar($'o');gfx_drawchar($'n');gfx_drawchar($'t');gfx_drawchar($'r');gfx_drawchar($'o');gfx_drawchar($'l');gfx_drawchar($'/');gfx_drawchar($'c');gfx_drawchar($'o');gfx_drawchar($'m');gfx_drawchar($'m');gfx_drawchar($'a');gfx_drawchar($'n');gfx_drawchar($'d');gfx_drawchar($'-');gfx_drawchar($'c');gfx_drawchar($'l');gfx_drawchar($'i');gfx_drawchar($'c');gfx_drawchar($'k');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'o');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'c');gfx_drawchar($'u');gfx_drawchar($'r');gfx_drawchar($'r');gfx_drawchar($'e');gfx_drawchar($'n');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($'p');gfx_drawchar($'.');gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($'d');gfx_drawchar($'d');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'h');gfx_drawchar($'i');gfx_drawchar($'f');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'f');gfx_drawchar($'o');gfx_drawchar($'r');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($'l');gfx_drawchar($'l'););
gfx_x= ggx; gfx_y+= gro; /*puts('  sequences.');*/ (gfx_drawchar($' ');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'q');gfx_drawchar($'u');gfx_drawchar($'e');gfx_drawchar($'n');gfx_drawchar($'c');gfx_drawchar($'e');gfx_drawchar($'s');gfx_drawchar($'.'););
gfx_x= ggx; gfx_y+= gro; /*puts('- alt/option-right-click to delete step.');*/ (gfx_drawchar($'-');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($'l');gfx_drawchar($'t');gfx_drawchar($'/');gfx_drawchar($'o');gfx_drawchar($'p');gfx_drawchar($'t');gfx_drawchar($'i');gfx_drawchar($'o');gfx_drawchar($'n');gfx_drawchar($'-');gfx_drawchar($'r');gfx_drawchar($'i');gfx_drawchar($'g');gfx_drawchar($'h');gfx_drawchar($'t');gfx_drawchar($'-');gfx_drawchar($'c');gfx_drawchar($'l');gfx_drawchar($'i');gfx_drawchar($'c');gfx_drawchar($'k');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'o');gfx_drawchar($' ');gfx_drawchar($'d');gfx_drawchar($'e');gfx_drawchar($'l');gfx_drawchar($'e');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($'p');gfx_drawchar($'.'););
gfx_x= ggx; gfx_y+= gro; /*puts('- control/command-right-click to insert step.');*/ (gfx_drawchar($'-');gfx_drawchar($' ');gfx_drawchar($'c');gfx_drawchar($'o');gfx_drawchar($'n');gfx_drawchar($'t');gfx_drawchar($'r');gfx_drawchar($'o');gfx_drawchar($'l');gfx_drawchar($'/');gfx_drawchar($'c');gfx_drawchar($'o');gfx_drawchar($'m');gfx_drawchar($'m');gfx_drawchar($'a');gfx_drawchar($'n');gfx_drawchar($'d');gfx_drawchar($'-');gfx_drawchar($'r');gfx_drawchar($'i');gfx_drawchar($'g');gfx_drawchar($'h');gfx_drawchar($'t');gfx_drawchar($'-');gfx_drawchar($'c');gfx_drawchar($'l');gfx_drawchar($'i');gfx_drawchar($'c');gfx_drawchar($'k');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'o');gfx_drawchar($' ');gfx_drawchar($'i');gfx_drawchar($'n');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'r');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($'p');gfx_drawchar($'.'););
gfx_y+= gro; 
gfx_x= ggx; gfx_y+= gro; /*puts('- click row grid labels to reveal controls for all steps at once.');*/ (gfx_drawchar($'-');gfx_drawchar($' ');gfx_drawchar($'c');gfx_drawchar($'l');gfx_drawchar($'i');gfx_drawchar($'c');gfx_drawchar($'k');gfx_drawchar($' ');gfx_drawchar($'r');gfx_drawchar($'o');gfx_drawchar($'w');gfx_drawchar($' ');gfx_drawchar($'g');gfx_drawchar($'r');gfx_drawchar($'i');gfx_drawchar($'d');gfx_drawchar($' ');gfx_drawchar($'l');gfx_drawchar($'a');gfx_drawchar($'b');gfx_drawchar($'e');gfx_drawchar($'l');gfx_drawchar($'s');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'o');gfx_drawchar($' ');gfx_drawchar($'r');gfx_drawchar($'e');gfx_drawchar($'v');gfx_drawchar($'e');gfx_drawchar($'a');gfx_drawchar($'l');gfx_drawchar($' ');gfx_drawchar($'c');gfx_drawchar($'o');gfx_drawchar($'n');gfx_drawchar($'t');gfx_drawchar($'r');gfx_drawchar($'o');gfx_drawchar($'l');gfx_drawchar($'s');gfx_drawchar($' ');gfx_drawchar($'f');gfx_drawchar($'o');gfx_drawchar($'r');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($'l');gfx_drawchar($'l');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($'p');gfx_drawchar($'s');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'o');gfx_drawchar($'n');gfx_drawchar($'c');gfx_drawchar($'e');gfx_drawchar($'.'););
gfx_x= ggx; gfx_y+= gro; /*puts('- text in [brackets] are clickable controls.');*/ (gfx_drawchar($'-');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($'x');gfx_drawchar($'t');gfx_drawchar($' ');gfx_drawchar($'i');gfx_drawchar($'n');gfx_drawchar($' ');gfx_drawchar($'[');gfx_drawchar($'b');gfx_drawchar($'r');gfx_drawchar($'a');gfx_drawchar($'c');gfx_drawchar($'k');gfx_drawchar($'e');gfx_drawchar($'t');gfx_drawchar($'s');gfx_drawchar($']');gfx_drawchar($' ');gfx_drawchar($'a');gfx_drawchar($'r');gfx_drawchar($'e');gfx_drawchar($' ');gfx_drawchar($'c');gfx_drawchar($'l');gfx_drawchar($'i');gfx_drawchar($'c');gfx_drawchar($'k');gfx_drawchar($'a');gfx_drawchar($'b');gfx_drawchar($'l');gfx_drawchar($'e');gfx_drawchar($' ');gfx_drawchar($'c');gfx_drawchar($'o');gfx_drawchar($'n');gfx_drawchar($'t');gfx_drawchar($'r');gfx_drawchar($'o');gfx_drawchar($'l');gfx_drawchar($'s');gfx_drawchar($'.'););
gfx_x= ggx; gfx_y+= gro; /*puts('- right-click to hide settings/help pane.');*/ (gfx_drawchar($'-');gfx_drawchar($' ');gfx_drawchar($'r');gfx_drawchar($'i');gfx_drawchar($'g');gfx_drawchar($'h');gfx_drawchar($'t');gfx_drawchar($'-');gfx_drawchar($'c');gfx_drawchar($'l');gfx_drawchar($'i');gfx_drawchar($'c');gfx_drawchar($'k');gfx_drawchar($' ');gfx_drawchar($'t');gfx_drawchar($'o');gfx_drawchar($' ');gfx_drawchar($'h');gfx_drawchar($'i');gfx_drawchar($'d');gfx_drawchar($'e');gfx_drawchar($' ');gfx_drawchar($'s');gfx_drawchar($'e');gfx_drawchar($'t');gfx_drawchar($'t');gfx_drawchar($'i');gfx_drawchar($'n');gfx_drawchar($'g');gfx_drawchar($'s');gfx_drawchar($'/');gfx_drawchar($'h');gfx_drawchar($'e');gfx_drawchar($'l');gfx_drawchar($'p');gfx_drawchar($' ');gfx_drawchar($'p');gfx_drawchar($'a');gfx_drawchar($'n');gfx_drawchar($'e');gfx_drawchar($'.'););

// new row
ggx= ggl; ggy= gfx_y + gro*2 + 5;

rightclick ?( setdn= 0; rightclick= 0; );

///// end settings pane
);

/////- dropdowns
/* dropdown param vars:
  gdrop- sequence, or id for choicegrids
  gdrng- seq values range
  gdmax- seq max col; for grid drops
  gdcc-  seq selected col; from source buttongrid
  gdy-   dropdown top pos
  gdx-   dropdown left pos
  gdtcc- tile col count; for choice grid drops
  gdtcw- tile col width
  gdtco- tile col offset
  gdtrc- tile row count
  gdtrh- tile row height
  gdtro- tile row offset
*/

//- text menus
gdrop == gdsortx || gdrop == gdvarx ?(
  // scan gdt
  grr= gcc= 0;
  gii= 0; while (
    gii0= gii;
    while ( gdt[gii+=1] != $'|' && gii < gdtlen; );
    gii-gii0 > gcc ? gcc= gii-gii0;
    grr+= 1;
    gdt[gii+1] != $'|' && gii < gdtlen;
  );
  // frame rect
  gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
  gfx_x= gdx-2; gfx_y= gdy-2;
  gfx_rectto(gdx+gcc*gfx_charw+2, gdy+grr*(gfx_texth+3)+2);
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= gdx; gfx_y= gdy;
  gfx_rectto(gdx+gcc*gfx_charw, gdy+grr*(gfx_texth+3));
  gii= 0; grr= 0; while (
    // text
    gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
    gxx= gdx; gfx_x=gxx+gfx_charw*.5; gfx_y= gdy+grr*(gfx_texth+3)+2;
    while ( gdt[gii+=1] != $'|' && gii < gdtlen ?(gfx_drawchar(gdt[gii]); 1;):0; );
    // mouseover?
    mouse_x >= gxx && mouse_x < gxx+gfx_charw*gcc && mouse_y >= gfx_y-2 && mouse_y < gfx_y+gfx_texth+1 ?(
      gfx_r= gfx_g= gfx_b= 0; gfx_a= ggma;
      gfx_x= gxx; gfx_y-= 2;
      gfx_rectto(gfx_x+gfx_charw*gcc, gfx_y+gfx_texth+3);
      gdclick || release ?( 
        gdrop[]= grr+1;
        gdrop= 0;
      );
    );
    grr+= 1;
    gdt[gii+1] != $'|' && gii < gdtlen;
  );
//- icon button grids
// ): 0 && gdrop == dirs ?(
//   // frame rect
//   gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
//   gfx_x= gdx-2; gfx_y= gdy-2;
//   gfx_rectto(gdx+gdrng*ggbco+1, gdy+ggbrh+2);
//   gcc= 0; loop ( gdrng,
//     // bg rect
//     gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
//     gfx_x= gdx+gcc*ggbco; gfx_y= gdy;
//     gfx_rectto(gdx+gcc*ggbco+ggbcw, gdy+ggbrh);
//     // icon
//     gfx_a= ggba;
//     gfx_x= gdx+gcc*ggbco; gfx_y= gdy;
//     gfx_blit(fnstep0+gcc,1,0); //???
//     // mouseover?
//     mouse_x >= gdx+gcc*ggbco && mouse_x < gdx+gcc*ggbco+ggbcw && mouse_y >= gdy && mouse_y < gdy+ggbrh ?(
//       gfx_r= gfx_g= gfx_b= 0; gfx_a= ggma;
//       gfx_x= gdx+gcc*ggbco; gfx_y= gdy;
//       gfx_rectto(gdx+gcc*ggbco+ggbcw, gdy+ggbrh);
//       gdclick || release ?( 
//         while ( gdrop[gdcc]= gcc;  
//             gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gcc2; deltaseqs[gii]= gpseq; 0; ): (gii+= 1) < deltaslen; );
//             mouse_cap & 8 && (gdcc+= 1) < gdmax; ); deltas= 1;
//         mouse_cap & 2 ?( norelease= 1; gdclick= 0; ) //rightclick keeps dropdown
//                       : gdrop= 0;
//       );
//     );
//     gfx_a= 1;
//     gcc+= 1;
//   );
//   
//- number button grids
): gdrop == lens || gdrop == vcs ?(
  // frame rect
  gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
  gfx_x= gdx-2; gfx_y= gdy-2;
  gfx_rectto(gdx+gdrng*ggbco+1, gdy+ggbrh+2);
  gcc= 0;
  loop ( gdrng,
    // bg rect
    gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
    gfx_x= gdx+gcc*ggbco; gfx_y= gdy;
    gfx_rectto(gdx+gcc*ggbco+ggbcw, gdy+ggbrh);
    // text
    gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
    gfx_x= gdx+gcc*ggbco+10+ggto; gfx_y= gdy+ggbrh-gfx_texth-3;
    gfx_drawchar((gdrop == lens?$'1':$'0')+gcc); //??? 
    // mouseover?
    mouse_x >= gdx+gcc*ggbco && mouse_x < gdx+gcc*ggbco+ggbcw && mouse_y >= gdy && mouse_y < gdy+ggbrh ?(
      gfx_r= gfx_g= gfx_b= 0; gfx_a= ggma;
      gfx_x= gdx+gcc*ggbco; gfx_y= gdy;
      gfx_rectto(gdx+gcc*ggbco+ggbcw, gdy+ggbrh);
      gdclick || release ?(
        while ( 
          gdrop[gdcc]= gcc; 
          gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gdcc; deltaseqs[gii]= gdrop; 0; ): (gii+= 1) < deltaslen; );
          mouse_cap & 8 && (gdcc+= 1) < gdmax;
        ); deltas= 1; 
        mouse_cap & 2 ?( norelease= 1; gdclick= 0; ) //rightclick keeps dropdown
                      : gdrop= 0;
      );
    );
    gfx_a= 1;
    gcc+= 1;
  );
);

gissync= gdrop == syncfracs;
gndx= 0; loop ( 2, gndx+= 1;

//- sliders
(gndx == 2 && (gdrop == gates || gdrop == trans || (gissync && tick[] >= 0)))
|| (gndx == 1 && (gdrop == syncfracs && tick[] < 0))
?(
  gissync ?(
    gslen= gdtcc*gdtco-(gdtco-gdtcw);
    gdy1= tick[] >= 0 ? gdy + gdtrc*gdtro-(gdtro-gdtrh)+2 : gdy; 
  ):(
    gslen= gdrop != trans || gdrng == 24 ? ggslen : gdrng == 36 ? ggslen * 1.5 : ggslen * 2;
    gdy1= gdy;
  );
  // frame rect
  gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
  gfx_x= gdx-2; gfx_y= gdy1-2;
  gfx_rectto(gdx+gslen+2, gdy1+ggbrh+2);
  // bg rect
  gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
  gfx_x= gdx; gfx_y= gdy1;
  gissync ?(
    gfx_rectto(gdx+(gslen*(gddef-gdbase)/gdrng+.499|0)-1, gdy1+ggbrh);
    gmx= gfx_x; //mid val for bidi
    gfx_x= gdx+(gslen*(gddef-gdbase)/gdrng+.499|0); gfx_y= gdy1;
    gfx_rectto(gdx+gslen, gdy1+ggbrh);
  ): gdrop != trans || gdrng != 36 ?(
    gfx_rectto(gdx+(gslen/2|0)-1, gdy1+ggbrh);
    gmx= gfx_x; //mid val for bidi
    gfx_x= gdx+(gslen/2|0); gfx_y= gdy1;
    gfx_rectto(gdx+gslen, gdy1+ggbrh);
  ):(
    gfx_rectto(gdx+gslen, gdy1+ggbrh);
    gmx= 0;
  );
  // mouseover?
  gvv= 0; //gvv==unscaled tick: for "1x" text
  mouse_x >= gdx && mouse_x < gdx+gslen && mouse_y >= gdy1 && mouse_y < gdy1+ggbrh ?(
    gval=  min( max( gdrng*(mouse_x-gdx-3)/(gslen-6), 0), gdrng);
    gdrop == trans ? gval|= 0;
    gdclick || release ?(
      gissync ?(
          tick[] < 0 ?(
            gticklen= gdalt ? tickf[] * 100 //hires-absolute relative to cur tick len
                            : syncfracs[-tick[]-1] * 60 / tempo; //else relative to tick time: seconds/synctick
            tickf[]= min((gdbase + gval)*2*gticklen/100,.9999999);
          ): tickf[]= min(gdbase + gval,.9999999);
        slider32= tickf[]; slider_automate(slider32);
      ): while ( gdrop[gdcc]= gval;  
          gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gdcc; deltaseqs[gii]= gdrop; 0; ): (gii+= 1) < deltaslen; );
          mouse_cap & 8 && (gdcc+= 1) < gdmax; ); deltas= 1;
      mouse_cap & 2 ?( norelease= 1; gdclick= 0; ) //rightclick keeps dropdown
                    : gdrop= 0;
    );
  ):(
    gissync ?( 
      tick[] < 0 ?(
        gticklen= gdalt ? tickf[] * 100
                        : syncfracs[-tick[]-1] * 60 / tempo; //seconds/synctick
        gval= tickf[]*100/gticklen;
        gval/= 2;
      ):(
        gval= tickf[];
        !gval ?( gval= gddef; gvv= 1; );
      );
      gval-= gdbase;
    ): gval= gdrop[gdcc];
  );
  // bar
  gfx_r= ggsr; gfx_g= ggsg; gfx_b= ggsb; gfx_a= ggsa;
  gfx_x= gdx; gfx_y= gdy1;
  
  gissync && tick[] >= 0 ?(
    gval1= min(max(gval,0),gdrng)-(gddef-gdbase);
    gval1 < 0 ?(
      gval1/= gddef-gdbase;
      gfx_x= gmx;
      gfx_rectto(gfx_x-((gfx_x-gdx)*(-gval1)+.499|0), gdy1+ggbrh);
    ):(
      gval1/= gdrng-(gddef-gdbase);
      gfx_x= gmx+1;
      gfx_rectto(gfx_x+((gdx+gslen-gfx_x)*(gval1)+.499|0), gdy1+ggbrh);
    );
  ):(
    gfx_rectto(gdx+(gslen*min(max(gval,0),gdrng)/gdrng+.499|0), gdy1+ggbrh);
    gmx ?(
      gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= .33;
      gfx_x= gmx; gfx_y= gdy1;
      gfx_rectto(gmx+1, gdy1+ggbrh);
    );
  );
  
  // text
  gfx_r= gfx_g= gfx_b= 0; gfx_a= ggba;
  gfx_x= gdx+5; gfx_y= gdy1+ggbrh-gfx_texth-3;
  gissync ?(
    gticklen= gdalt && tick[] < 0 ? tickf[] * 100
                                  : syncfracs[tick[]<0?-tick[]-1:tick[]] * 60 / tempo; //seconds/synctick
    gvv ?(
      /*puts('exact');*/                          (gfx_drawchar($'e');gfx_drawchar($'x');gfx_drawchar($'a');gfx_drawchar($'c');gfx_drawchar($'t'););
      gfx_drawchar($' '); gfx_drawchar(40);
      gfx_drawnumber(gticklen+.0005,3);
      gfx_drawchar($'s'); gfx_drawchar(41);
    ):(
      tick[] >= 0 ?(
        gfx_drawchar($'x');
        gfx_drawnumber((gval+gdbase)*2+.0005,3);
        gfx_drawchar($' '); gfx_drawchar(40);
      );
      gfx_drawnumber((gval+gdbase)*2*gticklen+.0005,3);
      gfx_drawchar($'s');
      tick[] >= 0 ? gfx_drawchar(41);
    );
  ): gdrop == gates ? gfx_drawnumber(gval,2) 
  : gfx_drawnumber(gval-tranbase[],0);
);

//- choice grids
gndx == 1 && (gdrop == dirs || (gdrop == syncfracs && !(tick[]<0 && gdalt)) || gdrop == gdchan 
    || gdrop == gdctl1 || gdrop == gdctl2 || gdrop == gdctl3 || gdrop == gdctl4) 
?(

  gissync && tick[] < 0 ? gdy1= gdy + ggbrh + 2 
                        : gdy1= gdy; 

  // frame rect
  gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
  gfx_x= gdx-2; gfx_y= gdy1-2;
  gfx_rectto(gdx+gdtcc*gdtco-(gdtco-gdtcw)+2, gdy1+gdtrc*gdtro-(gdtro-gdtrh)+2);
  // bg rects
  gcc= -1; loop ( gdtcc, gcc+= 1;
    grr= -1; loop ( gdtrc, grr+= 1;
      gfx_r= ggbr; gfx_g= ggbg; gfx_b= ggbb; gfx_a= 1;
      gfx_x= gdx+gcc*gdtco; gfx_y= gdy1+grr*gdtro;
      gfx_rectto(gfx_x+gdtcw, gfx_y+gdtrh);
    );
  );
  // image
  gfx_x= gdx; gfx_y= gdy1; gfx_a= 1;
  gdrop == dirs ?( gfx_a= ggba; gfx_blit(gdrop[gdcc] & dirop ? fndirtypes2 : fndirtypes, 1, 0); )
  : gdrop == syncfracs ? gfx_blit(fnsync0, 1, 0)
  : gdrop == gdchan ? gfx_blit(fnchan0, 1, 0)
  : gdrop == gdctl2 || gdrop == gdctl3 ? gfx_blit(fncc2, 1, 0)
  : gfx_blit(fncc1, 1, 0);
  // mouseover & click?
  mouse_x >= gdx && mouse_x < gdx+gdtcc*gdtco && mouse_y >= gdy1 && mouse_y < gdy1+gdtrc*gdtro ?(
    gfx_r= gfx_g= gfx_b= 0; gfx_a= ggma;
    gcc= (mouse_x-gdx)/gdtco|0; grr= (mouse_y-gdy1)/gdtro|0;
    !(gdrop == gdctl1 || gdrop == gdctl2 || gdrop == gdctl3 || gdrop == gdctl4) || grr < 15 ?(
      gfx_x= gdx+gcc*gdtco; gfx_y= gdy1+grr*gdtro;
      gfx_rectto(gfx_x+gdtcw, gfx_y+gdtrh);
    ):(
      gfx_x= gdx+(gcc/4|0)*gdtco*4; gfx_y= gdy1+grr*gdtro;
      gfx_rectto(gfx_x+gdtco*4-(gdtco-gdtcw), gfx_y+gdtrh-(gdtro-gdtrh));
    );
    gdclick || (release && gdrop != gdctl1 && gdrop != gdctl2 && gdrop != gdctl3 && gdrop != gdctl4) ?(
      gdrop == dirs ?(
        stepsdelta= 1;
//           grr==0 && gcc==1 ? gval= dirlast
//         : grr==0 && gcc==2 ? gval= dirnext2
//         : grr==0 && gcc==3 ? gval= dirnext3
//         : grr==1 && gcc==1 ? gval= dirfirst
//         : grr==2 && gcc==0 ? gval= dirsame
//         : 
        grr==3 && gcc==3 ? gval= dirtwiddle
        : grr==4 ? gval= dirsubtract * 2^gcc
        : gval= grr*gdtcc+gcc;
        gval2= gval == dircontract && mouse_cap & 16 && mouse_cap & 4 ? dirconadd : 0;
        gdcc2= gdcc;
        gval <= dirmask ?( 
          while ( 
            gdrop[gdcc2]= gval + (gdrop[gdcc2] & ($xffffff-dirmask)); 
            gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gdcc2; deltaseqs[gii]= gdrop; 0; ): (gii+= 1) < deltaslen; );
            mouse_cap & 8 && (gdcc2+= 1) < gdmax; 
          ); deltas= 1;
        ): gdrop[gdcc2] & gval ?(
          while ( 
            gdrop[gdcc2]&= $xffffff-gval-(gval==dircontract?dirconadd:0);
            gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gdcc2; deltaseqs[gii]= gdrop; 0; ): (gii+= 1) < deltaslen; );
            mouse_cap & 8 && (gdcc2+= 1) < gdmax; 
          ); deltas= 1;
        ):( 
          while ( 
            gdrop[gdcc2]|= gval+gval2; 
            //gval == dirop ? gdrop[gdcc2]&= $xffffff-dirsubtract-dircontract-dirtwiddle
            //gval == dirtwiddle ? gdrop[gdcc2]&= $xffffff-dirop
            gval == dircontract ? gdrop[gdcc2]&= $xffffff-dirsubtract
            : gval == dirsubtract ? gdrop[gdcc2]&= $xffffff-dircontract;
            gii= 0; while ( !(deltaseqs[gii]) ?( deltasteps[gii]= gdcc2; deltaseqs[gii]= gdrop; 0; ): (gii+= 1) < deltaslen; );
            mouse_cap & 8 && (gdcc2+= 1) < gdmax; 
          ); deltas= 1;
        );
      ): gdrop == syncfracs ?(
        gval= grr*10+gcc;
        gii= 0; while ( syncfracsgrid[gii] == gval ? 0 : (gii+= 1)<24; );
        gii < 24 ?(
          tick[]= tick[] < 0 ? -gii-1 : gii;
          mouse_cap & 2 ?( 
            tick[] < 0 ?(
              tickf[]= min(syncfracs[-tick[]-1] * 60 / tempo / 100,.9999999);
            ): tickf[]= 0;
          );
          slider2= tick[]; slider_automate(slider2);
          slider32= tickf[]; slider_automate(slider32);
        );
      ): gdrop == gdchan ?( 
        chan= grr*4+gcc;
        slider4= chan + chanbus*16; slider_automate(slider4);
      ): gdrop == gdctl1 ?( 
        grr < 15 ? ctl1cc[]= grr*8+gcc : gcc < 4 ? ctl1cc[]= -1 : ctl1cc[]= -2;
      ): gdrop == gdctl2 ?( 
        grr < 15 ? ctl2cc[]= grr*8+gcc : gcc < 4 ? ctl2cc[]= -1 : ctl2cc[]= -2; 
      ): gdrop == gdctl3 ?( 
        grr < 15 ? ctl3cc[]= grr*8+gcc : gcc < 4 ? ctl3cc[]= -1 : ctl3cc[]= -2; 
      ):(
        grr < 15 ? ctl4cc[]= grr*8+gcc : gcc < 4 ? ctl4cc[]= -1 : ctl4cc[]= -2; 
      );
      mouse_cap & 2 || (gdrop == syncfracs && tick[] < 0) ?( norelease= 1; gdclick= 0; ) //rightclick keeps dropdown
                                                          : gdrop= 0;
    );
  );
  // hilite current
  gdrop == syncfracs ?(
    gii= syncfracsgrid[tick[]<0?-tick[]-1:tick[]];
    gcc= gii%10|0; grr= gii/10|0;
    gfx_r= gfx_g= gfx_b= 0; gfx_a= ggma;
    !(gdrop == gdctl1 || gdrop == gdctl2 || gdrop == gdctl3 || gdrop == gdctl4) || grr < 15 ?(
      gfx_x= gdx+gcc*gdtco; gfx_y= gdy1+grr*gdtro;
      gfx_rectto(gfx_x+gdtcw, gfx_y+gdtrh);
    ):(
      gfx_x= gdx+(gcc/4|0)*gdtco*4; gfx_y= gdy1+grr*gdtro;
      gfx_rectto(gfx_x+gdtco*4-(gdtco-gdtcw), gfx_y+gdtrh-(gdtro-gdtrh));
    );
  );
);

); //...loop ( 2,

// click outside dropdown?
gdclick ? gdrop= 0;

/////- dbg

dbgvis ?(
  dbgro= gfx_texth+4;
  gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
  gfx_x= ggx; gfx_y= ggy;
  /*puts('dbg: ');*/                              (gfx_drawchar($'d');gfx_drawchar($'b');gfx_drawchar($'g');gfx_drawchar($':');gfx_drawchar($' '););
  gdp= dbgt; while (
    gdp[] == -1 ?(
      gfx_drawnumber( (gdp+=1)[], (gdp+=1)[] ); gfx_drawchar($' '); 
    ):(
      loop ( gdp[], 
        gdp[1] == ($'`') ?( gfx_x= ggx; gfx_y+= dbgro; gdp+= 1; )
        : gfx_drawchar( (gdp+=1)[] ) );
    );
    gfx_x > gfx_w-100 ?( gfx_x= ggx; gfx_y+= dbgro; );
    (gdp+= 1) < dbgp;
  );
  ggx = ggl;
  ggy= gfx_y+dbgro;
);

//BLOCK Debug ///////////////////////////////////////////////////////////////////////////////////////////////

/*******************************************************************************
    General purpose debugging aid. Paste into the gfx section of your code.

    Variables:
    debug1...debug6      - Displayed at the top of the debug area.
    dOffset              - Index of first item of buffer data to display.

*******************************************************************************/
//SHOWDEBUG= 0; //Set non-zero to enable the debug view
//dOffset= deltaseqs;
//debug1= beat_position; //tickpos; //notecnt;
//debug2= sortxcnt;
//debug3= !newsortx ? playpos : !playpos ? -.0001 : -playpos;
//debug4= swingcnt;
//debug5= dirpos[];
debug6= (dvo-1)/(maxmaxsteps+2);

aaticklen= ticklen;
aaswingcnt= swingcnt;
aaorderrev= orderrev;

  ggy+= 12;
  gfx_r= ggcr; gfx_g= ggcg; gfx_b= ggcb; gfx_a= 1;
  gfx_x= 0; gfx_y= ggy;
  gfx_rectto(gfx_w, gfx_y+gfx_texth);
  gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb; gfx_a= 1;
  gfx_x= ggl; gfx_y= ggy;
  /*puts('prever: ');*/                           (gfx_drawchar($'p');gfx_drawchar($'r');gfx_drawchar($'e');gfx_drawchar($'v');gfx_drawchar($'e');gfx_drawchar($'r');gfx_drawchar($':');gfx_drawchar($' '););
  gxx= gfx_x; gfx_drawnumber(aareadprever%10000,0); gfx_x= gxx+4*gfx_charw;

SHOWDEBUG ?
(
  /*puts('notes: ');*/                            (gfx_drawchar($'n');gfx_drawchar($'o');gfx_drawchar($'t');gfx_drawchar($'e');gfx_drawchar($'s');gfx_drawchar($':');gfx_drawchar($' '););
  gxx= gfx_x; gfx_drawnumber(sortx[]?sortxcnt:notecnt,0); gfx_x= gxx+4*gfx_charw;
  /*puts('playpos: ');*/                          (gfx_drawchar($'p');gfx_drawchar($'l');gfx_drawchar($'a');gfx_drawchar($'y');gfx_drawchar($'p');gfx_drawchar($'o');gfx_drawchar($'s');gfx_drawchar($':');gfx_drawchar($' '););
  gxx= gfx_x; gfx_drawnumber(!newsortx ? playpos : !playpos ? -.0001 : -playpos,0); gfx_x= gxx+4*gfx_charw;
  /*puts('dirpos: ');*/                           (gfx_drawchar($'d');gfx_drawchar($'i');gfx_drawchar($'r');gfx_drawchar($'p');gfx_drawchar($'o');gfx_drawchar($'s');gfx_drawchar($':');gfx_drawchar($' '););
  gxx= gfx_x; gfx_drawnumber(dirpos[],0); gfx_x= gxx+4*gfx_charw;
  /*puts('beatpos: ');*/                          (gfx_drawchar($'b');gfx_drawchar($'e');gfx_drawchar($'a');gfx_drawchar($'t');gfx_drawchar($'p');gfx_drawchar($'o');gfx_drawchar($'s');gfx_drawchar($':');gfx_drawchar($' '););
  gxx= gfx_x; gfx_drawnumber(beat_position,2); gfx_x= gxx+9*gfx_charw;
  ///*puts('tickpos: ');*/                        (gfx_drawchar($'t');gfx_drawchar($'i');gfx_drawchar($'c');gfx_drawchar($'k');gfx_drawchar($'p');gfx_drawchar($'o');gfx_drawchar($'s');gfx_drawchar($':');gfx_drawchar($' '););
  //gxx= gfx_x; gfx_drawnumber(tickpos,2); gfx_x= gxx+10*gfx_charw;
  ggy= gfx_y+dbgro;
 
    //Options
    dPrecision= 2;             //Decimal places for numbers
    dLeft= 5;                  //Debug window position in pixels
    dTop= ggy+15; //350;                   //Debug window position in pixels
    dRows= 10;                  //Row count for buffer data
    dCols= 10;                  //Column count for buffer data

    dRowHeight= 20;            //Row height offset for buffer data
    dVarWidth= 85;             //Column width offset for buffer data
    dColWidth= 55;             //Column width offset for buffer data
    dMarginX= 5;               //Left margin in pixels
    dMarginY= 5;               //Top margin in pixels
    dBufferY= 25;              //Vertical offset for buffer data display
    
    /* ------------------------------------------------------------- */

    dOld_x= gfx_x;
    dOld_y= gfx_y;
    dOld_a= gfx_a;
    dOld_r= gfx_r;
    dOld_g= gfx_g;
    dOld_b= gfx_b;
    dOld_mode= gfx_mode;

    gfx_a= 1;
    gfx_mode= 0;

    //Calculate debug window size
    dWidth= dCols * dColWidth + dMarginX;
    dHeight= dRows * dRowHeight + dBufferY;

    //Set background colour
    //gfx_r= 1;gfx_g= 1;gfx_b= 1;gfx_a= 1;
    gfx_r= ggcr; gfx_g= ggcg; gfx_b= ggcb; gfx_a= 1;

    //Erase
    gfx_x= dLeft;
    gfx_y= dTop;
    gfx_rectto(dLeft + dWidth, dTop + dHeight);

    //Set text colour
    //gfx_r= .7;gfx_g= 0;gfx_b= .3;
    gfx_r= ggfr; gfx_g= ggfg; gfx_b= ggfb;

    //Draw debug vars
    gfx_x= dLeft + dMarginX; gfx_y= dTop + dMarginY;
    gfx_drawNumber(debug1, dPrecision);

    gfx_x= dLeft + dMarginX + dVarWidth; gfx_y= dTop + dMarginY;
    gfx_drawNumber(debug2, dPrecision);

    gfx_x= dLeft + dMarginX + dVarWidth * 2; gfx_y= dTop + dMarginY;
    gfx_drawNumber(debug3, dPrecision);

    gfx_x= dLeft + dMarginX + dVarWidth * 3; gfx_y= dTop + dMarginY;
    gfx_drawNumber(debug4, dPrecision);

    gfx_x= dLeft + dMarginX + dVarWidth * 4; gfx_y= dTop + dMarginY;
    gfx_drawNumber(debug5, dPrecision);

    gfx_x= dLeft + dMarginX + dVarWidth * 5; gfx_y= dTop + dMarginY;
    gfx_drawNumber(debug6, dPrecision);

    //Draw separator
    gfx_x= dLeft + dMarginX;
    gfx_y= dTop + dBufferY - dMarginY;
    gfx_lineto(dLeft + dWidth - dMarginX, gfx_y, 1);

    //Draw buffer data
    di= 0;
    dRow= 0;
    dOffsetX = dOffset;
    loop
    (
        dRows,
        dCol= 0;
        loop
        (
            dCols,
            gfx_x= dLeft + dMarginX + dCol * dColWidth;
            gfx_y= dTop + dMarginY + dBufferY + dRow * dRowHeight;
            dOffsetX == evmsg23s ?(
              gfx_drawNumber(dOffsetX[di]&$xff, 0);
            ): dOffsetX == evmsgs ?(
                dOffsetX[di] == -notes ?(
                  gfx_drawChar($'#');
                ): dOffsetX[di] < 0 ?(
                  gfx_drawChar($'@');
                  gfx_drawNumber(-dOffsetX[di], 0);
                ): dOffsetX[di] ?(
                  dNum = (dOffsetX[di]&$xf0)/$x10;
                  dNum < 10 ? gfx_drawChar($'0'+dNum) : gfx_drawChar($'a'+dNum-10);
                  gfx_drawChar($':');
                  gfx_drawNumber(dOffsetX[di]&$xf, 0);
                );
                di == dCols*dRows/2-1 ?( dOffsetX= evmsg23s; di= -1; );
                
            ): dOffsetX == slvars ?(
              gfx_drawNumber(dOffsetX[di], dPrecision);
              di == dCols*4-1 ?( dOffsetX= prevars; di= -1; );
              
//            ): dOffsetX == sortxmap ?(
//              gfx_drawNumber(dOffsetX[di], dPrecision);
//              di == dCols*dRows/2-1 ?( dOffsetX= sortxpat; di= -1; );
              
            ): dOffsetX == vntmap ?(
              gfx_drawNumber((dOffsetX[di]-variants)/vntlen, 0);
              di == dCols-1 ?( dOffsetX= vntmap[0]; di= -1; );
            ): dOffsetX == vntmap[0] ?(
              gfx_drawNumber(dOffsetX[di+vntserial+(di?dvo-1:0)], dPrecision);
              di == dCols-1 ?( dOffsetX= vntmap[1]; di= -1; );
            ): dOffsetX == vntmap[1] ?(
              gfx_drawNumber(dOffsetX[di+vntserial+(di?dvo-1:0)], dPrecision);
              di == dCols-1 ?( dOffsetX= vntmap[2]; di= -1; );
            ): dOffsetX == vntmap[2] ?(
              gfx_drawNumber(dOffsetX[di+vntserial+(di?dvo-1:0)], dPrecision);
              di == dCols-1 ?( dOffsetX= vntmap[3]; di= -1; );
            ): dOffsetX == vntmap[3] ?(
              gfx_drawNumber(dOffsetX[di+vntserial+(di?dvo-1:0)], dPrecision);
              di == dCols-1 ?( dOffsetX= vntmap[4]; di= -1; );
            ): dOffsetX == vntmap[4] ?(
              gfx_drawNumber(dOffsetX[di+vntserial+(di?dvo-1:0)], dPrecision);
              //di == dCols-1 ?( dOffsetX= vntmap[5]; di= -1; );
              
            ): gfx_drawNumber(dOffsetX[di], dPrecision);
            di+= 1;
            
            dCol+= 1;
        );
        dRow+= 1;
    );

    //Restore previous state
    gfx_x= dOld_x;
    gfx_y= dOld_y;
    gfx_a= dOld_a;
    gfx_r= dOld_r;
    gfx_g= dOld_g;
    gfx_b= dOld_b;
    gfx_mode= dOld_mode;
);

//END Debug
