diff --git a/build/nsis/Mixxx.nsi b/build/nsis/Mixxx.nsi index 98eece8ef378..a7ab6f2792e3 100644 --- a/build/nsis/Mixxx.nsi +++ b/build/nsis/Mixxx.nsi @@ -450,9 +450,11 @@ Section "Uninstall" Delete "$INSTDIR\controllers\Korg nanoPAD2.midi.xml" Delete "$INSTDIR\controllers\Korg-nanoKONTROL-2-scripts.js" Delete "$INSTDIR\controllers\Korg-nanoPAD2-scripts.js" - Delete "$INSTDIR\controllers\M-Audio-Xponent-scripts.js" - Delete "$INSTDIR\controllers\M-Audio_Xponent.midi.xml" + Delete "$INSTDIR\controllers\korg_nanokontrol2.mixco.output.js" + Delete "$INSTDIR\controllers\korg_nanokontrol2.mixco.output.midi.xml" Delete "$INSTDIR\controllers\M-Audio_Xsession_pro.midi.xml" + Delete "$INSTDIR\controllers\maudio_xponent.mixco.output.js" + Delete "$INSTDIR\controllers\maudio_xponent.mixco.output.midi.xml" Delete "$INSTDIR\controllers\Midi-Keyboard.midi.xml" Delete "$INSTDIR\controllers\Midi_for_light.midi.xml" Delete "$INSTDIR\controllers\Midi_for_light-scripts.js" @@ -473,6 +475,8 @@ Section "Uninstall" Delete "$INSTDIR\controllers\Novation-Launchpad-Mini-scripts.js" Delete "$INSTDIR\controllers\Novation-Launchpad-Mini.midi.xml" Delete "$INSTDIR\controllers\Novation-Launchpad-scripts.js" + Delete "$INSTDIR\controllers\novation_twitch.mixco.output.js" + Delete "$INSTDIR\controllers\novation_twitch.mixco.output.midi.xml" Delete "$INSTDIR\controllers\Numark DJ2Go.midi.xml" Delete "$INSTDIR\controllers\Numark Mixtrack Pro.midi.xml" Delete "$INSTDIR\controllers\Numark MIXTRACK.midi.xml" diff --git a/res/controllers/M-Audio-Xponent-scripts.js b/res/controllers/M-Audio-Xponent-scripts.js deleted file mode 100644 index 47236f28ff91..000000000000 --- a/res/controllers/M-Audio-Xponent-scripts.js +++ /dev/null @@ -1,519 +0,0 @@ -function MaudioXponent () {} - -// ---------- Global variables ---------- - -MaudioXponent.id = ""; // The ID for the particular device being controlled for use in debugging, set at init time -MaudioXponent.off = 0x80; -MaudioXponent.on = 0x90; -MaudioXponent.mastermeter = 0; //1 for master meter, 0 for channel meter -MaudioXponent.flashprogress = 8; //flash duration on progress meters -MaudioXponent.leds = { - "play": 0x24, - "cue": 0x23, - "back": 0x21, - "fwd": 0x22, - "in": 0x29, - "out": 0x2B, - "loop": 0x2A, - "loop1": 0x25, - "loop2": 0x26, - "loop4": 0x27, - "loop8": 0x28, - "leftkey": 0x1C, - "rightkey": 0x1D, - "key": 0x1E, - "pluskey": 0x1F, - "minkey": 0x20, - "cue1": 0x17, - "cue2": 0x18, - "cue3": 0x19, - "cue4": 0x1A, - "cue5": 0x1B, - "fx1": 0x0C, - "fx2": 0x0D, - "fx3": 0x0E, - "fx4": 0x0F, - "leftp": 0x10, - "rightp": 0x11, - "bigx": 0x12, - "big-": 0x13, - "head": 0x14, - "scratch": 0x15, - "fadarbutton": 0x07, - "sync": 0x02, - "low": 0x08, - "middle": 0x09, - "hight": 0x0A, - "gain": 0x0B, - "shift": 0x2C -}; -MaudioXponent.binleds = { - 8: "filterLowKill", - 9: "filterMidKill", - 10: "filterHighKill", - 18: "keylock", - 19: "reverse", - 20: "pfl", - 33: "back", - 34: "fwd", - 36: "play" -}; -MaudioXponent.hotcues = { - 23: 1, - 24: 2, - 25: 3, - 26: 4, - 27: 5 -}; -MaudioXponent.timer = [-1, -1]; // Temporary storage of timer IDs -MaudioXponent.state = { - "flashes" : 0, - "faderpos" : 0, - "shift1" : 0, - "shift2" : 0, - "scrmode1" : 0, - "scrmode2" : 0, - "plnumberpos" : 0, - "plnumberneg" : 0, - "scratching1" : 0, - "scratching2" : 0, -}; // Temporary state variables - -// ---------- Functions ---------- - -MaudioXponent.init = function (id) { // called when the MIDI device is opened & set up - - //This code light on all leds and then light off - midi.sendShortMsg(0xB3,0x14,0x00); - midi.sendShortMsg(0xB3,0x15,0x00); - for (var led in MaudioXponent.leds) { - midi.sendShortMsg(MaudioXponent.on,MaudioXponent.leds[led],0x01); - midi.sendShortMsg(MaudioXponent.on + 1,MaudioXponent.leds[led],0x01); - MaudioXponent.pauseScript(15); - } - midi.sendShortMsg(0xB3,0x12,0x7F); - midi.sendShortMsg(0xB3,0x13,0x7F); - midi.sendShortMsg(0xB3,0x14,0x7F); - midi.sendShortMsg(0xB3,0x15,0x7F); - MaudioXponent.pauseScript(500); - for (var led in MaudioXponent.leds) { - midi.sendShortMsg(MaudioXponent.on,MaudioXponent.leds[led],0x00); - midi.sendShortMsg(MaudioXponent.on + 1,MaudioXponent.leds[led],0x00); - MaudioXponent.pauseScript(15); - } - midi.sendShortMsg(0xB3,0x14,0x00); - midi.sendShortMsg(0xB3,0x15,0x00); - //end of light on all leds - - MaudioXponent.flashdur1 = 0; - MaudioXponent.flashdur2 = 0; - engine.connectControl("[Channel1]","visual_playposition","MaudioXponent.playPositionMeter1"); - engine.connectControl("[Channel2]","visual_playposition","MaudioXponent.playPositionMeter2"); - if (MaudioXponent.mastermeter == 1) { - engine.connectControl("[Master]","VuMeterL","MaudioXponent.volumeLEDs1"); - engine.connectControl("[Master]","VuMeterR","MaudioXponent.volumeLEDs2"); - } else { - engine.connectControl("[Channel1]","VuMeter","MaudioXponent.volumeLEDs1"); - engine.connectControl("[Channel2]","VuMeter","MaudioXponent.volumeLEDs2"); - } - - engine.connectControl("[Channel1]","hotcue_1_enabled","MaudioXponent.hotcue"); - engine.connectControl("[Channel1]","hotcue_2_enabled","MaudioXponent.hotcue"); - engine.connectControl("[Channel1]","hotcue_3_enabled","MaudioXponent.hotcue"); - engine.connectControl("[Channel1]","hotcue_4_enabled","MaudioXponent.hotcue"); - engine.connectControl("[Channel1]","hotcue_5_enabled","MaudioXponent.hotcue"); - engine.connectControl("[Channel2]","hotcue_1_enabled","MaudioXponent.hotcue"); - engine.connectControl("[Channel2]","hotcue_2_enabled","MaudioXponent.hotcue"); - engine.connectControl("[Channel2]","hotcue_3_enabled","MaudioXponent.hotcue"); - engine.connectControl("[Channel2]","hotcue_4_enabled","MaudioXponent.hotcue"); - engine.connectControl("[Channel2]","hotcue_5_enabled","MaudioXponent.hotcue"); - - engine.connectControl("[Channel1]", "loop_enabled", "MaudioXponent.onLoopExit"); - engine.connectControl("[Channel1]", "loop_start_position", "MaudioXponent.onLoopIn"); - engine.connectControl("[Channel1]", "loop_end_position", "MaudioXponent.onLoopOut"); - engine.connectControl("[Channel2]", "loop_enabled", "MaudioXponent.onLoopExit"); - engine.connectControl("[Channel2]", "loop_start_position", "MaudioXponent.onLoopIn"); - engine.connectControl("[Channel2]", "loop_end_position", "MaudioXponent.onLoopOut"); - - //engine.connectControl("[Channel1]","bpm","MaudioXponent.bpmsync"); - -}; - -MaudioXponent.wheel = function (channel, control, value, status) { - var currentdeck = channel+1; - - // In either case, register the movement - - if (MaudioXponent.state["shift"+currentdeck] == 1) { - if (value > 64) { - MaudioXponent.state["plnumberpos"]++; - if (MaudioXponent.state["plnumberpos"] % 12 == 0) { - engine.setValue("[Playlist]","SelectTrackKnob",1); - } - } else if (value < 64) { - MaudioXponent.state["plnumberneg"]++; - if (MaudioXponent.state["plnumberneg"] % 12 == 0) { - engine.setValue("[Playlist]","SelectTrackKnob",-1); - } - } - }else{ - if (MaudioXponent.state["scratching"+currentdeck] == 1) { //scratch mode on - engine.scratchTick(currentdeck, value-64); - } else { //normal wheel mode - engine.setValue("[Channel"+currentdeck+"]", "jog", (value-64)/8); - } - } -}; - -MaudioXponent.wheelbuton = function(channel, control, value, status) { - var currentdeck = channel+1; - if (MaudioXponent.state["scrmode"+currentdeck] == 1) { //scratch mode on - engine.scratchEnable(currentdeck, 3*128, 33+1/3, 1.0/8, (1.0/8)/32); - MaudioXponent.state["scratching"+currentdeck] = true; - } -}; - -MaudioXponent.wheelbutoff = function(channel, control, value, status) { - var currentdeck = channel+1; - engine.scratchDisable (currentdeck); - MaudioXponent.state["scratching"+currentdeck] = false; -}; - -MaudioXponent.pauseScript = function(ms) { - startDate = new Date(); - currentDate = null; - while(currentDate-startDate < ms) currentDate = new Date(); -}; - -MaudioXponent.playPositionMeter1 = function(value) { - if (value >= 0.75) { - MaudioXponent.flashdur1++;; - if (MaudioXponent.flashdur1 == MaudioXponent.flashprogress) { - midi.sendShortMsg(0xB3,0x14,0x00); - } - if (MaudioXponent.flashdur1 >= MaudioXponent.flashprogress*2) { - midi.sendShortMsg(0xB3,0x14,MaudioXponent.convert(value)); - MaudioXponent.flashdur1 = 0; - } - }else{ - midi.sendShortMsg(0xB3,0x14,MaudioXponent.convert(value)); - } -}; - -MaudioXponent.playPositionMeter2 = function(value) { - if (value >= 0.75) { - MaudioXponent.flashdur2++;; - if (MaudioXponent.flashdur2 == MaudioXponent.flashprogress) { - midi.sendShortMsg(0xB3,0x15,0x00); - } - if (MaudioXponent.flashdur2 >= MaudioXponent.flashprogress*2) { - midi.sendShortMsg(0xB3,0x15,MaudioXponent.convert(value)); - MaudioXponent.flashdur2 = 0; - } - }else{ - midi.sendShortMsg(0xB3,0x15,MaudioXponent.convert(value)); - } -}; - -MaudioXponent.volumeLEDs1 = function(value) { - midi.sendShortMsg(0xB3,0x12,MaudioXponent.convert(value)); -}; - -MaudioXponent.volumeLEDs2 = function(value) { - midi.sendShortMsg(0xB3,0x13,MaudioXponent.convert(value)); -}; - -MaudioXponent.convert = function(value) { - value = value*127; - value = value.toFixed(0); - value = value.toString(16); - return (value); -}; - -MaudioXponent.actbin = function(channel, control, value, status) { // Generic binary button - script.debug(channel, control, value, status); - var currentdeck = channel+1; - var activenow = engine.getValue("[Channel"+currentdeck+"]", MaudioXponent.binleds[control]); - if (activenow) { // If currently active - engine.setValue("[Channel"+currentdeck+"]",MaudioXponent.binleds[control], 0); // Stop - midi.sendShortMsg(MaudioXponent.off + channel,control, 0x00); // Turn off the LED - }else { // If not currently active - engine.setValue("[Channel"+currentdeck+"]",MaudioXponent.binleds[control], 1); // Start - midi.sendShortMsg(MaudioXponent.on + channel,control, 0x01); // Turn on the LED - } -}; - -MaudioXponent.actbinstop = function(channel, control, value, status) { // Generic binary button - script.debug(channel, control, value, status); - var currentdeck = channel+1; - engine.setValue("[Channel"+currentdeck+"]",MaudioXponent.binleds[control],0); // Stop - midi.sendShortMsg(MaudioXponent.off + channel,control,0x00); // Turn off the LED -}; - -MaudioXponent.hotcue = function(channel, control, value, status) { // Generic binary button - var channelnow = 0; - if (control == "[Channel2]") { - channelnow = 1; - } - switch (value) { - case "hotcue_1_enabled": - if (channel == 1){ - midi.sendShortMsg(MaudioXponent.on + channelnow,0x17,0x01); // Turn on the LED - }else{ - midi.sendShortMsg(MaudioXponent.on + channelnow,0x17,0x00); // Turn off the LED - } - break; - case "hotcue_2_enabled": - if (channel == 1){ - midi.sendShortMsg(MaudioXponent.on + channelnow,0x18,0x01); // Turn on the LED - }else{ - midi.sendShortMsg(MaudioXponent.on + channelnow,0x18,0x00); // Turn off the LED - } - break; - case "hotcue_3_enabled": - if (channel == 1){ - midi.sendShortMsg(MaudioXponent.on + channelnow,0x19,0x01); // Turn on the LED - }else{ - midi.sendShortMsg(MaudioXponent.on + channelnow,0x19,0x00); // Turn off the LED - } - break; - case "hotcue_4_enabled": - if (channel == 1){ - midi.sendShortMsg(MaudioXponent.on + channelnow,0x1A,0x01); // Turn on the LED - }else{ - midi.sendShortMsg(MaudioXponent.on + channelnow,0x1A,0x00); // Turn off the LED - } - break; - case "hotcue_5_enabled": - if (channel == 1){ - midi.sendShortMsg(MaudioXponent.on + channelnow,0x1B,0x01); // Turn on the LED - }else{ - midi.sendShortMsg(MaudioXponent.on + channelnow,0x1B,0x00); // Turn off the LED - } - break; - } -}; - -MaudioXponent.hotcueset = function(channel, control, value, status) { - //MaudioXponent.debug(channel, control, value, status) - var currentdeck = channel+1; - if (MaudioXponent.state["shift"+currentdeck] == 1) { - engine.setValue("[Channel"+currentdeck+"]","hotcue_"+MaudioXponent.hotcues[control]+"_clear",1); - }else{ - engine.setValue("[Channel"+currentdeck+"]","hotcue_"+MaudioXponent.hotcues[control]+"_activate",1); - } -}; - -MaudioXponent.onLoopIn = function(channel, control, value, status) -{ - channelnow = control == "[Channel2]" ? 1 : 0; - midi.sendShortMsg(MaudioXponent.on + channelnow, 0x29, - engine.getValue (control, value) != -1); - /* TODO. - if (-1 == engine.getValue(control, "loop_end_position")) - { - MaudioXponent.state["flashes"] = 0; // initialize number of flashes - MaudioXponent.timer[channelnow] = engine.beginTimer( - 250, "MaudioXponent.flashled("+ channelnow +",\"0x2B\")"); - } - */ -} - -MaudioXponent.onLoopOut = function(channel, control, value, status) -{ - channelnow = control == "[Channel2]" ? 1 : 0; - /* - if (MaudioXponent.timer[channelnow] != -1) { - engine.stopTimer (MaudioXponent.timer[channelnow]); - MaudioXponent.timer[channelnow] = -1; - } - */ - midi.sendShortMsg(MaudioXponent.on + channelnow, 0x2B, - engine.getValue (control, value) != -1); -} - -MaudioXponent.onLoopExit = function(channel, control, value, status) -{ - channelnow = control == "[Channel2]" ? 1 : 0; - midi.sendShortMsg(MaudioXponent.on + channelnow, 0x2A, - engine.getValue (control, value) == 1); -} - -MaudioXponent.loopin = function(channel, control, value, status) { - //MaudioXponent.debug(channel, control, value, status) - var currentdeck = channel+1; - engine.setValue("[Channel"+currentdeck+"]","loop_in", 1); -}; - -MaudioXponent.loopout = function(channel, control, value, status) { - //MaudioXponent.debug(channel, control, value, status) - var currentdeck = channel+1; - engine.setValue("[Channel"+currentdeck+"]", "loop_out", 1); -}; - -MaudioXponent.loopexit = function(channel, control, value, status) { - var currentdeck = channel+1; - var activenow = engine.getValue("[Channel"+currentdeck+"]", "reloop_exit"); - engine.setValue("[Channel"+currentdeck+"]", "reloop_exit", 1); -}; - -MaudioXponent.flashled = function (channel, control) { - MaudioXponent.state["flashes"]++; - if (MaudioXponent.state["flashes"] % 2 == 0) { - midi.sendShortMsg(MaudioXponent.on + channel,control,0x01); // Turn on the LED - }else { - midi.sendShortMsg(MaudioXponent.on + channel,control,0x00); // Turn off the LED - } -}; - -MaudioXponent.faderbuttonon = function(channel, control, value, status) { - //script.debug(channel, control, value, status); - MaudioXponent.state["faderpos"] = engine.getValue("[Master]","crossfader"); - if (MaudioXponent.state["faderpos"] <= -0.90 && channel == 1) { - midi.sendShortMsg(MaudioXponent.on + channel,control,0x01); // Turn on the LED - engine.setValue("[Master]","crossfader",0); - }else if (MaudioXponent.state["faderpos"] >= 0.90 && channel == 0) { - midi.sendShortMsg(MaudioXponent.on + channel,control,0x01); // Turn on the LED - engine.setValue("[Master]","crossfader",0); - } -}; - -MaudioXponent.faderbuttonoff = function(channel, control, value, status) { - //script.debug(channel, control, value, status); - if (MaudioXponent.state["faderpos"] <= -0.90 && channel == 1) { - midi.sendShortMsg(MaudioXponent.on + channel,control,0x00); // Turn off the LED - engine.setValue("[Master]","crossfader",MaudioXponent.state["faderpos"]); - }else if (MaudioXponent.state["faderpos"] >= 0.90 && channel == 0) { - midi.sendShortMsg(MaudioXponent.on + channel,control,0x00); // Turn off the LED - engine.setValue("[Master]","crossfader",MaudioXponent.state["faderpos"]); - } -}; - -MaudioXponent.bpmsync = function(channel, control, value) { - print (channel); - print (control); -}; - -MaudioXponent.pitch = function(channel, control, value, status) { - var currentdeck = channel+1; - engine.setValue("[Channel"+currentdeck+"]","rate",script.pitch(control, value, status)); -}; - -MaudioXponent.secondaryon = function(channel, control, value, status) { - var currentdeck = channel+1; - midi.sendShortMsg(MaudioXponent.on + channel,control,0x01); // Turn on the LED - MaudioXponent.state["shift"+currentdeck] = 1; -}; - -MaudioXponent.secondaryoff = function(channel, control, value, status) { - var currentdeck = channel+1; - midi.sendShortMsg(MaudioXponent.on + channel,control,0x00); // Turn on the LED - MaudioXponent.state["shift"+currentdeck] = 0; -}; - -MaudioXponent.flanger = function(channel, control, value, status) { - //script.debug(channel, control, value, status); - if (control == 12) { - var activenow = engine.getValue("[Channel1]","flanger"); - if (activenow == 1) { // If currently active - midi.sendShortMsg(MaudioXponent.on+1,control,0x00); // Turn off the LED - engine.setValue("[Channel1]","flanger",0); - }else{ - midi.sendShortMsg(MaudioXponent.on+1,control,0x01); // Turn on the LED - engine.setValue("[Channel1]","flanger",1); - } - }else if (control == 13) { - var activenow = engine.getValue("[Channel2]","flanger"); - if (activenow == 1) { // If currently active - midi.sendShortMsg(MaudioXponent.on+1,control,0x00); // Turn off the LED - engine.setValue("[Channel2]","flanger",0); - }else{ - midi.sendShortMsg(MaudioXponent.on+1,control,0x01); // Turn on the LED - engine.setValue("[Channel2]","flanger",1); - } - } -}; - -MaudioXponent.scrmode = function(channel, control, value, status) { - var currentdeck = channel+1; - if (MaudioXponent.state["scrmode"+currentdeck] == 1) { - midi.sendShortMsg(MaudioXponent.on + channel,control,0x00); // Turn off the LED - MaudioXponent.state["scrmode"+currentdeck] = 0; - }else{ - midi.sendShortMsg(MaudioXponent.on + channel,control,0x01); // Turn on the LED - MaudioXponent.state["scrmode"+currentdeck] = 1; - } -}; - -MaudioXponent.playlist = function(channel, control, value, status) { - var currentdeck = channel+1; - switch (control) { - case 28: - midi.sendShortMsg(MaudioXponent.on + channel,control,0x01); // Turn on the LED - engine.setValue("[Playlist]","SelectPrevTrack",1); - break; - case 29: - midi.sendShortMsg(MaudioXponent.on + channel,control,0x01); // Turn on the LED - engine.setValue("[Playlist]","SelectNextTrack",1); - break; - case 30: - midi.sendShortMsg(MaudioXponent.on + channel,control,0x01); // Turn on the LED - var activenow = engine.getValue("[Channel"+currentdeck+"]","play"); - if (activenow == 1) { // If currently active - engine.setValue("[Playlist]","LoadSelectedIntoFirstStopped",1); - }else{ - engine.setValue("[Channel"+currentdeck+"]","LoadSelectedTrack",1); - } - break; - case 31: - midi.sendShortMsg(MaudioXponent.on + channel,control,0x01); // Turn on the LED - engine.setValue("[Playlist]","SelectPrevPlaylist",1); - break; - case 32: - midi.sendShortMsg(MaudioXponent.on + channel,control,0x01); // Turn on the LED - engine.setValue("[Playlist]","SelectNextPlaylist",1); - break; - } -}; - -MaudioXponent.playlistoff = function(channel, control, value, status) { - midi.sendShortMsg(MaudioXponent.off + channel,control,0x00); // Turn off the LED -}; - -MaudioXponent.cuedefon = function(channel, control, value, status) { - var currentdeck = channel+1; - engine.setValue("[Channel"+currentdeck+"]","cue_default",1); - midi.sendShortMsg(MaudioXponent.on + channel,control,0x01); // Turn on the LED -}; - -MaudioXponent.cuedefoff = function(channel, control, value, status) { - var currentdeck = channel+1; - engine.setValue("[Channel"+currentdeck+"]","cue_default",0); - midi.sendShortMsg(MaudioXponent.off + channel,control,0x00); // Turn off the LED -}; - -MaudioXponent.volbuttonon = function(channel, control, value, status) { - //script.debug(channel, control, value, status); - var currentdeck = channel+1; - engine.setValue("[Channel"+currentdeck+"]","volume",0); - midi.sendShortMsg(MaudioXponent.on + channel,control,0x01); // Turn on the LED -}; - -MaudioXponent.volbuttonoff = function(channel, control, value, status) { - //script.debug(channel, control, value, status); - var currentdeck = channel+1; - engine.setValue("[Channel"+currentdeck+"]","volume",1); - midi.sendShortMsg(MaudioXponent.off + channel,control,0x00); // Turn off the LED -}; - -MaudioXponent.shutdown = function (id) { // called when the MIDI device is closed - - for (var led in MaudioXponent.leds) { - midi.sendShortMsg(MaudioXponent.on,MaudioXponent.leds[led],0x00); // Turn off deck 1 lights - midi.sendShortMsg(MaudioXponent.on + 1,MaudioXponent.leds[led],0x00); // Turn off deck 2 lights - } - midi.sendShortMsg(0xB3,0x14,0x00); - midi.sendShortMsg(0xB3,0x15,0x00); - -}; - diff --git a/res/controllers/M-Audio_Xponent.midi.xml b/res/controllers/M-Audio_Xponent.midi.xml deleted file mode 100644 index 9c7d4f5f2d67..000000000000 --- a/res/controllers/M-Audio_Xponent.midi.xml +++ /dev/null @@ -1,1045 +0,0 @@ - - - - M-Audio Xponent - Luca Franceschini, Juan Pedro Bolívar Puente - Make sure to set the bank switch on the bottom of the Xponent to A. - - - - - - - - - - [Master] - crossfader - 0xB2 - 7 - fader - - - [Master] - headMix - 0xB2 - 13 - fader - - - [Channel1] - MaudioXponent.faderbuttonon - 0x90 - 7 - - - - - - [Channel1] - MaudioXponent.faderbuttonoff - 0x80 - 7 - - - - - - [Channel1] - MaudioXponent.actbin - 0x90 - 36 - - - - - - [Channel1] - play - 0x80 - 36 - button - - - [Channel1] - MaudioXponent.cuedefon - 0x90 - 35 - - - - - - [Channel1] - MaudioXponent.cuedefoff - 0x80 - 35 - - - - - - [Channel1] - MaudioXponent.actbin - 0x90 - 33 - - - - - - [Channel1] - MaudioXponent.actbinstop - 0x80 - 33 - - - - - - [Channel1] - MaudioXponent.actbin - 0x90 - 34 - - - - - - [Channel1] - MaudioXponent.actbinstop - 0x80 - 34 - - - - - - [Channel1] - MaudioXponent.actbin - 0x90 - 19 - - - - - - [Channel1] - volume - 0xB0 - 7 - fader - - - [Channel1] - MaudioXponent.pitch - 0xE0 - 0 - - - - - - [Channel1] - MaudioXponent.wheel - 0xB0 - 22 - - - - - - [Channel1] - MaudioXponent.wheelbuton - 0x90 - 22 - - - - - - [Channel1] - MaudioXponent.wheelbutoff - 0x80 - 22 - - - - - - [Channel1] - MaudioXponent.actbin - 0x90 - 20 - - - - - - [Channel1] - pregain - 0xB0 - 11 - fader - - - [Channel1] - filterLow - 0xB0 - 8 - fader - - - [Channel1] - filterMid - 0xB0 - 9 - fader - - - [Channel1] - filterHigh - 0xB0 - 10 - fader - - - [Channel1] - MaudioXponent.actbin - 0x90 - 8 - - - - - - [Channel1] - filterLowKill - 0x80 - 8 - button - - - [Channel1] - MaudioXponent.actbin - 0x90 - 9 - - - - - - [Channel1] - filterMidKill - 0x80 - 9 - button - - - [Channel1] - MaudioXponent.actbin - 0x90 - 10 - - - - - - [Channel1] - filterHighKill - 0x80 - 10 - button - - - [Channel1] - rate_temp_up - 0x90 - 16 - button - - - [Channel1] - rate_temp_up - 0x80 - 16 - button - - - [Channel1] - rate_temp_down - 0x90 - 17 - button - - - [Channel1] - rate_temp_down - 0x80 - 17 - button - - - [Channel1] - beatsync - 0x90 - 2 - button - - - [Channel1] - beatsync - 0x80 - 2 - button - - - [Channel1] - MaudioXponent.loopin - 0x90 - 41 - - - - - - [Channel1] - MaudioXponent.loopexit - 0x90 - 42 - - - - - - [Channel1] - MaudioXponent.loopout - 0x90 - 43 - - - - - - [Channel1] - MaudioXponent.hotcueset - 0x90 - 23 - - - - - - [Channel1] - MaudioXponent.hotcueset - 0x90 - 24 - - - - - - [Channel1] - MaudioXponent.hotcueset - 0x90 - 25 - - - - - - [Channel1] - MaudioXponent.hotcueset - 0x90 - 26 - - - - - - [Channel1] - MaudioXponent.hotcueset - 0x90 - 27 - - - - - - [Channel1] - MaudioXponent.secondaryon - 0x90 - 44 - - - - - - [Channel1] - MaudioXponent.secondaryoff - 0x80 - 44 - - - - - - [Channel1] - MaudioXponent.scrmode - 0x90 - 21 - - - - - - [Channel1] - MaudioXponent.playlist - 0x90 - 28 - - - - - - [Channel1] - MaudioXponent.playlistoff - 0x80 - 28 - - - - - - [Channel1] - MaudioXponent.playlist - 0x90 - 29 - - - - - - [Channel1] - MaudioXponent.playlistoff - 0x80 - 29 - - - - - - [Channel1] - MaudioXponent.playlist - 0x90 - 30 - - - - - - [Channel1] - MaudioXponent.playlistoff - 0x80 - 30 - - - - - - [Channel1] - MaudioXponent.playlist - 0x90 - 31 - - - - - - [Channel1] - MaudioXponent.playlistoff - 0x80 - 31 - - - - - - [Channel1] - MaudioXponent.playlist - 0x90 - 32 - - - - - - [Channel1] - MaudioXponent.playlistoff - 0x80 - 32 - - - - - - [Channel1] - MaudioXponent.volbuttonon - 0x90 - 11 - - - - - - [Channel1] - MaudioXponent.volbuttonoff - 0x80 - 11 - - - - - - [Channel2] - MaudioXponent.faderbuttonon - 0x91 - 7 - - - - - - [Channel2] - MaudioXponent.faderbuttonoff - 0x81 - 7 - - - - - - [Channel2] - MaudioXponent.actbin - 0x91 - 36 - - - - - - [Channel2] - play - 0x81 - 36 - button - - - [Channel2] - MaudioXponent.cuedefon - 0x91 - 35 - - - - - - [Channel2] - MaudioXponent.cuedefoff - 0x81 - 35 - - - - - - [Channel2] - MaudioXponent.actbin - 0x91 - 33 - - - - - - [Channel2] - MaudioXponent.actbinstop - 0x81 - 33 - - - - - - [Channel2] - MaudioXponent.actbin - 0x91 - 34 - - - - - - [Channel2] - MaudioXponent.actbinstop - 0x81 - 34 - - - - - - [Channel2] - MaudioXponent.actbin - 0x91 - 19 - - - - - - [Channel2] - volume - 0xB1 - 7 - fader - - - [Channel2] - MaudioXponent.pitch - 0xE1 - 0 - - - - - - [Channel2] - MaudioXponent.wheel - 0xB1 - 22 - - - - - - [Channel2] - MaudioXponent.wheelbuton - 0x91 - 22 - - - - - - [Channel2] - MaudioXponent.wheelbutoff - 0x81 - 22 - - - - - - [Channel2] - MaudioXponent.actbin - 0x91 - 20 - - - - - - [Channel2] - pregain - 0xB1 - 11 - fader - - - [Channel2] - filterLow - 0xB1 - 8 - fader - - - [Channel2] - filterMid - 0xB1 - 9 - fader - - - [Channel2] - filterHigh - 0xB1 - 10 - fader - - - [Channel2] - MaudioXponent.actbin - 0x91 - 8 - - - - - - [Channel2] - filterLowKill - 0x81 - 8 - button - - - [Channel2] - MaudioXponent.actbin - 0x91 - 9 - - - - - - [Channel2] - filterMidKill - 0x81 - 9 - button - - - [Channel2] - MaudioXponent.actbin - 0x91 - 10 - - - - - - [Channel2] - filterHighKill - 0x81 - 10 - button - - - [Channel2] - rate_temp_up - 0x91 - 16 - button - - - [Channel2] - rate_temp_up - 0x81 - 16 - button - - - [Channel2] - rate_temp_down - 0x91 - 17 - button - - - [Channel2] - rate_temp_down - 0x81 - 17 - button - - - [Channel2] - beatsync - 0x91 - 2 - button - - - [Channel2] - beatsync - 0x81 - 2 - button - - - [Channel2] - MaudioXponent.loopin - 0x91 - 41 - - - - - - [Channel2] - MaudioXponent.loopexit - 0x91 - 42 - - - - - - [Channel2] - MaudioXponent.loopout - 0x91 - 43 - - - - - - [Channel2] - MaudioXponent.hotcueset - 0x91 - 23 - - - - - - [Channel2] - MaudioXponent.hotcueset - 0x91 - 24 - - - - - - [Channel2] - MaudioXponent.hotcueset - 0x91 - 25 - - - - - - [Channel2] - MaudioXponent.hotcueset - 0x91 - 26 - - - - - - [Channel2] - MaudioXponent.hotcueset - 0x91 - 27 - - - - - - [Channel2] - MaudioXponent.secondaryon - 0x91 - 44 - - - - - - [Channel2] - MaudioXponent.secondaryoff - 0x81 - 44 - - - - - - [Channel2] - MaudioXponent.flanger - 0x91 - 12 - - - - - - [Channel2] - MaudioXponent.flanger - 0x91 - 13 - - - - - - [Flanger] - lfoDepth - 0xB1 - 12 - fader - - - [Flanger] - lfoDelay - 0xB1 - 13 - fader - - - [Flanger] - lfoPeriod - 0xB1 - 14 - fader - - - [Channel2] - MaudioXponent.scrmode - 0x91 - 21 - - - - - - [Channel2] - MaudioXponent.playlist - 0x91 - 28 - - - - - - [Channel2] - MaudioXponent.playlistoff - 0x81 - 28 - - - - - - [Channel2] - MaudioXponent.playlist - 0x91 - 29 - - - - - - [Channel2] - MaudioXponent.playlistoff - 0x81 - 29 - - - - - - [Channel2] - MaudioXponent.playlist - 0x91 - 30 - - - - - - [Channel2] - MaudioXponent.playlistoff - 0x81 - 30 - - - - - - [Channel2] - MaudioXponent.playlist - 0x91 - 31 - - - - - - [Channel2] - MaudioXponent.playlistoff - 0x81 - 31 - - - - - - [Channel2] - MaudioXponent.playlist - 0x91 - 32 - - - - - - [Channel2] - MaudioXponent.playlistoff - 0x81 - 32 - - - - - - [Channel2] - MaudioXponent.volbuttonon - 0x91 - 11 - - - - - - [Channel2] - MaudioXponent.volbuttonoff - 0x81 - 11 - - - - - - [Channel1] - MaudioXponent.actbin - 0x90 - 18 - - - - - - [Channel2] - MaudioXponent.actbin - 0x91 - 18 - - - - - - - - - - - - - - - - diff --git a/res/controllers/korg_nanokontrol2.mixco.output.js b/res/controllers/korg_nanokontrol2.mixco.output.js new file mode 100644 index 000000000000..40372c2c7cbe --- /dev/null +++ b/res/controllers/korg_nanokontrol2.mixco.output.js @@ -0,0 +1,8214 @@ +/* + * File generated with Mixco framework version: 2.0.2 + * More info at: + */ + +MIXCO_SCRIPT_FILENAME = '/home/raskolnikov/dev/mixco/script/korg_nanokontrol2.mixco.litcoffee'; + +require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 64 ? v1 - 128 : v1); + }); + add('button', function(v) { + return v !== 0; + }); + add('switch', function(v) { + return 1; + }); + result.switch_ = result["switch"]; + add('hercjog', function(v1, v0) { + return v0 + (v1 > 64 ? v1 - 128 : v1); + }); + add('spread64', function(v) { + return v - 64; + }); + add('selectknob', function(v) { + if (v > 64) { + return v - 128; + } else { + return v; + } + }); + return add('soft-takeover', 'softTakeover', { + enable: function(b) { + if (isinstance(b, exports.MapIn)) { + return b.script.mixxx.engine.softTakeover(b.group, b.key, true); + } + }, + disable: function(b) { + if (isinstance(b, exports.MapIn)) { + return b.script.mixxx.engine.softTakeover(b.group, b.key, false); + } + } + }); + })(); + + exports.makeOptionsChooser = makeOptionsChooser = function(obj) { + var key, opt, result; + result = {}; + for (key in option) { + opt = option[key]; + Object.defineProperty(result, key, { + get: (function(opt) { + return function() { + return obj.option(opt); + }; + })(opt) + }); + } + return result; + }; + + exports.Behaviour = (function(superClass) { + extend1(Behaviour, superClass); + + function Behaviour() { + return Behaviour.__super__.constructor.apply(this, arguments); + } + + Behaviour.prototype.enable = function(script, actor) { + var i, len, opt, ref3, results; + assert(this.actor == null); + assert(this.script == null); + this.script = script; + this.actor = actor; + this._eventListener = (function(_this) { + return function(ev) { + var i, len, opt, ref3; + if (_this._options != null) { + ev = copy(ev); + ref3 = _this._options; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (typeof opt.process === "function") { + opt.process(ev, _this); + } + } + } + return _this.onMidiEvent(ev); + }; + })(this); + actor.on('event', this._eventListener); + if (this._options != null) { + ref3 = this._options; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + results.push(typeof opt.enable === "function" ? opt.enable(this) : void 0); + } + return results; + } + }; + + Behaviour.prototype.disable = function(script, actor) { + var i, len, opt, ref3; + assert(this.script === script); + assert(this.actor === actor); + if (this._options != null) { + ref3 = this._options; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (typeof opt.disable === "function") { + opt.disable(this); + } + } + } + actor.removeListener('event', this._eventListener); + delete this.script; + return delete this.actor; + }; + + Behaviour.prototype.option = function() { + var i, len, opt, options, ref3; + options = 1 <= arguments.length ? slice.call(arguments, 0) : []; + for (i = 0, len = options.length; i < len; i++) { + opt = options[i]; + assert(opt); + } + (ref3 = (this._options != null ? this._options : this._options = [])).push.apply(ref3, map(options, toOption)); + return this; + }; + + Behaviour.property('options', function() { + return makeOptionsChooser(this); + }); + + Behaviour.prototype.directInMapping = function() { + return null; + }; + + Behaviour.prototype.directOutMapping = function() { + return null; + }; + + Behaviour.prototype.onMidiEvent = function(ev) { + return null; + }; + + Behaviour.prototype.getMidiValue = function() { + return this.value; + }; + + Behaviour.property('midiValue', function() { + return this.getMidiValue(); + }); + + return Behaviour; + + })(value.Value); + + exports.Call = (function(superClass) { + extend1(Call, superClass); + + function Call(onMidiEvent) { + this.onMidiEvent = onMidiEvent; + Call.__super__.constructor.call(this); + } + + return Call; + + })(exports.Behaviour); + + exports.call = factory(exports.Call); + + exports.Output = (function(superClass) { + extend1(Output, superClass); + + Output.prototype.minimum = 1; + + Output.prototype.maximum = void 0; + + function Output() { + Output.__super__.constructor.apply(this, arguments); + this.output = value.value(); + } + + Output.prototype.enable = function() { + Output.__super__.enable.apply(this, arguments); + if (this.actor.send != null) { + if (this._updateOutputCallback == null) { + this._updateOutputCallback = (function(_this) { + return function() { + return _this.updateOutput(); + }; + })(this); + } + this.output.on('value', this._updateOutputCallback); + } + if (this.actor.doSend != null) { + return this.updateOutput(this.actor.doSend); + } + }; + + Output.prototype.disable = function() { + if (this._updateOutputCallback != null) { + this.removeListener('value', this._updateOutputCallback); + this._updateOutputCallback = void 0; + } + return Output.__super__.disable.apply(this, arguments); + }; + + Output.prototype.updateOutput = function(sendfn) { + if (sendfn == null) { + sendfn = null; + } + if (sendfn == null) { + sendfn = this.actor.send; + } + return sendfn.call(this.actor, (Math.abs(this.output.value) >= this.minimum ? 'on' : 'off')); + }; + + return Output; + + })(exports.Behaviour); + + exports.Transform = (function(superClass) { + extend1(Transform, superClass); + + function Transform(transformer1, initial) { + this.transformer = transformer1; + if (initial == null) { + initial = void 0; + } + Transform.__super__.constructor.call(this, { + initial: initial + }); + } + + Transform.prototype.onMidiEvent = function(ev) { + var result; + result = this.transformer(ev, this.midiValue); + if (result != null) { + return this.output.value = this.value = result; + } + }; + + Transform.prototype.getMidiValue = function() { + var base, ref3; + return (ref3 = typeof (base = this.transformer).inverse === "function" ? base.inverse(this.value) : void 0) != null ? ref3 : this.value; + }; + + return Transform; + + })(exports.Output); + + exports.transform = factory(exports.Transform); + + exports.modifier = function() { + return exports.transform(transform.momentaryT, false); + }; + + exports["switch"] = function() { + return exports.transform(transform.binaryT, false); + }; + + exports.switch_ = exports["switch"]; + + exports.MapIn = (function(superClass) { + extend1(MapIn, superClass); + + function MapIn(ingroupOrParams, inkey) { + var ref3; + if (inkey == null) { + inkey = void 0; + } + MapIn.__super__.constructor.apply(this, arguments); + ref3 = !isinstance(ingroupOrParams, String) ? ingroupOrParams : { + group: ingroupOrParams, + key: inkey + }, this.group = ref3.group, this.key = ref3.key; + this._transform = transform.mappings[this.key]; + } + + MapIn.prototype.transform = function(trans) { + this._transform = trans; + return this; + }; + + MapIn.prototype.enable = function(script, actor) { + var engine; + MapIn.__super__.enable.apply(this, arguments); + engine = script.mixxx.engine; + this.value = engine.getValue(this.group, this.key); + if (this.listeners('value').length > 0) { + if (this._inHandler == null) { + this._inHandler = script.registerHandler((function(_this) { + return function(v) { + return _this.value = v; + }; + })(this)); + } + engine.connectControl(this.group, this.key, this._inHandler); + return this._inHandlerConnected = true; + } + }; + + MapIn.prototype.disable = function() { + if (this._inHandlerConnected != null) { + this.script.mixxx.engine.connectControl(this.group, this.key, this._inHandler, true); + this._inHandlerConnected = false; + } + return MapIn.__super__.disable.apply(this, arguments); + }; + + MapIn.prototype.directInMapping = function() { + if (this._transform === transform.mappings[this.key]) { + return { + group: this.group, + key: this.key + }; + } + }; + + MapIn.prototype.onMidiEvent = function(ev) { + var val; + val = this._transform(ev, this.midiValue); + if (val != null) { + this.script.mixxx.engine.setValue(this.group, this.key, val); + if (this.listeners('value').length === 0) { + return this.value = val; + } + } + }; + + MapIn.prototype.getMidiValue = function() { + var ref3, ref4; + return (ref3 = (ref4 = this._transform) != null ? typeof ref4.inverse === "function" ? ref4.inverse(this.value) : void 0 : void 0) != null ? ref3 : this.value; + }; + + return MapIn; + + })(exports.Behaviour); + + exports.mapIn = factory(exports.MapIn); + + exports.MapOut = (function(superClass) { + extend1(MapOut, superClass); + + function MapOut(outgroupOrParams, outkey) { + var ref3; + if (outkey == null) { + outkey = void 0; + } + MapOut.__super__.constructor.apply(this, arguments); + ref3 = !isinstance(outgroupOrParams, String) ? outgroupOrParams : { + outgroup: outgroupOrParams, + outkey: outkey + }, this.outgroup = ref3.outgroup, this.outkey = ref3.outkey; + } + + MapOut.prototype.meter = function(transformer) { + if (transformer == null) { + transformer = void 0; + } + this._outTransform = transformer; + if (this._outTransform == null) { + this._outTransform = transform.mappings[this.outkey].inverse; + } + this.updateOutput = function() { + return this.actor.send(Math.floor(this._outTransform(this.output.value))); + }; + return this; + }; + + MapOut.prototype.enable = function(script, actor) { + var engine; + MapOut.__super__.enable.apply(this, arguments); + engine = script.mixxx.engine; + this.output.value = engine.getValue(this.outgroup, this.outkey); + if (this.output.listeners('value').length > 0) { + if (this._outHandler == null) { + this._outHandler = script.registerHandler((function(_this) { + return function(v) { + return _this.output.value = v; + }; + })(this)); + } + engine.connectControl(this.outgroup, this.outkey, this._outHandler); + return this._outHandlerConnected = true; + } + }; + + MapOut.prototype.disable = function() { + if (this._outHandlerConnected != null) { + this.script.mixxx.engine.connectControl(this.outgroup, this.outkey, this._outHandler, true); + this._outHandlerConnected = false; + } + return MapOut.__super__.disable.apply(this, arguments); + }; + + MapOut.prototype.directOutMapping = function() { + if (this._outTransform == null) { + return { + group: this.outgroup, + key: this.outkey, + minimum: this.minimum + }; + } + }; + + return MapOut; + + })(exports.Output); + + exports.mapOut = factory(exports.MapOut); + + exports.Map = (function(superClass) { + extend1(Map, superClass); + + function Map(groupOrParams, key, outgroup, outkey) { + var params; + params = !isinstance(groupOrParams, String) ? groupOrParams : { + group: groupOrParams, + key: key, + outgroup: outgroup, + outkey: outkey + }; + if (params.outgroup == null) { + params.outgroup = params.group; + } + if (params.outkey == null) { + params.outkey = params.key; + } + Map.__super__.constructor.call(this, params); + } + + return Map; + + })(multi(exports.MapIn, exports.MapOut)); + + exports.map = factory(exports.Map); + + exports.toBehaviour = function() { + var args, behaviour; + behaviour = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + if (args.length > 0) { + return exports.map.apply(exports, [behaviour].concat(slice.call(args))); + } else { + return behaviour; + } + }; + + exports.soft = function() { + return exports.map.apply(exports, arguments).option(option.softTakeover); + }; + + exports.toggle = function() { + var args, offValue, onValue; + offValue = arguments[0], onValue = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; + return exports.map.apply(exports, args).transform(function(ev) { + if (ev.pressed) { + return onValue; + } else { + return offValue; + } + }); + }; + + exports.set = function() { + var args, valueToSet; + valueToSet = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.toggle.apply(exports, [valueToSet, null].concat(slice.call(args))); + }; + + exports.Chooser = (function(superClass) { + extend1(Chooser, superClass); + + function Chooser(arg) { + var ref3; + ref3 = arg != null ? arg : {}, this.autoExclusive = ref3.autoExclusive, this.onDisable = ref3.onDisable; + Chooser.__super__.constructor.apply(this, arguments); + this._selectedIndex = null; + this._chooseOptions = []; + this._chooseActivators = []; + this._chooseSelectors = []; + this._chooseHandles = []; + } + + Chooser.prototype.add = function(group, key, listen) { + var activator, idx; + if (listen == null) { + listen = null; + } + idx = this._chooseOptions.length; + activator = exports.map(group, key).transform((function(_this) { + return function(ev) { + if (ev.pressed) { + _this.activate(idx); + } + return null; + }; + })(this)); + this._chooseOptions.push([group, key, listen]); + this._chooseActivators.push(activator); + return activator; + }; + + Chooser.prototype.enable = function(script) { + var engine, group, i, key, len, listen, ref3, ref4; + Chooser.__super__.enable.apply(this, arguments); + if (this._updateValueHandler == null) { + this._updateValueHandler = script.registerHandler((function(_this) { + return function() { + return _this._updateValue(); + }; + })(this)); + } + engine = script.mixxx.engine; + ref3 = this._chooseOptions; + for (i = 0, len = ref3.length; i < len; i++) { + ref4 = ref3[i], group = ref4[0], key = ref4[1], listen = ref4[2]; + if (listen == null) { + listen = key; + } + engine.connectControl(group, listen, this._updateValueHandler); + } + return this._updateValue(); + }; + + Chooser.prototype.disable = function(script) { + var engine, group, i, key, len, listen, ref3, ref4; + assert(this._updateValueHandler); + engine = script.mixxx.engine; + ref3 = this._chooseOptions; + for (i = 0, len = ref3.length; i < len; i++) { + ref4 = ref3[i], group = ref4[0], key = ref4[1], listen = ref4[2]; + if (listen == null) { + listen = key; + } + engine.connectControl(group, listen, this._updateValueHandler, true); + } + return Chooser.__super__.disable.apply(this, arguments); + }; + + Chooser.prototype.activator = function(idx) { + assert((0 <= idx && idx < this._chooseOptions.length)); + return this._chooseActivators[idx]; + }; + + Chooser.prototype.selector = function() { + var select, selector; + select = (function(_this) { + return function(ev) { + var v; + v = (ev.value / 128.0 * _this._chooseOptions.length).clamp(0, _this._chooseOptions.length - 1); + _this._update({ + index: Math.floor(v) + }); + return v; + }; + })(this); + select.inverse = (function(_this) { + return function(v) { + return v / _this._chooseOptions.length * 128.0; + }; + })(this); + selector = extend(exports.transform(select), { + _updateValue: function(newv) { + if (Math.floor(newv) !== Math.floor(this.value)) { + return this.value = this.output.value = newv; + } + } + }); + this._chooseSelectors.push(selector); + return selector; + }; + + Chooser.prototype.momentary = function() { + return exports.action({ + press: (function(_this) { + return function() { + return _this._update({ + enable: true + }); + }; + })(this), + release: (function(_this) { + return function() { + return _this._update({ + enable: false + }); + }; + })(this) + }); + }; + + Chooser.prototype.activate = function(idx) { + this._update({ + index: idx, + enable: true + }); + return this; + }; + + Chooser.prototype.select = function(idx) { + if (this.actor != null) { + this._update({ + index: idx, + enable: true + }); + } else { + this._selectedIndex = idx; + } + return this; + }; + + Chooser.prototype.onMidiEvent = function(event) { + var enable; + if (event.pressed) { + enable = !this.value; + this._update({ + enable: enable + }); + if (!enable) { + return typeof this.onDisable === "function" ? this.onDisable() : void 0; + } + } + }; + + Chooser.prototype._update = function(arg) { + var enable, group, i, idx, index, key, len, listen, ref3, ref4, ref5, ref6, ref7, script; + ref3 = arg != null ? arg : {}, index = ref3.index, enable = ref3.enable; + if (enable == null) { + enable = this.value; + } + if (index == null) { + index = this._selectedIndex; + } + index = index != null ? index.clamp(0, this._chooseOptions.length - 1) : void 0; + if (index !== this._selectedIndex || enable !== this.value) { + script = (ref4 = this.script) != null ? ref4 : this._chooseActivators[index].script; + if (index != null) { + ref5 = this._chooseOptions[index], group = ref5[0], key = ref5[1], listen = ref5[2]; + script.mixxx.engine.setValue(group, key, enable); + } + if (!this.autoExclusive || !enable) { + ref6 = this._chooseOptions; + for (idx = i = 0, len = ref6.length; i < len; idx = ++i) { + ref7 = ref6[idx], group = ref7[0], key = ref7[1]; + if (idx !== index) { + script.mixxx.engine.setValue(group, key, false); + } + } + } + return this._selectedIndex = index; + } + }; + + Chooser.prototype._updateValue = function() { + var engine, i, len, ref3, selector; + if (this.script != null) { + engine = this.script.mixxx.engine; + this.value = this.output.value = _.some(this._chooseOptions, function(arg) { + var group, key, listen; + group = arg[0], key = arg[1], listen = arg[2]; + if (listen == null) { + listen = key; + } + return engine.getValue(group, listen); + }); + ref3 = this._chooseSelectors; + for (i = 0, len = ref3.length; i < len; i++) { + selector = ref3[i]; + selector._updateValue(this._selectedIndex); + } + } + return this; + }; + + return Chooser; + + })(exports.Output); + + exports.chooser = factory(exports.Chooser); + + exports.When = (function(superClass) { + extend1(When, superClass); + + function When() { + var _condition, base, wrapped; + _condition = arguments[0], wrapped = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this._condition = _condition; + this["else"] = (function(_this) { + return function() { + return _this._else.apply(_this, arguments); + }; + })(this); + this["else"].when = (function(_this) { + return function() { + return _this._elseWhen.apply(_this, arguments); + }; + })(this); + this.when = this["else"].when; + this.else_ = this["else"]; + When.__super__.constructor.call(this); + this._wrapped = exports.toBehaviour.apply(exports, wrapped); + this._condition.on('value', (function(_this) { + return function() { + return _this._update(); + }; + })(this)); + if (this._lastCondition !== 'no-more-negations') { + this._lastCondition = this._condition; + if ((base = this._lastCondition).negation == null) { + base.negation = value.not(this._condition); + } + } + } + + When.prototype.option = function() { + var ref3; + When.__super__.option.apply(this, arguments); + (ref3 = this._wrapped).option.apply(ref3, arguments); + return this; + }; + + When.prototype._elseWhen = function() { + var args, condition, nextCondition; + condition = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + assert(this._lastCondition != null, "Can not define more conditions after 'else'"); + nextCondition = value.and(condition, value.not(this._lastCondition)); + nextCondition.negation = value.and(this._lastCondition.negation, value.not(condition)); + this._lastCondition = nextCondition; + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(exports.When, [nextCondition].concat(slice.call(args)), function(){}); + }; + + When.prototype._else = function() { + var args, nextCondition; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastCondition != null, "Can not define more conditions after 'else'"); + nextCondition = this._lastCondition.negation; + nextCondition.negation = 'no-more-negations'; + delete this._lastCondition; + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(exports.When, [nextCondition].concat(slice.call(args)), function(){}); + }; + + When.prototype.enable = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + When.__super__.enable.apply(this, arguments); + this._enableOn = args; + this._enableRequested = true; + return this._update(); + }; + + When.prototype.disable = function() { + this._enableRequested = false; + this._update(); + return When.__super__.disable.apply(this, arguments); + }; + + When.prototype._update = function() { + var ref3, ref4; + this.value = this._enableRequested && this._condition.value; + if (this._wrapped.actor && !this.value) { + (ref3 = this._wrapped).disable.apply(ref3, this._enableOn); + } + if (!this._wrapped.actor && this.value) { + return (ref4 = this._wrapped).enable.apply(ref4, this._enableOn); + } + }; + + When.prototype.directOutMapping = function() { + return null; + }; + + When.prototype.directInMapping = function() { + return null; + }; + + return When; + + })(exports.Behaviour); + + exports.when = factory(exports.When); + + exports.Action = (function(superClass) { + extend1(Action, superClass); + + Action.prototype.minimum = true; + + function Action(action) { + this.action = action != null ? action : void 0; + Action.__super__.constructor.call(this); + if (this.onPress == null) { + this.onPress = this.action.press; + } + if (this.onRelease == null) { + this.onRelease = this.action.release; + } + } + + Action.prototype.onMidiEvent = function(ev) { + var val; + val = this.value = this.output.value = ev.pressed; + if (val) { + return typeof this.onPress === "function" ? this.onPress() : void 0; + } else { + return typeof this.onRelease === "function" ? this.onRelease() : void 0; + } + }; + + return Action; + + })(exports.Output); + + exports.action = factory(exports.Action); + + exports.punchIn = function(threshold, threshold2) { + var inThreshold, oldxfader; + if (threshold2 == null) { + threshold2 = void 0; + } + oldxfader = void 0; + inThreshold = function(newxfader, threshold) { + return (threshold < 0 && newxfader < threshold) || (threshold > 0 && newxfader > threshold); + }; + return exports.action({ + press: function() { + var engine, newxfader; + engine = this.script.mixxx.engine; + newxfader = engine.getValue("[Master]", "crossfader"); + if (inThreshold(newxfader, threshold) || ((threshold2 != null) && inThreshold(newxfader, threshold2))) { + oldxfader = newxfader; + return engine.setValue("[Master]", "crossfader", 0); + } + }, + release: function() { + var engine; + engine = this.script.mixxx.engine; + if (oldxfader != null) { + engine.setValue("[Master]", "crossfader", oldxfader); + return oldxfader = void 0; + } + } + }); + }; + + exports.scratchEnable = function(deck, intervalsPerRev, rpm, alpha, beta, ramp) { + if (intervalsPerRev == null) { + intervalsPerRev = 128 * 4; + } + if (rpm == null) { + rpm = 44.0; + } + if (alpha == null) { + alpha = 1.0 / 8.0; + } + if (beta == null) { + beta = 1.0 / 8.0 / 32.0; + } + if (ramp == null) { + ramp = true; + } + return exports.action({ + press: function() { + var enable; + enable = this.script.mixxx.engine.scratchEnable; + return enable(deck, intervalsPerRev, rpm, alpha, beta, ramp); + }, + release: function() { + return this.script.mixxx.engine.scratchDisable(deck, ramp); + } + }); + }; + + exports.scratchTick = function(deck, transform) { + if (transform == null) { + transform = function(x) { + return x; + }; + } + return exports.call(function(ev) { + var engine; + engine = this.script.mixxx.engine; + return engine.scratchTick(deck, transform(ev.value)); + }); + }; + + exports.spinback = function() { + var args, deck; + deck = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.modifier().on('value', function() { + var ref3; + return (ref3 = this.script.mixxx.engine).spinback.apply(ref3, [deck, this.value].concat(slice.call(args))); + }); + }; + + exports.brake = function() { + var args, deck; + deck = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.modifier().on('value', function() { + var ref3; + return (ref3 = this.script.mixxx.engine).brake.apply(ref3, [deck, this.value].concat(slice.call(args))); + }); + }; + + exports.playhead = function(g) { + return exports.mapOut(g, "playposition").meter((function() { + var step; + step = 0; + return function(pos) { + var duration, engine; + engine = this.script.mixxx.engine; + duration = (function() { + switch (false) { + case !!engine.getValue(g, "play"): + return void 0; + case !(pos > .9): + return 5; + case !(pos > .8): + return 9; + case !(pos > .75): + return 13; + default: + return void 0; + } + })(); + if (duration != null) { + step = (step + 1) % duration; + if (step > duration / 2) { + return 0; + } else { + return pos * 127; + } + } else { + step = 0; + return pos * 127; + } + }; + })()); + }; + + exports.beatEffect = function(channel, type) { + var i, len, result, size, sizes; + if (type == null) { + type = ''; + } + sizes = ["0.0625", "0.125", "0.25", "0.5", "1", "2", "4", "8", "16", "32", "64"]; + result = exports.chooser({ + autoExclusive: true, + onDisable: function() { + var engine; + engine = this.script.mixxx.engine; + if (type !== 'roll' && engine.getValue(channel, "loop_enabled")) { + return engine.setValue(channel, "reloop_exit", true); + } + } + }); + for (i = 0, len = sizes.length; i < len; i++) { + size = sizes[i]; + result.add(channel, "beatloop" + type + "_" + size + "_activate", "beatloop_" + size + "_enabled"); + } + return result.select(4); + }; + + exports.stutter = function(group, beats) { + var tick; + if (beats == null) { + beats = 0.25; + } + tick = function() { + var engine, gain, newgain; + engine = this.script.mixxx.engine; + gain = engine.getValue(group, "pregain"); + newgain = gain > 0 ? (this._oldgain = gain, 0) : this._oldgain; + return engine.setValue(group, "pregain", newgain); + }; + return exports.action({ + press: function() { + var bpm, delta, engine; + engine = this.script.mixxx.engine; + bpm = engine.getValue(group, "bpm"); + delta = beats * 60000 / bpm; + if (this._timerHandle == null) { + this._timerHandle = this.script.registerHandler(bind(tick, this)); + } + return this._timerId != null ? this._timerId : this._timerId = engine.beginTimer(delta, this._timerHandle); + }, + release: function() { + var engine; + engine = this.script.mixxx.engine; + engine.stopTimer(this._timerId); + if (this._oldgain != null) { + engine.setValue(group, "pregain", this._oldgain); + } + delete this._timerId; + return delete this._oldgain; + } + }); + }; + +}).call(this); + +},{"./transform":7,"./util":8,"./value":9,"events":10,"heterarchy":13,"underscore":16}],4:[function(require,module,exports){ +// Generated by CoffeeScript 1.10.0 +(function() { + var assert, exports, konsole; + + assert = require('./util').assert; + + konsole = this; + + exports = konsole; + + if (konsole.log == null) { + konsole.log = function() { + return print("" + arguments); + }; + } + + if (konsole.info == null) { + konsole.info = konsole.log; + } + + if (konsole.warn == null) { + konsole.warn = konsole.log; + } + + if (konsole.error == null) { + konsole.error = konsole.log; + } + + if (konsole.time == null) { + konsole.time = function() { + return assert(False, "time not implemented in konsole"); + }; + } + + if (konsole.timeEnd == null) { + konsole.timeEnd = function() { + return assert(False, "time not implemented in konsole"); + }; + } + + if (konsole.trace == null) { + konsole.trace = function() { + var err; + err = new Error(); + err.name = "Trace"; + err.message = "" + arguments; + return konsole.error(err.stack); + }; + } + + if (konsole.dir == null) { + konsole.dir = function() { + return konsole.log(object + "\n"); + }; + } + + if (konsole.assert == null) { + konsole.assert = assert; + } + +}).call(this); + +},{"./util":8}],5:[function(require,module,exports){ +// Generated by CoffeeScript 1.10.0 +(function() { + var MIDI_CC, MIDI_NOTE_OFF, MIDI_NOTE_ON, MIDI_PITCHBEND, assert, behaviour, ccIds, event, extend, factory, hexStr, indent, joinLn, midiId, multi, noteIds, noteOnIds, pbIds, ref, ref1, some, xmlTag, + slice = [].slice, + extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + multi = require('heterarchy').multi; + + ref = require('./util'), indent = ref.indent, hexStr = ref.hexStr, assert = ref.assert, factory = ref.factory, xmlTag = ref.xmlTag, joinLn = ref.joinLn; + + behaviour = require('./behaviour'); + + ref1 = require('underscore'), some = ref1.some, extend = ref1.extend; + + exports.MIDI_NOTE_ON = MIDI_NOTE_ON = 0x9; + + exports.MIDI_NOTE_OFF = MIDI_NOTE_OFF = 0x8; + + exports.MIDI_CC = MIDI_CC = 0xB; + + exports.MIDI_PITCHBEND = MIDI_PITCHBEND = 0xE; + + midiId = function(message, midino, channel) { + if (message == null) { + message = MIDI_CC; + } + if (midino == null) { + midino = 0; + } + if (channel == null) { + channel = 0; + } + return { + message: message, + midino: midino, + channel: channel, + status: function() { + return (this.message << 4) | this.channel; + }, + configMidi: function(depth) { + return (indent(depth)) + "" + (hexStr(this.status())) + "\n" + (indent(depth)) + "" + (hexStr(this.midino)) + ""; + } + }; + }; + + exports.midiId = midiId; + + pbIds = function() { + return [midiId.apply(null, [MIDI_PITCHBEND, 0].concat(slice.call(arguments)))]; + }; + + noteOnIds = function() { + return [midiId.apply(null, [MIDI_NOTE_ON].concat(slice.call(arguments)))]; + }; + + noteIds = function() { + return [midiId.apply(null, [MIDI_NOTE_ON].concat(slice.call(arguments))), midiId.apply(null, [MIDI_NOTE_OFF].concat(slice.call(arguments)))]; + }; + + ccIds = function() { + return [midiId.apply(null, [MIDI_CC].concat(slice.call(arguments)))]; + }; + + exports.pbIds = pbIds; + + exports.noteOnIds = noteOnIds; + + exports.noteIds = noteIds; + + exports.ccIds = ccIds; + + exports.event = event = function(channel, control, value, status, group) { + return { + channel: channel, + control: control, + value: (function() { + switch (status >> 4) { + case MIDI_PITCHBEND: + return (value * 128.0 + control) / 128.0; + default: + return value; + } + })(), + status: status, + group: group, + message: function() { + return this.status >> 4; + }, + pressed: status >> 4 !== MIDI_NOTE_OFF && value + }; + }; + + exports.Control = (function(superClass) { + extend1(Control, superClass); + + function Control() { + var args, ids; + ids = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this.ids = ids != null ? ids : [midiId()]; + this["else"] = (function(_this) { + return function() { + return _this._else.apply(_this, arguments); + }; + })(this); + this["else"].when = (function(_this) { + return function() { + return _this._elseWhen.apply(_this, arguments); + }; + })(this); + this.else_ = this["else"]; + Control.__super__.constructor.call(this); + if (!(this.ids instanceof Array)) { + this.ids = ccIds.apply(null, [this.ids].concat(slice.call(args))); + } + this._behaviours = []; + if (typeof this._controlRegistry === "function") { + this._controlRegistry(this); + } + } + + Control.prototype.does = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit); + this._behaviours.push(this.registerBehaviour(behaviour.toBehaviour.apply(behaviour, args))); + return this; + }; + + Control.prototype.when = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit); + this._lastWhen = behaviour.when.apply(behaviour, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + return this; + }; + + Control.prototype._elseWhen = function() { + var args, ref2; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastWhen != null, "'elseWhen' must be preceded by 'when' or 'elseWhen'"); + this._lastWhen = (ref2 = this._lastWhen["else"]).when.apply(ref2, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + return this; + }; + + Control.prototype._else = function() { + var args, ref2; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastWhen != null, "'else' must be preceded by 'when' or 'elseWhen'"); + this._lastWhen = (ref2 = this._lastWhen)["else"].apply(ref2, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + this._lastWhen = void 0; + return this; + }; + + Control.prototype.init = function(script) { + var b, i, len, ref2; + this.script = script; + assert(!this._isInit); + ref2 = this._behaviours; + for (i = 0, len = ref2.length; i < len; i++) { + b = ref2[i]; + b.enable(script, this); + } + return this._isInit = true; + }; + + Control.prototype.shutdown = function(script) { + var b, i, len, ref2; + assert(script === this.script); + assert(this._isInit); + ref2 = this._behaviours; + for (i = 0, len = ref2.length; i < len; i++) { + b = ref2[i]; + b.disable(script, this); + } + this._isInit = false; + return delete this.script; + }; + + Control.prototype.registerBehaviour = function(b) { + return b; + }; + + Control.prototype.configInputs = function(depth, script) {}; + + Control.prototype.configOutputs = function(depth, script) {}; + + Control.prototype.setRegistry = function(registry) { + assert((this._controlRegistry == null) || (registry == null)); + return this._controlRegistry = registry; + }; + + return Control; + + })(behaviour.Actor); + + exports.InControl = (function(superClass) { + extend1(InControl, superClass); + + function InControl() { + return InControl.__super__.constructor.apply(this, arguments); + } + + InControl.prototype.init = function(script) { + InControl.__super__.init.apply(this, arguments); + if (this.needsHandler()) { + return script.registerHandler(((function(_this) { + return function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return _this.emit('event', event.apply(null, args)); + }; + })(this)), this.handlerId()); + } + }; + + InControl.prototype.option = function() { + var beh, i, len, options, ref2, ref3; + options = 1 <= arguments.length ? slice.call(arguments, 0) : []; + (ref2 = (this._options != null ? this._options : this._options = [])).push.apply(ref2, options); + ref3 = this._behaviours; + for (i = 0, len = ref3.length; i < len; i++) { + beh = ref3[i]; + beh.option.apply(beh, options); + } + return this; + }; + + InControl.property('options', function() { + return behaviour.makeOptionsChooser(this); + }); + + InControl.prototype.registerBehaviour = function(beh) { + if (this._options != null) { + beh.option.apply(beh, this._options); + } + return beh; + }; + + InControl.prototype.needsHandler = function() { + return this._behaviours.length !== 1 || !this._behaviours[0].directInMapping() || some(this._behaviours[0]._options, function(opt) { + return !opt.name; + }); + }; + + InControl.prototype.handlerId = function() { + return "x" + (this.ids[0].status().toString(16)) + "_x" + (this.ids[0].midino.toString(16)); + }; + + InControl.prototype.configInputs = function(depth, script) { + var id, mapping; + if (this.needsHandler()) { + mapping = { + group: "[Master]", + key: script.handlerKey(this.handlerId()) + }; + } else { + mapping = this._behaviours[0].directInMapping(); + } + return joinLn((function() { + var i, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + results.push(this.configInMapping(depth, mapping, id)); + } + return results; + }).call(this)); + }; + + InControl.prototype.configInMapping = function(depth, mapping, id) { + return (indent(depth)) + "\n" + (indent(depth + 1)) + "" + mapping.group + "\n" + (indent(depth + 1)) + "" + mapping.key + "\n" + (id.configMidi(depth + 1)) + "\n" + (indent(depth + 1)) + "\n" + (this.configOptions(depth + 2)) + "\n" + (indent(depth + 1)) + "\n" + (indent(depth)) + ""; + }; + + InControl.prototype.configOptions = function(depth) { + var opt, ref2; + if (this.needsHandler()) { + return (indent(depth)) + ""; + } else if (((ref2 = this._behaviours[0]._options) != null ? ref2.length : void 0) > 0) { + return joinLn((function() { + var i, len, ref3, results; + ref3 = this._behaviours[0]._options; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (opt.name != null) { + results.push((indent(depth)) + "<" + opt.name + "/>"); + } else { + results.push(void 0); + } + } + return results; + }).call(this)); + } else { + return (indent(depth)) + ""; + } + }; + + return InControl; + + })(exports.Control); + + exports.OutControl = (function(superClass) { + extend1(OutControl, superClass); + + function OutControl() { + OutControl.__super__.constructor.apply(this, arguments); + this._states = { + on: 0x7f, + off: 0x00, + disable: 0x00 + }; + } + + OutControl.prototype.send = function(state) { + return this.doSend(state); + }; + + OutControl.prototype.states = function(states) { + extend(this._states, states); + return this; + }; + + OutControl.prototype.doSend = function(state) { + var i, id, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + if (id.message !== MIDI_NOTE_OFF) { + if (state in this._states) { + results.push(this.script.mixxx.midi.sendShortMsg(id.status(), id.midino, this._states[state])); + } else { + results.push(this.script.mixxx.midi.sendShortMsg(id.status(), id.midino, state)); + } + } else { + results.push(void 0); + } + } + return results; + }; + + OutControl.prototype.init = function() { + if (!this.needsSend()) { + this.send = void 0; + } + return OutControl.__super__.init.apply(this, arguments); + }; + + OutControl.prototype.shutdown = function() { + this.doSend('disable'); + return OutControl.__super__.shutdown.apply(this, arguments); + }; + + OutControl.prototype.needsSend = function() { + return this._behaviours.length !== 1 || !this._behaviours[0].directOutMapping(); + }; + + OutControl.prototype.configOutputs = function(depth, script) { + var id, mapping; + mapping = !this.needsSend() && this._behaviours[0].directOutMapping(); + if (mapping) { + return joinLn((function() { + var i, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + results.push(this.configOutMapping(depth, mapping, id)); + } + return results; + }).call(this)); + } + }; + + OutControl.prototype.configOutMapping = function(depth, mapping, id) { + var options; + if (id.message !== MIDI_NOTE_OFF) { + options = joinLn([xmlTag('minimum', mapping.minimum, depth + 1), xmlTag('maximum', mapping.maximum, depth + 1)]); + return (indent(depth)) + "\n" + (indent(depth + 1)) + "" + mapping.group + "\n" + (indent(depth + 1)) + "" + mapping.key + "\n" + (id.configMidi(depth + 1)) + "\n" + (indent(depth + 1)) + "" + (hexStr(this._states['on'])) + "\n" + (indent(depth + 1)) + "" + (hexStr(this._states['off'])) + "\n" + options + "\n" + (indent(depth)) + ""; + } + }; + + return OutControl; + + })(exports.Control); + + exports.input = factory(exports.InControl); + + exports.output = factory(exports.OutControl); + + exports.InOutControl = (function(superClass) { + extend1(InOutControl, superClass); + + function InOutControl() { + return InOutControl.__super__.constructor.apply(this, arguments); + } + + return InOutControl; + + })(multi(exports.InControl, exports.OutControl)); + + exports.control = factory(exports.InOutControl); + +}).call(this); + +},{"./behaviour":3,"./util":8,"heterarchy":13,"underscore":16}],6:[function(require,module,exports){ +(function (process){ +// Generated by CoffeeScript 1.10.0 +(function() { + var Control, S, _, assert, basename, bind, catching, flatten, indent, issubclass, mro, ref, ref1, ref2, xmlEscape, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, + slice = [].slice; + + ref = require('underscore'), flatten = ref.flatten, bind = ref.bind; + + ref1 = require('heterarchy'), issubclass = ref1.issubclass, mro = ref1.mro; + + Control = require('./control').Control; + + ref2 = require('./util'), indent = ref2.indent, xmlEscape = ref2.xmlEscape, catching = ref2.catching, assert = ref2.assert; + + require('./console'); + + basename = require('path').basename; + + S = require('string'); + + _ = require('underscore'); + + exports.nameFromFilename = function(fname) { + var extensions, name; + extensions = [".mixco.coffee", ".mixco.litcoffee", ".mixco.js", ".mixco"]; + fname = basename(fname); + assert(_.some(extensions, function(x) { + return S(fname).endsWith(x); + }), "Script file name: " + fname + " must end in one of: " + extensions); + name = extensions.reduce((function(fname, ext) { + return fname.replace(ext, ""); + }), fname); + assert(name.match(/^[a-zA-Z_$][0-9a-zA-Z_$].*$/, "Script name must be a valid JavaScript identifier")); + return name; + }; + + exports.register = function(targetModule, scriptTypeOrDefinition) { + var instance, name, scriptType; + name = targetModule.filename != null ? exports.nameFromFilename(targetModule.filename) : typeof MIXCO_SCRIPT_FILENAME !== "undefined" && MIXCO_SCRIPT_FILENAME !== null ? exports.nameFromFilename(MIXCO_SCRIPT_FILENAME) : assert(false, "Invalid script"); + scriptType = issubclass(scriptTypeOrDefinition, exports.Script) ? scriptTypeOrDefinition : exports.create(scriptTypeOrDefinition); + instance = new scriptType; + instance.__registeredName = name; + targetModule.exports[name] = instance; + if (targetModule === require.main) { + return instance.main(); + } + }; + + exports.create = function(scriptDefinition) { + var NewScript, constructor, init, k, shutdown, special, v; + assert(scriptDefinition.constructor != null, "Script definition must have a constructor"); + constructor = scriptDefinition.constructor, init = scriptDefinition.init, shutdown = scriptDefinition.shutdown; + NewScript = (function(superClass) { + extend(NewScript, superClass); + + function NewScript() { + NewScript.__super__.constructor.apply(this, arguments); + try { + Control.prototype.setRegistry(bind(this.add, this)); + constructor.apply(this, arguments); + } finally { + Control.prototype.setRegistry(null); + } + this; + } + + NewScript.prototype.init = function() { + var ref3; + if ((ref3 = this.preinit) != null) { + ref3.apply(this, arguments); + } + NewScript.__super__.init.apply(this, arguments); + return init != null ? init.apply(this, arguments) : void 0; + }; + + NewScript.prototype.shutdown = function() { + var ref3; + if (shutdown != null) { + shutdown.apply(this, arguments); + } + NewScript.__super__.shutdown.apply(this, arguments); + return (ref3 = this.postshutdown) != null ? ref3.apply(this, arguments) : void 0; + }; + + return NewScript; + + })(exports.Script); + special = ['name', 'constructor', 'init', 'shutdown']; + for (k in scriptDefinition) { + v = scriptDefinition[k]; + if (indexOf.call(special, k) < 0) { + NewScript.prototype[k] = v; + } + } + return NewScript; + }; + + exports.Script = (function() { + Script.prototype.info = { + name: "[mixco] Generic Script", + author: "Juan Pedro Bolivar Puente ", + description: "", + forums: "", + wiki: "" + }; + + Script.property('name', { + get: function() { + assert(this.__registeredName, "Script must be registered"); + return this.__registeredName; + } + }); + + Script.prototype.add = function() { + var controls, ref3; + controls = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit, "Can only add controls in constructor"); + return (ref3 = this.controls).push.apply(ref3, flatten(controls)); + }; + + Script.prototype.init = catching(function() { + var control, i, len, ref3, results; + this._isInit = true; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.init(this)); + } + return results; + }); + + Script.prototype.shutdown = catching(function() { + var control, i, len, ref3; + ref3 = this.controls; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + control.shutdown(this); + } + return delete this._isInit; + }); + + function Script() { + this.controls = []; + } + + Script.prototype.mixxx = { + engine: (typeof engine !== "undefined" && engine !== null ? engine : void 0), + midi: (typeof midi !== "undefined" && midi !== null ? midi : void 0), + script: (typeof script !== "undefined" && script !== null ? script : void 0) + }; + + Script.prototype.main = function() { + var arg, i, len, ref3, results; + ref3 = process.argv; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + arg = ref3[i]; + if (arg === '-h' || arg === '--help') { + console.info(this.help()); + break; + } + if (arg === '-g' || arg === '--generate-config') { + console.info(this.config()); + break; + } else { + results.push(void 0); + } + } + return results; + }; + + Script.prototype.help = function() { + return "Mixxx Controller Script\n=======================\n\nName: " + this.info.name + "\nAuthor: " + this.info.author + "\nDescription: " + this.info.description + "\nForums: " + this.info.description + "\n\nUsage\n-----\n1. Generate Mixxx config:\n coffee " + this.name + ".coffee -g > " + this.name + ".xml\n\n2. Generate Mixxx script:\n coffee -c " + this.name + ".coffee"; + }; + + Script.prototype.config = function() { + return "\n\n" + (indent(1)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.name)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.author)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.description)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.wiki)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.forums)) + "\n" + (indent(1)) + "\n" + (indent(1)) + "\n" + (indent(2)) + "\n" + (indent(3)) + "\n" + (indent(2)) + "\n" + (indent(2)) + "\n" + (this.configInputs(3)) + "\n" + (indent(2)) + "\n" + (indent(2)) + "\n" + (this.configOutputs(3)) + "\n" + (indent(2)) + "\n" + (indent(1)) + "\n"; + }; + + Script.prototype.configInputs = function(depth) { + var control; + return ((function() { + var i, len, ref3, results; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.configInputs(depth, this)); + } + return results; + }).call(this)).filter(function(x) { + return x; + }).join('\n'); + }; + + Script.prototype.configOutputs = function(depth) { + var control; + return ((function() { + var i, len, ref3, results; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.configOutputs(depth, this)); + } + return results; + }).call(this)).filter(function(x) { + return x; + }).join('\n'); + }; + + Script.prototype._nextCallbackId = 1; + + Script.prototype.registerHandler = function(callback, id) { + var handlerName; + if (id == null) { + id = void 0; + } + id || (id = this._nextCallbackId++); + handlerName = "__handle_" + id; + assert(!this[handlerName], "Handlers can be registered only once (" + handlerName + ")"); + this[handlerName] = callback; + return this.handlerKey(id); + }; + + Script.prototype.handlerKey = function(id) { + if (id == null) { + id = void 0; + } + if (id == null) { + id = this._nextCallbackId - 1; + } + return this.name + ".__handle_" + id; + }; + + return Script; + + })(); + +}).call(this); + +}).call(this,require('_process')) +},{"./console":4,"./control":5,"./util":8,"_process":12,"heterarchy":13,"path":11,"string":15,"underscore":16}],7:[function(require,module,exports){ +// Generated by CoffeeScript 1.10.0 +(function() { + var binaryT, centeredT, defaultT, identityT, linearT, momentaryT, + slice = [].slice; + + exports.identity = function(v) { + return v; + }; + + exports.identity.inverse = exports.identity; + + exports.momentary = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } + }; + + exports.momentary.inverse = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } + }; + + exports.binary = function(v, oldv) { + if (v > 0) { + return !oldv; + } else { + return null; + } + }; + + exports.binary.inverse = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } + }; + + exports.linear = function(v, min, max) { + return min + v * (max - min); + }; + + exports.linear.inverse = function(v, min, max) { + return (v - min) / (max - min); + }; + + exports.centered = function(v, min, center, max) { + if (v < .5) { + return linear(v * 2, min, center); + } else { + return linear((v - .5) * 2, center, max); + } + }; + + exports.centered.inverse = function(v, min, center, max) { + if (v < center) { + return 0.5 * linear.inverse(v, min, center); + } else { + return 0.5 + 0.5 * linear.inverse(v, center, max); + } + }; + + exports.transform = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.value / 127.0].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return 127 * f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; + }; + + exports.transformI = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.value].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; + }; + + exports.transformB = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.pressed / 127.0].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return 127 * f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; + }; + + exports.identityT = identityT = exports.transformI(exports.identity); + + exports.momentaryT = momentaryT = exports.transformB(exports.momentary); + + exports.binaryT = binaryT = exports.transformB(exports.binary); + + exports.linearT = linearT = function() { + return exports.transform.apply(exports, [exports.linear].concat(slice.call(arguments))); + }; + + exports.centeredT = centeredT = function() { + return exports.transform.apply(exports, [exports.centered].concat(slice.call(arguments))); + }; + + exports.defaultT = defaultT = linearT(0.0, 1.0); + + exports.mappings = { + "beatloop_0.0625_activate": momentaryT, + "beatloop_0.0625_toggle": momentaryT, + "beatloop_0.125_activate": momentaryT, + "beatloop_0.125_toggle": momentaryT, + "beatloop_0.5_activate": momentaryT, + "beatloop_0.5_toggle": momentaryT, + "beatlooproll_0.0625_activate": momentaryT, + "beatlooproll_0.125_activate": momentaryT, + "beatlooproll_0.5_activate": momentaryT, + back: momentaryT, + balance: linearT(-1.0, 1.0), + beatloop_16_activate: momentaryT, + beatloop_16_toggle: momentaryT, + beatloop_1_activate: momentaryT, + beatloop_1_toggle: momentaryT, + beatloop_2_activate: momentaryT, + beatloop_2_toggle: momentaryT, + beatloop_32_activate: momentaryT, + beatloop_32_toggle: momentaryT, + beatloop_4_activate: momentaryT, + beatloop_4_toggle: momentaryT, + beatloop_8_activate: momentaryT, + beatloop_8_toggle: momentaryT, + beatlooproll_16_activate: momentaryT, + beatlooproll_1_activate: momentaryT, + beatlooproll_2_activate: momentaryT, + beatlooproll_32_activate: momentaryT, + beatlooproll_4_activate: momentaryT, + beatlooproll_8_activate: momentaryT, + beatloop_double: momentaryT, + beatloop_halve: momentaryT, + beatjump_4_forward: momentaryT, + beatjump_4_backward: momentaryT, + beatjump_1_forward: momentaryT, + beatjump_1_backward: momentaryT, + beats_translate_curpos: momentaryT, + beatsync: momentaryT, + beatsync_tempo: momentaryT, + crossfader: linearT(-1.0, 1.0), + cue_default: momentaryT, + eject: momentaryT, + enabled: binaryT, + filterHigh: centeredT(0.0, 1.0, 4.0), + filterHighKill: binaryT, + filterLow: centeredT(0.0, 1.0, 4.0), + filterLowKill: binaryT, + filterMid: centeredT(0.0, 1.0, 4.0), + filterMidKill: binaryT, + fwd: momentaryT, + headMix: centeredT(-1.0, 1.0), + headVolume: centeredT(0.0, 1.0, 5.0), + hotcue_1_activate: momentaryT, + hotcue_1_clear: momentaryT, + hotcue_2_activate: momentaryT, + hotcue_2_clear: momentaryT, + hotcue_3_activate: momentaryT, + hotcue_3_clear: momentaryT, + hotcue_4_activate: momentaryT, + hotcue_4_clear: momentaryT, + hotcue_5_activate: momentaryT, + hotcue_5_clear: momentaryT, + hotcue_6_activate: momentaryT, + hotcue_6_clear: momentaryT, + hotcue_7_activate: momentaryT, + hotcue_7_clear: momentaryT, + jog: identityT, + keylock: binaryT, + lfoDelay: linearT(50.0, 10000.0), + lfoDepth: defaultT, + lfoPeriod: linearT(50000.0, 2000000.0), + LoadSelectedTrack: momentaryT, + loop_double: momentaryT, + loop_enabled: binaryT, + loop_end_position: linearT, + loop_halve: momentaryT, + loop_in: momentaryT, + loop_out: momentaryT, + loop_start_position: linearT, + play: binaryT, + playposition: linearT(0.0, 1.0), + plf: binaryT, + pregain: centeredT(0.0, 1.0, 4.0), + pregain_toggle: binaryT, + rate: linearT(-1.0, 1.0), + rate_temp_down: momentaryT, + rate_temp_down_small: momentaryT, + rate_temp_up: momentaryT, + rate_temp_up_small: momentaryT, + reverse: binaryT, + scratch2: linearT(-3.0, 3.0), + scratch2_enable: binaryT, + SelectNextPlaylist: momentaryT, + SelectNextTrack: momentaryT, + SelectPrevPlaylist: momentaryT, + SelectPrevTrack: momentaryT, + SelectTrackKnob: identityT, + slip_enabled: binaryT, + super1: linearT(0.0, 10.0), + talkover: binaryT, + ToggleSelectedSidebarItem: momentaryT, + volume: defaultT, + VuMeter: defaultT, + VuMeterL: defaultT, + VuMeterR: defaultT, + wheel: linearT(-3.0, 3.0) + }; + +}).call(this); + +},{}],8:[function(require,module,exports){ +// Generated by CoffeeScript 1.10.0 +(function() { + Function.prototype.property = function(prop, desc) { + if (desc instanceof Function) { + desc = { + get: desc + }; + } + return Object.defineProperty(this.prototype, prop, desc); + }; + + Number.prototype.clamp = function(min, max) { + return Math.min(Math.max(this, min), max); + }; + + Number.prototype.sign = function() { + if (this < 0) { + return -1; + } else { + return 1; + } + }; + + Array.prototype.equals = function(other) { + return this.length === other.length && this.every(function(elem, i) { + return elem === other[i]; + }); + }; + + exports.copy = function(a, b) { + var k, v; + if (b == null) { + b = {}; + } + for (k in a) { + v = a[k]; + b[k] = v; + } + return b; + }; + + exports.catching = function(f) { + return function() { + var err, error1; + try { + return f.apply(this, arguments); + } catch (error1) { + err = error1; + return console.log("ERROR: " + err); + } + }; + }; + + exports.assert = function(value, error) { + if (error == null) { + error = void 0; + } + if (!value) { + throw new Error(error != null ? error : "Assertion failed"); + } + }; + + exports.xmlEscape = function(str) { + var ref; + return (ref = str != null ? str.replace('&', '&').replace('"', '"').replace('>', '>').replace('<', '<') : void 0) != null ? ref : ''; + }; + + exports.indent = function(depth) { + return Array(depth * 4).join(" "); + }; + + exports.hexStr = function(number) { + return "0x" + (number.toString(16)); + }; + + exports.xmlTag = function(str, value, indent) { + if (indent == null) { + indent = 0; + } + if (value != null) { + return (exports.indent(indent)) + "<" + str + ">" + value + ""; + } else { + return ""; + } + }; + + exports.joinLn = function(lines) { + return lines.filter(function(x) { + return x; + }).join('\n'); + }; + + exports.factory = function(Klass) { + return function() { + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(Klass, arguments, function(){}); + }; + }; + +}).call(this); + +},{}],9:[function(require,module,exports){ +// Generated by CoffeeScript 1.10.0 +(function() { + var events, factory, util, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + slice = [].slice; + + events = require('events'); + + util = require('./util'); + + factory = util.factory; + + exports.Value = (function(superClass) { + extend(Value, superClass); + + function Value(arg) { + var initial; + initial = (arg != null ? arg : {}).initial; + Value.__super__.constructor.apply(this, arguments); + this.setMaxListeners(0); + if (initial != null) { + this.value = initial; + } + } + + Value.property('value', { + get: function() { + return this._value; + }, + set: function(newValue) { + return this.setValue(newValue); + } + }); + + Value.prototype.setValue = function(newValue) { + if (this._value !== newValue) { + this._value = newValue; + this.emit('value', newValue); + } + return this._value; + }; + + return Value; + + })(events.EventEmitter); + + exports.value = factory(exports.Value); + + exports.Const = (function() { + Const.prototype.value = void 0; + + function Const(initial) { + if (initial == null) { + initial = void 0; + } + this.value = initial; + } + + Const.prototype.on = function() {}; + + Const.prototype.addListener = function() {}; + + Const.prototype.removeListener = function() {}; + + Const.prototype.listeners = function() { + return []; + }; + + return Const; + + })(); + + exports["const"] = factory(exports.Const); + + exports.Reduce = (function(superClass) { + extend(Reduce, superClass); + + function Reduce() { + var i, len, reduced, reducer, ref, v; + reducer = arguments[0], reduced = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this.reducer = reducer; + this.reduced = reduced; + Reduce.__super__.constructor.call(this); + ref = this.reduced; + for (i = 0, len = ref.length; i < len; i++) { + v = ref[i]; + v.on('value', (function(_this) { + return function() { + return _this.update(); + }; + })(this)); + } + this.update(); + } + + Reduce.prototype.update = function() { + return this.value = this.reduced.reduce((function(_this) { + return function(a, b) { + return exports["const"](_this.reducer(a.value, b.value)); + }; + })(this)).value; + }; + + return Reduce; + + })(exports.Value); + + exports.reduce = factory(exports.Reduce); + + exports.and = function() { + return exports.reduce.apply(exports, [(function(a, b) { + return a && b; + })].concat(slice.call(arguments))); + }; + + exports.or = function() { + return exports.reduce.apply(exports, [(function(a, b) { + return a || b; + })].concat(slice.call(arguments))); + }; + + exports.Transform = (function(superClass) { + extend(Transform, superClass); + + function Transform(transformer, transformed) { + this.transformer = transformer; + this.transformed = transformed; + Transform.__super__.constructor.call(this); + this.transformed.on('value', (function(_this) { + return function() { + return _this.update(); + }; + })(this)); + this.update(); + } + + Transform.prototype.update = function() { + return this.value = this.transformer(this.transformed.value); + }; + + return Transform; + + })(exports.Value); + + exports.transform = factory(exports.Transform); + + exports.not = function() { + return exports.transform.apply(exports, [(function(a) { + return !a; + })].concat(slice.call(arguments))); + }; + +}).call(this); + +},{"./util":8,"events":10}],10:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +},{}],11:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// resolves . and .. elements in a path array with directory names there +// must be no slashes, empty elements, or device names (c:\) in the array +// (so also no leading and trailing slashes - it does not distinguish +// relative and absolute paths) +function normalizeArray(parts, allowAboveRoot) { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + + return parts; +} + +// Split a filename into [root, dir, basename, ext], unix version +// 'root' is just a slash, or nothing. +var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +var splitPath = function(filename) { + return splitPathRe.exec(filename).slice(1); +}; + +// path.resolve([from ...], to) +// posix version +exports.resolve = function() { + var resolvedPath = '', + resolvedAbsolute = false; + + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? arguments[i] : process.cwd(); + + // Skip empty and invalid entries + if (typeof path !== 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + continue; + } + + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path.charAt(0) === '/'; + } + + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + + // Normalize the path + resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { + return !!p; + }), !resolvedAbsolute).join('/'); + + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; +}; + +// path.normalize(path) +// posix version +exports.normalize = function(path) { + var isAbsolute = exports.isAbsolute(path), + trailingSlash = substr(path, -1) === '/'; + + // Normalize the path + path = normalizeArray(filter(path.split('/'), function(p) { + return !!p; + }), !isAbsolute).join('/'); + + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + + return (isAbsolute ? '/' : '') + path; +}; + +// posix version +exports.isAbsolute = function(path) { + return path.charAt(0) === '/'; +}; + +// posix version +exports.join = function() { + var paths = Array.prototype.slice.call(arguments, 0); + return exports.normalize(filter(paths, function(p, index) { + if (typeof p !== 'string') { + throw new TypeError('Arguments to path.join must be strings'); + } + return p; + }).join('/')); +}; + + +// path.relative(from, to) +// posix version +exports.relative = function(from, to) { + from = exports.resolve(from).substr(1); + to = exports.resolve(to).substr(1); + + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + + var end = arr.length - 1; + for (; end >= 0; end--) { + if (arr[end] !== '') break; + } + + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + + var fromParts = trim(from.split('/')); + var toParts = trim(to.split('/')); + + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + + return outputParts.join('/'); +}; + +exports.sep = '/'; +exports.delimiter = ':'; + +exports.dirname = function(path) { + var result = splitPath(path), + root = result[0], + dir = result[1]; + + if (!root && !dir) { + // No dirname whatsoever + return '.'; + } + + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.substr(0, dir.length - 1); + } + + return root + dir; +}; + + +exports.basename = function(path, ext) { + var f = splitPath(path)[2]; + // TODO: make this comparison case-insensitive on windows? + if (ext && f.substr(-1 * ext.length) === ext) { + f = f.substr(0, f.length - ext.length); + } + return f; +}; + + +exports.extname = function(path) { + return splitPath(path)[3]; +}; + +function filter (xs, f) { + if (xs.filter) return xs.filter(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (f(xs[i], i, xs)) res.push(xs[i]); + } + return res; +} + +// String.prototype.substr - negative index don't work in IE8 +var substr = 'ab'.substr(-1) === 'b' + ? function (str, start, len) { return str.substr(start, len) } + : function (str, start, len) { + if (start < 0) start = str.length + start; + return str.substr(start, len); + } +; + +}).call(this,require('_process')) +},{"_process":12}],12:[function(require,module,exports){ +// shim for using process in browser +var process = module.exports = {}; + +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. + +var cachedSetTimeout; +var cachedClearTimeout; + +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + +} +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],13:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.3 +(function() { + var assert, copyOwn, every, find, generate, head, hierarchy, inherited, isEmpty, isEqual, isJavaScriptClass, map, memoize, merge, mro, partial, ref, reject, reparent, some, tail, without, + slice = [].slice, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + + ref = require('underscore'), head = ref.head, tail = ref.tail, map = ref.map, find = ref.find, some = ref.some, without = ref.without, isEmpty = ref.isEmpty, every = ref.every, memoize = ref.memoize, reject = ref.reject, partial = ref.partial, isEqual = ref.isEqual; + + assert = function(value, error) { + if (error == null) { + error = void 0; + } + if (!value) { + throw new Error(error != null ? error : "Assertion failed"); + } + }; + + exports.multi = function() { + var bases; + bases = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return generate(merge(map(bases, mro).concat([bases]))); + }; + + generate = memoize(function(linearization) { + var next, result; + next = head(linearization); + if (isEqual(linearization, hierarchy(next))) { + return next; + } else { + return result = (function(superClass) { + var class1; + + extend(result, superClass); + + function result() { + return class1.apply(this, arguments); + } + + result.prototype.__mro__ = linearization; + + class1 = reparent(next, result, next.prototype.constructor); + + copyOwn(next, result); + + copyOwn(next.prototype, result.prototype, partial(reparent, next, result)); + + return result; + + })(generate(tail(linearization))); + } + }); + + copyOwn = function(from, to, project) { + var key, value; + if (project == null) { + project = function(x) { + return x; + }; + } + for (key in from) { + if (!hasProp.call(from, key)) continue; + value = from[key]; + if (!to.hasOwnProperty(key)) { + to[key] = project(value); + } + } + return to; + }; + + reparent = function(oldklass, newklass, value) { + var newsuper, oldsuper, superctor; + if (!(value instanceof Function)) { + return value; + } else if (value === oldklass.prototype.constructor && inherited(oldklass) === Object) { + superctor = inherited(newklass).prototype.constructor; + return function() { + superctor.apply(this, arguments); + return value.apply(this, arguments); + }; + } else { + newsuper = inherited(newklass).prototype; + oldsuper = oldklass.__super__; + return function() { + oldklass.__super__ = newsuper; + try { + return value.apply(this, arguments); + } finally { + oldklass.__super__ = oldsuper; + } + }; + } + }; + + merge = function(inputs) { + var next, results; + results = []; + while (!isEmpty(inputs)) { + next = find(map(inputs, head), function(candidate) { + return every(inputs, function(input) { + return indexOf.call(tail(input), candidate) < 0; + }); + }); + assert(next != null, "Inconsistent multiple inheritance"); + inputs = reject(map(inputs, function(lst) { + return without(lst, next); + }), isEmpty); + results.push(next); + } + return results; + }; + + isJavaScriptClass = function(cls) { + return cls === Array || cls === Boolean || cls === Date || cls === Error || cls === Function || cls === Number || cls === RegExp || cls === String || cls === Object; + }; + + exports.mro = mro = function(cls) { + var result; + if ((cls == null) || (cls.prototype == null)) { + return []; + } else if (!cls.prototype.hasOwnProperty('__mro__')) { + result = [cls].concat(mro(inherited(cls))); + if (!isJavaScriptClass(cls)) { + cls.prototype.__mro__ = result; + } + return result; + } else { + return cls.prototype.__mro__; + } + }; + + exports.inherited = inherited = function(cls) { + var ref1; + return (ref1 = Object.getPrototypeOf(cls.prototype)) != null ? ref1.constructor : void 0; + }; + + exports.hierarchy = hierarchy = function(cls) { + if (cls == null) { + return []; + } else { + return [cls].concat(hierarchy(inherited(cls))); + } + }; + + exports.isinstance = function() { + var classes, obj; + obj = arguments[0], classes = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.issubclass.apply(exports, [obj != null ? obj.constructor : void 0].concat(slice.call(classes))); + }; + + exports.issubclass = function() { + var classes, klass, linearization; + klass = arguments[0], classes = 2 <= arguments.length ? slice.call(arguments, 1) : []; + linearization = mro(klass); + return some(classes, function(cls) { + return indexOf.call(linearization, cls) >= 0; + }); + }; + +}).call(this); + +},{"underscore":16}],14:[function(require,module,exports){ +function count(self, substr) { + var count = 0 + var pos = self.indexOf(substr) + + while (pos >= 0) { + count += 1 + pos = self.indexOf(substr, pos + 1) + } + + return count +} + +module.exports = count +},{}],15:[function(require,module,exports){ +/* +string.js - Copyright (C) 2012-2014, JP Richardson +*/ + +!(function() { + "use strict"; + + var VERSION = '3.1.3'; + + var ENTITIES = {}; + + // from http://semplicewebsites.com/removing-accents-javascript + var latin_map={"Á":"A","Ă":"A","Ắ":"A","Ặ":"A","Ằ":"A","Ẳ":"A","Ẵ":"A","Ǎ":"A","Â":"A","Ấ":"A","Ậ":"A","Ầ":"A","Ẩ":"A","Ẫ":"A","Ä":"A","Ǟ":"A","Ȧ":"A","Ǡ":"A","Ạ":"A","Ȁ":"A","À":"A","Ả":"A","Ȃ":"A","Ā":"A","Ą":"A","Å":"A","Ǻ":"A","Ḁ":"A","Ⱥ":"A","Ã":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ḃ":"B","Ḅ":"B","Ɓ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ć":"C","Č":"C","Ç":"C","Ḉ":"C","Ĉ":"C","Ċ":"C","Ƈ":"C","Ȼ":"C","Ď":"D","Ḑ":"D","Ḓ":"D","Ḋ":"D","Ḍ":"D","Ɗ":"D","Ḏ":"D","Dz":"D","Dž":"D","Đ":"D","Ƌ":"D","DZ":"DZ","DŽ":"DZ","É":"E","Ĕ":"E","Ě":"E","Ȩ":"E","Ḝ":"E","Ê":"E","Ế":"E","Ệ":"E","Ề":"E","Ể":"E","Ễ":"E","Ḙ":"E","Ë":"E","Ė":"E","Ẹ":"E","Ȅ":"E","È":"E","Ẻ":"E","Ȇ":"E","Ē":"E","Ḗ":"E","Ḕ":"E","Ę":"E","Ɇ":"E","Ẽ":"E","Ḛ":"E","Ꝫ":"ET","Ḟ":"F","Ƒ":"F","Ǵ":"G","Ğ":"G","Ǧ":"G","Ģ":"G","Ĝ":"G","Ġ":"G","Ɠ":"G","Ḡ":"G","Ǥ":"G","Ḫ":"H","Ȟ":"H","Ḩ":"H","Ĥ":"H","Ⱨ":"H","Ḧ":"H","Ḣ":"H","Ḥ":"H","Ħ":"H","Í":"I","Ĭ":"I","Ǐ":"I","Î":"I","Ï":"I","Ḯ":"I","İ":"I","Ị":"I","Ȉ":"I","Ì":"I","Ỉ":"I","Ȋ":"I","Ī":"I","Į":"I","Ɨ":"I","Ĩ":"I","Ḭ":"I","Ꝺ":"D","Ꝼ":"F","Ᵹ":"G","Ꞃ":"R","Ꞅ":"S","Ꞇ":"T","Ꝭ":"IS","Ĵ":"J","Ɉ":"J","Ḱ":"K","Ǩ":"K","Ķ":"K","Ⱪ":"K","Ꝃ":"K","Ḳ":"K","Ƙ":"K","Ḵ":"K","Ꝁ":"K","Ꝅ":"K","Ĺ":"L","Ƚ":"L","Ľ":"L","Ļ":"L","Ḽ":"L","Ḷ":"L","Ḹ":"L","Ⱡ":"L","Ꝉ":"L","Ḻ":"L","Ŀ":"L","Ɫ":"L","Lj":"L","Ł":"L","LJ":"LJ","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ń":"N","Ň":"N","Ņ":"N","Ṋ":"N","Ṅ":"N","Ṇ":"N","Ǹ":"N","Ɲ":"N","Ṉ":"N","Ƞ":"N","Nj":"N","Ñ":"N","NJ":"NJ","Ó":"O","Ŏ":"O","Ǒ":"O","Ô":"O","Ố":"O","Ộ":"O","Ồ":"O","Ổ":"O","Ỗ":"O","Ö":"O","Ȫ":"O","Ȯ":"O","Ȱ":"O","Ọ":"O","Ő":"O","Ȍ":"O","Ò":"O","Ỏ":"O","Ơ":"O","Ớ":"O","Ợ":"O","Ờ":"O","Ở":"O","Ỡ":"O","Ȏ":"O","Ꝋ":"O","Ꝍ":"O","Ō":"O","Ṓ":"O","Ṑ":"O","Ɵ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Õ":"O","Ṍ":"O","Ṏ":"O","Ȭ":"O","Ƣ":"OI","Ꝏ":"OO","Ɛ":"E","Ɔ":"O","Ȣ":"OU","Ṕ":"P","Ṗ":"P","Ꝓ":"P","Ƥ":"P","Ꝕ":"P","Ᵽ":"P","Ꝑ":"P","Ꝙ":"Q","Ꝗ":"Q","Ŕ":"R","Ř":"R","Ŗ":"R","Ṙ":"R","Ṛ":"R","Ṝ":"R","Ȑ":"R","Ȓ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꜿ":"C","Ǝ":"E","Ś":"S","Ṥ":"S","Š":"S","Ṧ":"S","Ş":"S","Ŝ":"S","Ș":"S","Ṡ":"S","Ṣ":"S","Ṩ":"S","ẞ":"SS","Ť":"T","Ţ":"T","Ṱ":"T","Ț":"T","Ⱦ":"T","Ṫ":"T","Ṭ":"T","Ƭ":"T","Ṯ":"T","Ʈ":"T","Ŧ":"T","Ɐ":"A","Ꞁ":"L","Ɯ":"M","Ʌ":"V","Ꜩ":"TZ","Ú":"U","Ŭ":"U","Ǔ":"U","Û":"U","Ṷ":"U","Ü":"U","Ǘ":"U","Ǚ":"U","Ǜ":"U","Ǖ":"U","Ṳ":"U","Ụ":"U","Ű":"U","Ȕ":"U","Ù":"U","Ủ":"U","Ư":"U","Ứ":"U","Ự":"U","Ừ":"U","Ử":"U","Ữ":"U","Ȗ":"U","Ū":"U","Ṻ":"U","Ų":"U","Ů":"U","Ũ":"U","Ṹ":"U","Ṵ":"U","Ꝟ":"V","Ṿ":"V","Ʋ":"V","Ṽ":"V","Ꝡ":"VY","Ẃ":"W","Ŵ":"W","Ẅ":"W","Ẇ":"W","Ẉ":"W","Ẁ":"W","Ⱳ":"W","Ẍ":"X","Ẋ":"X","Ý":"Y","Ŷ":"Y","Ÿ":"Y","Ẏ":"Y","Ỵ":"Y","Ỳ":"Y","Ƴ":"Y","Ỷ":"Y","Ỿ":"Y","Ȳ":"Y","Ɏ":"Y","Ỹ":"Y","Ź":"Z","Ž":"Z","Ẑ":"Z","Ⱬ":"Z","Ż":"Z","Ẓ":"Z","Ȥ":"Z","Ẕ":"Z","Ƶ":"Z","IJ":"IJ","Œ":"OE","ᴀ":"A","ᴁ":"AE","ʙ":"B","ᴃ":"B","ᴄ":"C","ᴅ":"D","ᴇ":"E","ꜰ":"F","ɢ":"G","ʛ":"G","ʜ":"H","ɪ":"I","ʁ":"R","ᴊ":"J","ᴋ":"K","ʟ":"L","ᴌ":"L","ᴍ":"M","ɴ":"N","ᴏ":"O","ɶ":"OE","ᴐ":"O","ᴕ":"OU","ᴘ":"P","ʀ":"R","ᴎ":"N","ᴙ":"R","ꜱ":"S","ᴛ":"T","ⱻ":"E","ᴚ":"R","ᴜ":"U","ᴠ":"V","ᴡ":"W","ʏ":"Y","ᴢ":"Z","á":"a","ă":"a","ắ":"a","ặ":"a","ằ":"a","ẳ":"a","ẵ":"a","ǎ":"a","â":"a","ấ":"a","ậ":"a","ầ":"a","ẩ":"a","ẫ":"a","ä":"a","ǟ":"a","ȧ":"a","ǡ":"a","ạ":"a","ȁ":"a","à":"a","ả":"a","ȃ":"a","ā":"a","ą":"a","ᶏ":"a","ẚ":"a","å":"a","ǻ":"a","ḁ":"a","ⱥ":"a","ã":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ḃ":"b","ḅ":"b","ɓ":"b","ḇ":"b","ᵬ":"b","ᶀ":"b","ƀ":"b","ƃ":"b","ɵ":"o","ć":"c","č":"c","ç":"c","ḉ":"c","ĉ":"c","ɕ":"c","ċ":"c","ƈ":"c","ȼ":"c","ď":"d","ḑ":"d","ḓ":"d","ȡ":"d","ḋ":"d","ḍ":"d","ɗ":"d","ᶑ":"d","ḏ":"d","ᵭ":"d","ᶁ":"d","đ":"d","ɖ":"d","ƌ":"d","ı":"i","ȷ":"j","ɟ":"j","ʄ":"j","dz":"dz","dž":"dz","é":"e","ĕ":"e","ě":"e","ȩ":"e","ḝ":"e","ê":"e","ế":"e","ệ":"e","ề":"e","ể":"e","ễ":"e","ḙ":"e","ë":"e","ė":"e","ẹ":"e","ȅ":"e","è":"e","ẻ":"e","ȇ":"e","ē":"e","ḗ":"e","ḕ":"e","ⱸ":"e","ę":"e","ᶒ":"e","ɇ":"e","ẽ":"e","ḛ":"e","ꝫ":"et","ḟ":"f","ƒ":"f","ᵮ":"f","ᶂ":"f","ǵ":"g","ğ":"g","ǧ":"g","ģ":"g","ĝ":"g","ġ":"g","ɠ":"g","ḡ":"g","ᶃ":"g","ǥ":"g","ḫ":"h","ȟ":"h","ḩ":"h","ĥ":"h","ⱨ":"h","ḧ":"h","ḣ":"h","ḥ":"h","ɦ":"h","ẖ":"h","ħ":"h","ƕ":"hv","í":"i","ĭ":"i","ǐ":"i","î":"i","ï":"i","ḯ":"i","ị":"i","ȉ":"i","ì":"i","ỉ":"i","ȋ":"i","ī":"i","į":"i","ᶖ":"i","ɨ":"i","ĩ":"i","ḭ":"i","ꝺ":"d","ꝼ":"f","ᵹ":"g","ꞃ":"r","ꞅ":"s","ꞇ":"t","ꝭ":"is","ǰ":"j","ĵ":"j","ʝ":"j","ɉ":"j","ḱ":"k","ǩ":"k","ķ":"k","ⱪ":"k","ꝃ":"k","ḳ":"k","ƙ":"k","ḵ":"k","ᶄ":"k","ꝁ":"k","ꝅ":"k","ĺ":"l","ƚ":"l","ɬ":"l","ľ":"l","ļ":"l","ḽ":"l","ȴ":"l","ḷ":"l","ḹ":"l","ⱡ":"l","ꝉ":"l","ḻ":"l","ŀ":"l","ɫ":"l","ᶅ":"l","ɭ":"l","ł":"l","lj":"lj","ſ":"s","ẜ":"s","ẛ":"s","ẝ":"s","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ᵯ":"m","ᶆ":"m","ń":"n","ň":"n","ņ":"n","ṋ":"n","ȵ":"n","ṅ":"n","ṇ":"n","ǹ":"n","ɲ":"n","ṉ":"n","ƞ":"n","ᵰ":"n","ᶇ":"n","ɳ":"n","ñ":"n","nj":"nj","ó":"o","ŏ":"o","ǒ":"o","ô":"o","ố":"o","ộ":"o","ồ":"o","ổ":"o","ỗ":"o","ö":"o","ȫ":"o","ȯ":"o","ȱ":"o","ọ":"o","ő":"o","ȍ":"o","ò":"o","ỏ":"o","ơ":"o","ớ":"o","ợ":"o","ờ":"o","ở":"o","ỡ":"o","ȏ":"o","ꝋ":"o","ꝍ":"o","ⱺ":"o","ō":"o","ṓ":"o","ṑ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","õ":"o","ṍ":"o","ṏ":"o","ȭ":"o","ƣ":"oi","ꝏ":"oo","ɛ":"e","ᶓ":"e","ɔ":"o","ᶗ":"o","ȣ":"ou","ṕ":"p","ṗ":"p","ꝓ":"p","ƥ":"p","ᵱ":"p","ᶈ":"p","ꝕ":"p","ᵽ":"p","ꝑ":"p","ꝙ":"q","ʠ":"q","ɋ":"q","ꝗ":"q","ŕ":"r","ř":"r","ŗ":"r","ṙ":"r","ṛ":"r","ṝ":"r","ȑ":"r","ɾ":"r","ᵳ":"r","ȓ":"r","ṟ":"r","ɼ":"r","ᵲ":"r","ᶉ":"r","ɍ":"r","ɽ":"r","ↄ":"c","ꜿ":"c","ɘ":"e","ɿ":"r","ś":"s","ṥ":"s","š":"s","ṧ":"s","ş":"s","ŝ":"s","ș":"s","ṡ":"s","ṣ":"s","ṩ":"s","ʂ":"s","ᵴ":"s","ᶊ":"s","ȿ":"s","ɡ":"g","ß":"ss","ᴑ":"o","ᴓ":"o","ᴝ":"u","ť":"t","ţ":"t","ṱ":"t","ț":"t","ȶ":"t","ẗ":"t","ⱦ":"t","ṫ":"t","ṭ":"t","ƭ":"t","ṯ":"t","ᵵ":"t","ƫ":"t","ʈ":"t","ŧ":"t","ᵺ":"th","ɐ":"a","ᴂ":"ae","ǝ":"e","ᵷ":"g","ɥ":"h","ʮ":"h","ʯ":"h","ᴉ":"i","ʞ":"k","ꞁ":"l","ɯ":"m","ɰ":"m","ᴔ":"oe","ɹ":"r","ɻ":"r","ɺ":"r","ⱹ":"r","ʇ":"t","ʌ":"v","ʍ":"w","ʎ":"y","ꜩ":"tz","ú":"u","ŭ":"u","ǔ":"u","û":"u","ṷ":"u","ü":"u","ǘ":"u","ǚ":"u","ǜ":"u","ǖ":"u","ṳ":"u","ụ":"u","ű":"u","ȕ":"u","ù":"u","ủ":"u","ư":"u","ứ":"u","ự":"u","ừ":"u","ử":"u","ữ":"u","ȗ":"u","ū":"u","ṻ":"u","ų":"u","ᶙ":"u","ů":"u","ũ":"u","ṹ":"u","ṵ":"u","ᵫ":"ue","ꝸ":"um","ⱴ":"v","ꝟ":"v","ṿ":"v","ʋ":"v","ᶌ":"v","ⱱ":"v","ṽ":"v","ꝡ":"vy","ẃ":"w","ŵ":"w","ẅ":"w","ẇ":"w","ẉ":"w","ẁ":"w","ⱳ":"w","ẘ":"w","ẍ":"x","ẋ":"x","ᶍ":"x","ý":"y","ŷ":"y","ÿ":"y","ẏ":"y","ỵ":"y","ỳ":"y","ƴ":"y","ỷ":"y","ỿ":"y","ȳ":"y","ẙ":"y","ɏ":"y","ỹ":"y","ź":"z","ž":"z","ẑ":"z","ʑ":"z","ⱬ":"z","ż":"z","ẓ":"z","ȥ":"z","ẕ":"z","ᵶ":"z","ᶎ":"z","ʐ":"z","ƶ":"z","ɀ":"z","ff":"ff","ffi":"ffi","ffl":"ffl","fi":"fi","fl":"fl","ij":"ij","œ":"oe","st":"st","ₐ":"a","ₑ":"e","ᵢ":"i","ⱼ":"j","ₒ":"o","ᵣ":"r","ᵤ":"u","ᵥ":"v","ₓ":"x"}; + +//****************************************************************************** +// Added an initialize function which is essentially the code from the S +// constructor. Now, the S constructor calls this and a new method named +// setValue calls it as well. The setValue function allows constructors for +// modules that extend string.js to set the initial value of an object without +// knowing the internal workings of string.js. +// +// Also, all methods which return a new S object now call: +// +// return new this.constructor(s); +// +// instead of: +// +// return new S(s); +// +// This allows extended objects to keep their proper instanceOf and constructor. +//****************************************************************************** + + function initialize (object, s) { + if (s !== null && s !== undefined) { + if (typeof s === 'string') + object.s = s; + else + object.s = s.toString(); + } else { + object.s = s; //null or undefined + } + + object.orig = s; //original object, currently only used by toCSV() and toBoolean() + + if (s !== null && s !== undefined) { + if (object.__defineGetter__) { + object.__defineGetter__('length', function() { + return object.s.length; + }) + } else { + object.length = s.length; + } + } else { + object.length = -1; + } + } + + function S(s) { + initialize(this, s); + } + + var __nsp = String.prototype; + var __sp = S.prototype = { + + between: function(left, right) { + var s = this.s; + var startPos = s.indexOf(left); + var endPos = s.indexOf(right, startPos + left.length); + if (endPos == -1 && right != null) + return new this.constructor('') + else if (endPos == -1 && right == null) + return new this.constructor(s.substring(startPos + left.length)) + else + return new this.constructor(s.slice(startPos + left.length, endPos)); + }, + + //# modified slightly from https://github.com/epeli/underscore.string + camelize: function() { + var s = this.trim().s.replace(/(\-|_|\s)+(.)?/g, function(mathc, sep, c) { + return (c ? c.toUpperCase() : ''); + }); + return new this.constructor(s); + }, + + capitalize: function() { + return new this.constructor(this.s.substr(0, 1).toUpperCase() + this.s.substring(1).toLowerCase()); + }, + + charAt: function(index) { + return this.s.charAt(index); + }, + + chompLeft: function(prefix) { + var s = this.s; + if (s.indexOf(prefix) === 0) { + s = s.slice(prefix.length); + return new this.constructor(s); + } else { + return this; + } + }, + + chompRight: function(suffix) { + if (this.endsWith(suffix)) { + var s = this.s; + s = s.slice(0, s.length - suffix.length); + return new this.constructor(s); + } else { + return this; + } + }, + + //#thanks Google + collapseWhitespace: function() { + var s = this.s.replace(/[\s\xa0]+/g, ' ').replace(/^\s+|\s+$/g, ''); + return new this.constructor(s); + }, + + contains: function(ss) { + return this.s.indexOf(ss) >= 0; + }, + + count: function(ss) { + return require('./_count')(this.s, ss) + }, + + //#modified from https://github.com/epeli/underscore.string + dasherize: function() { + var s = this.trim().s.replace(/[_\s]+/g, '-').replace(/([A-Z])/g, '-$1').replace(/-+/g, '-').toLowerCase(); + return new this.constructor(s); + }, + + latinise: function() { + var s = this.replace(/[^A-Za-z0-9\[\] ]/g, function(x) { return latin_map[x] || x; }); + return new this.constructor(s); + }, + + decodeHtmlEntities: function() { //https://github.com/substack/node-ent/blob/master/index.js + var s = this.s; + s = s.replace(/&#(\d+);?/g, function (_, code) { + return String.fromCharCode(code); + }) + .replace(/&#[xX]([A-Fa-f0-9]+);?/g, function (_, hex) { + return String.fromCharCode(parseInt(hex, 16)); + }) + .replace(/&([^;\W]+;?)/g, function (m, e) { + var ee = e.replace(/;$/, ''); + var target = ENTITIES[e] || (e.match(/;$/) && ENTITIES[ee]); + + if (typeof target === 'number') { + return String.fromCharCode(target); + } + else if (typeof target === 'string') { + return target; + } + else { + return m; + } + }) + + return new this.constructor(s); + }, + + endsWith: function() { + var suffixes = Array.prototype.slice.call(arguments, 0); + for (var i = 0; i < suffixes.length; ++i) { + var l = this.s.length - suffixes[i].length; + if (l >= 0 && this.s.indexOf(suffixes[i], l) === l) return true; + } + return false; + }, + + escapeHTML: function() { //from underscore.string + return new this.constructor(this.s.replace(/[&<>"']/g, function(m){ return '&' + reversedEscapeChars[m] + ';'; })); + }, + + ensureLeft: function(prefix) { + var s = this.s; + if (s.indexOf(prefix) === 0) { + return this; + } else { + return new this.constructor(prefix + s); + } + }, + + ensureRight: function(suffix) { + var s = this.s; + if (this.endsWith(suffix)) { + return this; + } else { + return new this.constructor(s + suffix); + } + }, + + humanize: function() { //modified from underscore.string + if (this.s === null || this.s === undefined) + return new this.constructor('') + var s = this.underscore().replace(/_id$/,'').replace(/_/g, ' ').trim().capitalize() + return new this.constructor(s) + }, + + isAlpha: function() { + return !/[^a-z\xDF-\xFF]|^$/.test(this.s.toLowerCase()); + }, + + isAlphaNumeric: function() { + return !/[^0-9a-z\xDF-\xFF]/.test(this.s.toLowerCase()); + }, + + isEmpty: function() { + return this.s === null || this.s === undefined ? true : /^[\s\xa0]*$/.test(this.s); + }, + + isLower: function() { + return this.isAlpha() && this.s.toLowerCase() === this.s; + }, + + isNumeric: function() { + return !/[^0-9]/.test(this.s); + }, + + isUpper: function() { + return this.isAlpha() && this.s.toUpperCase() === this.s; + }, + + left: function(N) { + if (N >= 0) { + var s = this.s.substr(0, N); + return new this.constructor(s); + } else { + return this.right(-N); + } + }, + + lines: function() { //convert windows newlines to unix newlines then convert to an Array of lines + return this.replaceAll('\r\n', '\n').s.split('\n'); + }, + + pad: function(len, ch) { //https://github.com/component/pad + if (ch == null) ch = ' '; + if (this.s.length >= len) return new this.constructor(this.s); + len = len - this.s.length; + var left = Array(Math.ceil(len / 2) + 1).join(ch); + var right = Array(Math.floor(len / 2) + 1).join(ch); + return new this.constructor(left + this.s + right); + }, + + padLeft: function(len, ch) { //https://github.com/component/pad + if (ch == null) ch = ' '; + if (this.s.length >= len) return new this.constructor(this.s); + return new this.constructor(Array(len - this.s.length + 1).join(ch) + this.s); + }, + + padRight: function(len, ch) { //https://github.com/component/pad + if (ch == null) ch = ' '; + if (this.s.length >= len) return new this.constructor(this.s); + return new this.constructor(this.s + Array(len - this.s.length + 1).join(ch)); + }, + + parseCSV: function(delimiter, qualifier, escape, lineDelimiter) { //try to parse no matter what + delimiter = delimiter || ','; + escape = escape || '\\' + if (typeof qualifier == 'undefined') + qualifier = '"'; + + var i = 0, fieldBuffer = [], fields = [], len = this.s.length, inField = false, inUnqualifiedString = false, self = this; + var ca = function(i){return self.s.charAt(i)}; + if (typeof lineDelimiter !== 'undefined') var rows = []; + + if (!qualifier) + inField = true; + + while (i < len) { + var current = ca(i); + switch (current) { + case escape: + //fix for issues #32 and #35 + if (inField && ((escape !== qualifier) || ca(i+1) === qualifier)) { + i += 1; + fieldBuffer.push(ca(i)); + break; + } + if (escape !== qualifier) break; + case qualifier: + inField = !inField; + break; + case delimiter: + if(inUnqualifiedString) { + inField=false; + inUnqualifiedString=false; + } + if (inField && qualifier) + fieldBuffer.push(current); + else { + fields.push(fieldBuffer.join('')) + fieldBuffer.length = 0; + } + break; + case lineDelimiter: + if(inUnqualifiedString) { + inField=false; + inUnqualifiedString=false; + fields.push(fieldBuffer.join('')) + rows.push(fields); + fields = []; + fieldBuffer.length = 0; + } + else if (inField) { + fieldBuffer.push(current); + } else { + if (rows) { + fields.push(fieldBuffer.join('')) + rows.push(fields); + fields = []; + fieldBuffer.length = 0; + } + } + break; + case ' ': + if (inField) + fieldBuffer.push(current); + break; + default: + if (inField) + fieldBuffer.push(current); + else if(current!==qualifier) { + fieldBuffer.push(current); + inField=true; + inUnqualifiedString=true; + } + break; + } + i += 1; + } + + fields.push(fieldBuffer.join('')); + if (rows) { + rows.push(fields); + return rows; + } + return fields; + }, + + replaceAll: function(ss, r) { + //var s = this.s.replace(new RegExp(ss, 'g'), r); + var s = this.s.split(ss).join(r) + return new this.constructor(s); + }, + + strip: function() { + var ss = this.s; + for(var i= 0, n=arguments.length; i= 0) { + var s = this.s.substr(this.s.length - N, N); + return new this.constructor(s); + } else { + return this.left(-N); + } + }, + + setValue: function (s) { + initialize(this, s); + return this; + }, + + slugify: function() { + var sl = (new S(new S(this.s).latinise().s.replace(/[^\w\s-]/g, '').toLowerCase())).dasherize().s; + if (sl.charAt(0) === '-') + sl = sl.substr(1); + return new this.constructor(sl); + }, + + startsWith: function() { + var prefixes = Array.prototype.slice.call(arguments, 0); + for (var i = 0; i < prefixes.length; ++i) { + if (this.s.lastIndexOf(prefixes[i], 0) === 0) return true; + } + return false; + }, + + stripPunctuation: function() { + //return new this.constructor(this.s.replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()]/g,"")); + return new this.constructor(this.s.replace(/[^\w\s]|_/g, "").replace(/\s+/g, " ")); + }, + + stripTags: function() { //from sugar.js + var s = this.s, args = arguments.length > 0 ? arguments : ['']; + multiArgs(args, function(tag) { + s = s.replace(RegExp('<\/?' + tag + '[^<>]*>', 'gi'), ''); + }); + return new this.constructor(s); + }, + + template: function(values, opening, closing) { + var s = this.s + var opening = opening || Export.TMPL_OPEN + var closing = closing || Export.TMPL_CLOSE + + var open = opening.replace(/[-[\]()*\s]/g, "\\$&").replace(/\$/g, '\\$') + var close = closing.replace(/[-[\]()*\s]/g, "\\$&").replace(/\$/g, '\\$') + var r = new RegExp(open + '(.+?)' + close, 'g') + //, r = /\{\{(.+?)\}\}/g + var matches = s.match(r) || []; + + matches.forEach(function(match) { + var key = match.substring(opening.length, match.length - closing.length).trim();//chop {{ and }} + var value = typeof values[key] == 'undefined' ? '' : values[key]; + s = s.replace(match, value); + }); + return new this.constructor(s); + }, + + times: function(n) { + return new this.constructor(new Array(n + 1).join(this.s)); + }, + + toBoolean: function() { + if (typeof this.orig === 'string') { + var s = this.s.toLowerCase(); + return s === 'true' || s === 'yes' || s === 'on' || s === '1'; + } else + return this.orig === true || this.orig === 1; + }, + + toFloat: function(precision) { + var num = parseFloat(this.s) + if (precision) + return parseFloat(num.toFixed(precision)) + else + return num + }, + + toInt: function() { //thanks Google + // If the string starts with '0x' or '-0x', parse as hex. + return /^\s*-?0x/i.test(this.s) ? parseInt(this.s, 16) : parseInt(this.s, 10) + }, + + trim: function() { + var s; + if (typeof __nsp.trim === 'undefined') + s = this.s.replace(/(^\s*|\s*$)/g, '') + else + s = this.s.trim() + return new this.constructor(s); + }, + + trimLeft: function() { + var s; + if (__nsp.trimLeft) + s = this.s.trimLeft(); + else + s = this.s.replace(/(^\s*)/g, ''); + return new this.constructor(s); + }, + + trimRight: function() { + var s; + if (__nsp.trimRight) + s = this.s.trimRight(); + else + s = this.s.replace(/\s+$/, ''); + return new this.constructor(s); + }, + + truncate: function(length, pruneStr) { //from underscore.string, author: github.com/rwz + var str = this.s; + + length = ~~length; + pruneStr = pruneStr || '...'; + + if (str.length <= length) return new this.constructor(str); + + var tmpl = function(c){ return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' '; }, + template = str.slice(0, length+1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA' + + if (template.slice(template.length-2).match(/\w\w/)) + template = template.replace(/\s*\S+$/, ''); + else + template = new S(template.slice(0, template.length-1)).trimRight().s; + + return (template+pruneStr).length > str.length ? new S(str) : new S(str.slice(0, template.length)+pruneStr); + }, + + toCSV: function() { + var delim = ',', qualifier = '"', escape = '\\', encloseNumbers = true, keys = false; + var dataArray = []; + + function hasVal(it) { + return it !== null && it !== ''; + } + + if (typeof arguments[0] === 'object') { + delim = arguments[0].delimiter || delim; + delim = arguments[0].separator || delim; + qualifier = arguments[0].qualifier || qualifier; + encloseNumbers = !!arguments[0].encloseNumbers; + escape = arguments[0].escape || escape; + keys = !!arguments[0].keys; + } else if (typeof arguments[0] === 'string') { + delim = arguments[0]; + } + + if (typeof arguments[1] === 'string') + qualifier = arguments[1]; + + if (arguments[1] === null) + qualifier = null; + + if (this.orig instanceof Array) + dataArray = this.orig; + else { //object + for (var key in this.orig) + if (this.orig.hasOwnProperty(key)) + if (keys) + dataArray.push(key); + else + dataArray.push(this.orig[key]); + } + + var rep = escape + qualifier; + var buildString = []; + for (var i = 0; i < dataArray.length; ++i) { + var shouldQualify = hasVal(qualifier) + if (typeof dataArray[i] == 'number') + shouldQualify &= encloseNumbers; + + if (shouldQualify) + buildString.push(qualifier); + + if (dataArray[i] !== null && dataArray[i] !== undefined) { + var d = new S(dataArray[i]).replaceAll(qualifier, rep).s; + buildString.push(d); + } else + buildString.push('') + + if (shouldQualify) + buildString.push(qualifier); + + if (delim) + buildString.push(delim); + } + + //chop last delim + //console.log(buildString.length) + buildString.length = buildString.length - 1; + return new this.constructor(buildString.join('')); + }, + + toString: function() { + return this.s; + }, + + //#modified from https://github.com/epeli/underscore.string + underscore: function() { + var s = this.trim().s.replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/([A-Z\d]+)([A-Z][a-z])/,'$1_$2').replace(/[-\s]+/g, '_').toLowerCase(); + return new this.constructor(s); + }, + + unescapeHTML: function() { //from underscore.string + return new this.constructor(this.s.replace(/\&([^;]+);/g, function(entity, entityCode){ + var match; + + if (entityCode in escapeChars) { + return escapeChars[entityCode]; + } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) { + return String.fromCharCode(parseInt(match[1], 16)); + } else if (match = entityCode.match(/^#(\d+)$/)) { + return String.fromCharCode(~~match[1]); + } else { + return entity; + } + })); + }, + + valueOf: function() { + return this.s.valueOf(); + }, + + //#Added a New Function called wrapHTML. + wrapHTML: function (tagName, tagAttrs) { + var s = this.s, el = (tagName == null) ? 'span' : tagName, elAttr = '', wrapped = ''; + if(typeof tagAttrs == 'object') for(var prop in tagAttrs) elAttr += ' ' + prop + '="' +(new this.constructor(tagAttrs[prop])).escapeHTML() + '"'; + s = wrapped.concat('<', el, elAttr, '>', this, ''); + return new this.constructor(s); + } + } + + var methodsAdded = []; + function extendPrototype() { + for (var name in __sp) { + (function(name){ + var func = __sp[name]; + if (!__nsp.hasOwnProperty(name)) { + methodsAdded.push(name); + __nsp[name] = function() { + String.prototype.s = this; + return func.apply(this, arguments); + } + } + })(name); + } + } + + function restorePrototype() { + for (var i = 0; i < methodsAdded.length; ++i) + delete String.prototype[methodsAdded[i]]; + methodsAdded.length = 0; + } + + +/************************************* +/* Attach Native JavaScript String Properties +/*************************************/ + + var nativeProperties = getNativeStringProperties(); + for (var name in nativeProperties) { + (function(name) { + var stringProp = __nsp[name]; + if (typeof stringProp == 'function') { + //console.log(stringProp) + if (!__sp[name]) { + if (nativeProperties[name] === 'string') { + __sp[name] = function() { + //console.log(name) + return new this.constructor(stringProp.apply(this, arguments)); + } + } else { + __sp[name] = stringProp; + } + } + } + })(name); + } + + +/************************************* +/* Function Aliases +/*************************************/ + + __sp.repeat = __sp.times; + __sp.include = __sp.contains; + __sp.toInteger = __sp.toInt; + __sp.toBool = __sp.toBoolean; + __sp.decodeHTMLEntities = __sp.decodeHtmlEntities //ensure consistent casing scheme of 'HTML' + + +//****************************************************************************** +// Set the constructor. Without this, string.js objects are instances of +// Object instead of S. +//****************************************************************************** + + __sp.constructor = S; + + +/************************************* +/* Private Functions +/*************************************/ + + function getNativeStringProperties() { + var names = getNativeStringPropertyNames(); + var retObj = {}; + + for (var i = 0; i < names.length; ++i) { + var name = names[i]; + var func = __nsp[name]; + try { + // #127: pass extra parameter to keep shelljs happy + var type = typeof func.apply('test', ['string']); + retObj[name] = type; + } catch (e) {} + } + return retObj; + } + + function getNativeStringPropertyNames() { + var results = []; + if (Object.getOwnPropertyNames) { + results = Object.getOwnPropertyNames(__nsp); + results.splice(results.indexOf('valueOf'), 1); + results.splice(results.indexOf('toString'), 1); + return results; + } else { //meant for legacy cruft, this could probably be made more efficient + var stringNames = {}; + var objectNames = []; + for (var name in String.prototype) + stringNames[name] = name; + + for (var name in Object.prototype) + delete stringNames[name]; + + //stringNames['toString'] = 'toString'; //this was deleted with the rest of the object names + for (var name in stringNames) { + results.push(name); + } + return results; + } + } + + function Export(str) { + return new S(str); + }; + + //attach exports to StringJSWrapper + Export.extendPrototype = extendPrototype; + Export.restorePrototype = restorePrototype; + Export.VERSION = VERSION; + Export.TMPL_OPEN = '{{'; + Export.TMPL_CLOSE = '}}'; + Export.ENTITIES = ENTITIES; + + + +/************************************* +/* Exports +/*************************************/ + + if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { + module.exports = Export; + + } else { + + if(typeof define === "function" && define.amd) { + define([], function() { + return Export; + }); + } else { + window.S = Export; + } + } + + +/************************************* +/* 3rd Party Private Functions +/*************************************/ + + //from sugar.js + function multiArgs(args, fn) { + var result = [], i; + for(i = 0; i < args.length; i++) { + result.push(args[i]); + if(fn) fn.call(args, args[i], i); + } + return result; + } + + //from underscore.string + var escapeChars = { + lt: '<', + gt: '>', + quot: '"', + apos: "'", + amp: '&' + }; + + function escapeRegExp (s) { + // most part from https://github.com/skulpt/skulpt/blob/ecaf75e69c2e539eff124b2ab45df0b01eaf2295/src/str.js#L242 + var c; + var i; + var ret = []; + var re = /^[A-Za-z0-9]+$/; + s = ensureString(s); + for (i = 0; i < s.length; ++i) { + c = s.charAt(i); + + if (re.test(c)) { + ret.push(c); + } + else { + if (c === "\\000") { + ret.push("\\000"); + } + else { + ret.push("\\" + c); + } + } + } + return ret.join(""); + } + + function ensureString(string) { + return string == null ? '' : '' + string; + } + + //from underscore.string + var reversedEscapeChars = {}; + for(var key in escapeChars){ reversedEscapeChars[escapeChars[key]] = key; } + + ENTITIES = { + "amp" : "&", + "gt" : ">", + "lt" : "<", + "quot" : "\"", + "apos" : "'", + "AElig" : 198, + "Aacute" : 193, + "Acirc" : 194, + "Agrave" : 192, + "Aring" : 197, + "Atilde" : 195, + "Auml" : 196, + "Ccedil" : 199, + "ETH" : 208, + "Eacute" : 201, + "Ecirc" : 202, + "Egrave" : 200, + "Euml" : 203, + "Iacute" : 205, + "Icirc" : 206, + "Igrave" : 204, + "Iuml" : 207, + "Ntilde" : 209, + "Oacute" : 211, + "Ocirc" : 212, + "Ograve" : 210, + "Oslash" : 216, + "Otilde" : 213, + "Ouml" : 214, + "THORN" : 222, + "Uacute" : 218, + "Ucirc" : 219, + "Ugrave" : 217, + "Uuml" : 220, + "Yacute" : 221, + "aacute" : 225, + "acirc" : 226, + "aelig" : 230, + "agrave" : 224, + "aring" : 229, + "atilde" : 227, + "auml" : 228, + "ccedil" : 231, + "eacute" : 233, + "ecirc" : 234, + "egrave" : 232, + "eth" : 240, + "euml" : 235, + "iacute" : 237, + "icirc" : 238, + "igrave" : 236, + "iuml" : 239, + "ntilde" : 241, + "oacute" : 243, + "ocirc" : 244, + "ograve" : 242, + "oslash" : 248, + "otilde" : 245, + "ouml" : 246, + "szlig" : 223, + "thorn" : 254, + "uacute" : 250, + "ucirc" : 251, + "ugrave" : 249, + "uuml" : 252, + "yacute" : 253, + "yuml" : 255, + "copy" : 169, + "reg" : 174, + "nbsp" : 160, + "iexcl" : 161, + "cent" : 162, + "pound" : 163, + "curren" : 164, + "yen" : 165, + "brvbar" : 166, + "sect" : 167, + "uml" : 168, + "ordf" : 170, + "laquo" : 171, + "not" : 172, + "shy" : 173, + "macr" : 175, + "deg" : 176, + "plusmn" : 177, + "sup1" : 185, + "sup2" : 178, + "sup3" : 179, + "acute" : 180, + "micro" : 181, + "para" : 182, + "middot" : 183, + "cedil" : 184, + "ordm" : 186, + "raquo" : 187, + "frac14" : 188, + "frac12" : 189, + "frac34" : 190, + "iquest" : 191, + "times" : 215, + "divide" : 247, + "OElig;" : 338, + "oelig;" : 339, + "Scaron;" : 352, + "scaron;" : 353, + "Yuml;" : 376, + "fnof;" : 402, + "circ;" : 710, + "tilde;" : 732, + "Alpha;" : 913, + "Beta;" : 914, + "Gamma;" : 915, + "Delta;" : 916, + "Epsilon;" : 917, + "Zeta;" : 918, + "Eta;" : 919, + "Theta;" : 920, + "Iota;" : 921, + "Kappa;" : 922, + "Lambda;" : 923, + "Mu;" : 924, + "Nu;" : 925, + "Xi;" : 926, + "Omicron;" : 927, + "Pi;" : 928, + "Rho;" : 929, + "Sigma;" : 931, + "Tau;" : 932, + "Upsilon;" : 933, + "Phi;" : 934, + "Chi;" : 935, + "Psi;" : 936, + "Omega;" : 937, + "alpha;" : 945, + "beta;" : 946, + "gamma;" : 947, + "delta;" : 948, + "epsilon;" : 949, + "zeta;" : 950, + "eta;" : 951, + "theta;" : 952, + "iota;" : 953, + "kappa;" : 954, + "lambda;" : 955, + "mu;" : 956, + "nu;" : 957, + "xi;" : 958, + "omicron;" : 959, + "pi;" : 960, + "rho;" : 961, + "sigmaf;" : 962, + "sigma;" : 963, + "tau;" : 964, + "upsilon;" : 965, + "phi;" : 966, + "chi;" : 967, + "psi;" : 968, + "omega;" : 969, + "thetasym;" : 977, + "upsih;" : 978, + "piv;" : 982, + "ensp;" : 8194, + "emsp;" : 8195, + "thinsp;" : 8201, + "zwnj;" : 8204, + "zwj;" : 8205, + "lrm;" : 8206, + "rlm;" : 8207, + "ndash;" : 8211, + "mdash;" : 8212, + "lsquo;" : 8216, + "rsquo;" : 8217, + "sbquo;" : 8218, + "ldquo;" : 8220, + "rdquo;" : 8221, + "bdquo;" : 8222, + "dagger;" : 8224, + "Dagger;" : 8225, + "bull;" : 8226, + "hellip;" : 8230, + "permil;" : 8240, + "prime;" : 8242, + "Prime;" : 8243, + "lsaquo;" : 8249, + "rsaquo;" : 8250, + "oline;" : 8254, + "frasl;" : 8260, + "euro;" : 8364, + "image;" : 8465, + "weierp;" : 8472, + "real;" : 8476, + "trade;" : 8482, + "alefsym;" : 8501, + "larr;" : 8592, + "uarr;" : 8593, + "rarr;" : 8594, + "darr;" : 8595, + "harr;" : 8596, + "crarr;" : 8629, + "lArr;" : 8656, + "uArr;" : 8657, + "rArr;" : 8658, + "dArr;" : 8659, + "hArr;" : 8660, + "forall;" : 8704, + "part;" : 8706, + "exist;" : 8707, + "empty;" : 8709, + "nabla;" : 8711, + "isin;" : 8712, + "notin;" : 8713, + "ni;" : 8715, + "prod;" : 8719, + "sum;" : 8721, + "minus;" : 8722, + "lowast;" : 8727, + "radic;" : 8730, + "prop;" : 8733, + "infin;" : 8734, + "ang;" : 8736, + "and;" : 8743, + "or;" : 8744, + "cap;" : 8745, + "cup;" : 8746, + "int;" : 8747, + "there4;" : 8756, + "sim;" : 8764, + "cong;" : 8773, + "asymp;" : 8776, + "ne;" : 8800, + "equiv;" : 8801, + "le;" : 8804, + "ge;" : 8805, + "sub;" : 8834, + "sup;" : 8835, + "nsub;" : 8836, + "sube;" : 8838, + "supe;" : 8839, + "oplus;" : 8853, + "otimes;" : 8855, + "perp;" : 8869, + "sdot;" : 8901, + "lceil;" : 8968, + "rceil;" : 8969, + "lfloor;" : 8970, + "rfloor;" : 8971, + "lang;" : 9001, + "rang;" : 9002, + "loz;" : 9674, + "spades;" : 9824, + "clubs;" : 9827, + "hearts;" : 9829, + "diams;" : 9830 + } + + +}).call(this); + +},{"./_count":14}],16:[function(require,module,exports){ +// Underscore.js 1.8.3 +// http://underscorejs.org +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `exports` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var + push = ArrayProto.push, + slice = ArrayProto.slice, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind, + nativeCreate = Object.create; + + // Naked function reference for surrogate-prototype-swapping. + var Ctor = function(){}; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.8.3'; + + // Internal function that returns an efficient (for current engines) version + // of the passed-in callback, to be repeatedly applied in other Underscore + // functions. + var optimizeCb = function(func, context, argCount) { + if (context === void 0) return func; + switch (argCount == null ? 3 : argCount) { + case 1: return function(value) { + return func.call(context, value); + }; + case 2: return function(value, other) { + return func.call(context, value, other); + }; + case 3: return function(value, index, collection) { + return func.call(context, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(context, accumulator, value, index, collection); + }; + } + return function() { + return func.apply(context, arguments); + }; + }; + + // A mostly-internal function to generate callbacks that can be applied + // to each element in a collection, returning the desired result — either + // identity, an arbitrary callback, a property matcher, or a property accessor. + var cb = function(value, context, argCount) { + if (value == null) return _.identity; + if (_.isFunction(value)) return optimizeCb(value, context, argCount); + if (_.isObject(value)) return _.matcher(value); + return _.property(value); + }; + _.iteratee = function(value, context) { + return cb(value, context, Infinity); + }; + + // An internal function for creating assigner functions. + var createAssigner = function(keysFunc, undefinedOnly) { + return function(obj) { + var length = arguments.length; + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; + } + } + return obj; + }; + }; + + // An internal function for creating a new object that inherits from another. + var baseCreate = function(prototype) { + if (!_.isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + }; + + var property = function(key) { + return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + }; + + // Helper for collection methods to determine whether a collection + // should be iterated as an array or as an object + // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + var getLength = property('length'); + var isArrayLike = function(collection) { + var length = getLength(collection); + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + }; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles raw objects in addition to array-likes. Treats all + // sparse array-likes as if they were dense. + _.each = _.forEach = function(obj, iteratee, context) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { + iteratee(obj[i], i, obj); + } + } else { + var keys = _.keys(obj); + for (i = 0, length = keys.length; i < length; i++) { + iteratee(obj[keys[i]], keys[i], obj); + } + } + return obj; + }; + + // Return the results of applying the iteratee to each element. + _.map = _.collect = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + results = Array(length); + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + results[index] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Create a reducing function iterating left or right. + function createReduce(dir) { + // Optimized iterator function as using arguments.length + // in the main function will deoptimize the, see #1991. + function iterator(obj, iteratee, memo, keys, index, length) { + for (; index >= 0 && index < length; index += dir) { + var currentKey = keys ? keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + } + + return function(obj, iteratee, memo, context) { + iteratee = optimizeCb(iteratee, context, 4); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + index = dir > 0 ? 0 : length - 1; + // Determine the initial value if none is provided. + if (arguments.length < 3) { + memo = obj[keys ? keys[index] : index]; + index += dir; + } + return iterator(obj, iteratee, memo, keys, index, length); + }; + } + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. + _.reduce = _.foldl = _.inject = createReduce(1); + + // The right-associative version of reduce, also known as `foldr`. + _.reduceRight = _.foldr = createReduce(-1); + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, predicate, context) { + var key; + if (isArrayLike(obj)) { + key = _.findIndex(obj, predicate, context); + } else { + key = _.findKey(obj, predicate, context); + } + if (key !== void 0 && key !== -1) return obj[key]; + }; + + // Return all the elements that pass a truth test. + // Aliased as `select`. + _.filter = _.select = function(obj, predicate, context) { + var results = []; + predicate = cb(predicate, context); + _.each(obj, function(value, index, list) { + if (predicate(value, index, list)) results.push(value); + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, predicate, context) { + return _.filter(obj, _.negate(cb(predicate)), context); + }; + + // Determine whether all of the elements match a truth test. + // Aliased as `all`. + _.every = _.all = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (!predicate(obj[currentKey], currentKey, obj)) return false; + } + return true; + }; + + // Determine if at least one element in the object matches a truth test. + // Aliased as `any`. + _.some = _.any = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (predicate(obj[currentKey], currentKey, obj)) return true; + } + return false; + }; + + // Determine if the array or object contains a given item (using `===`). + // Aliased as `includes` and `include`. + _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + if (typeof fromIndex != 'number' || guard) fromIndex = 0; + return _.indexOf(obj, item, fromIndex) >= 0; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + var func = isFunc ? method : value[method]; + return func == null ? func : func.apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, _.property(key)); + }; + + // Convenience version of a common use case of `filter`: selecting only objects + // containing specific `key:value` pairs. + _.where = function(obj, attrs) { + return _.filter(obj, _.matcher(attrs)); + }; + + // Convenience version of a common use case of `find`: getting the first object + // containing specific `key:value` pairs. + _.findWhere = function(obj, attrs) { + return _.find(obj, _.matcher(attrs)); + }; + + // Return the maximum element (or element-based computation). + _.max = function(obj, iteratee, context) { + var result = -Infinity, lastComputed = -Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value > result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed > lastComputed || computed === -Infinity && result === -Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iteratee, context) { + var result = Infinity, lastComputed = Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value < result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed < lastComputed || computed === Infinity && result === Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Shuffle a collection, using the modern version of the + // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + _.shuffle = function(obj) { + var set = isArrayLike(obj) ? obj : _.values(obj); + var length = set.length; + var shuffled = Array(length); + for (var index = 0, rand; index < length; index++) { + rand = _.random(0, index); + if (rand !== index) shuffled[index] = shuffled[rand]; + shuffled[rand] = set[index]; + } + return shuffled; + }; + + // Sample **n** random values from a collection. + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `map`. + _.sample = function(obj, n, guard) { + if (n == null || guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + return obj[_.random(obj.length - 1)]; + } + return _.shuffle(obj).slice(0, Math.max(0, n)); + }; + + // Sort the object's values by a criterion produced by an iteratee. + _.sortBy = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value: value, + index: index, + criteria: iteratee(value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + }; + + // An internal function used for aggregate "group by" operations. + var group = function(behavior) { + return function(obj, iteratee, context) { + var result = {}; + iteratee = cb(iteratee, context); + _.each(obj, function(value, index) { + var key = iteratee(value, index, obj); + behavior(result, value, key); + }); + return result; + }; + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = group(function(result, value, key) { + if (_.has(result, key)) result[key].push(value); else result[key] = [value]; + }); + + // Indexes the object's values by a criterion, similar to `groupBy`, but for + // when you know that your index values will be unique. + _.indexBy = group(function(result, value, key) { + result[key] = value; + }); + + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + _.countBy = group(function(result, value, key) { + if (_.has(result, key)) result[key]++; else result[key] = 1; + }); + + // Safely create a real, live array from anything iterable. + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (isArrayLike(obj)) return _.map(obj, _.identity); + return _.values(obj); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + if (obj == null) return 0; + return isArrayLike(obj) ? obj.length : _.keys(obj).length; + }; + + // Split a collection into two arrays: one whose elements all satisfy the given + // predicate, and one whose elements all do not satisfy the predicate. + _.partition = function(obj, predicate, context) { + predicate = cb(predicate, context); + var pass = [], fail = []; + _.each(obj, function(value, key, obj) { + (predicate(value, key, obj) ? pass : fail).push(value); + }); + return [pass, fail]; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head` and `take`. The **guard** check + // allows it to work with `_.map`. + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[0]; + return _.initial(array, array.length - n); + }; + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. + _.initial = function(array, n, guard) { + return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. + _.last = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[array.length - 1]; + return _.rest(array, Math.max(0, array.length - n)); + }; + + // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. + // Especially useful on the arguments object. Passing an **n** will return + // the rest N values in the array. + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, n == null || guard ? 1 : n); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, _.identity); + }; + + // Internal implementation of a recursive `flatten` function. + var flatten = function(input, shallow, strict, startIndex) { + var output = [], idx = 0; + for (var i = startIndex || 0, length = getLength(input); i < length; i++) { + var value = input[i]; + if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { + //flatten current level of array or arguments object + if (!shallow) value = flatten(value, shallow, strict); + var j = 0, len = value.length; + output.length += len; + while (j < len) { + output[idx++] = value[j++]; + } + } else if (!strict) { + output[idx++] = value; + } + } + return output; + }; + + // Flatten out an array, either recursively (by default), or just one level. + _.flatten = function(array, shallow) { + return flatten(array, shallow, false); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iteratee, context) { + if (!_.isBoolean(isSorted)) { + context = iteratee; + iteratee = isSorted; + isSorted = false; + } + if (iteratee != null) iteratee = cb(iteratee, context); + var result = []; + var seen = []; + for (var i = 0, length = getLength(array); i < length; i++) { + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; + if (isSorted) { + if (!i || seen !== computed) result.push(value); + seen = computed; + } else if (iteratee) { + if (!_.contains(seen, computed)) { + seen.push(computed); + result.push(value); + } + } else if (!_.contains(result, value)) { + result.push(value); + } + } + return result; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(flatten(arguments, true, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersection = function(array) { + var result = []; + var argsLength = arguments.length; + for (var i = 0, length = getLength(array); i < length; i++) { + var item = array[i]; + if (_.contains(result, item)) continue; + for (var j = 1; j < argsLength; j++) { + if (!_.contains(arguments[j], item)) break; + } + if (j === argsLength) result.push(item); + } + return result; + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = flatten(arguments, true, true, 1); + return _.filter(array, function(value){ + return !_.contains(rest, value); + }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + return _.unzip(arguments); + }; + + // Complement of _.zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices + _.unzip = function(array) { + var length = array && _.max(array, getLength).length || 0; + var result = Array(length); + + for (var index = 0; index < length; index++) { + result[index] = _.pluck(array, index); + } + return result; + }; + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. + _.object = function(list, values) { + var result = {}; + for (var i = 0, length = getLength(list); i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; + + // Generator function to create the findIndex and findLastIndex functions + function createPredicateIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; + } + + // Returns the first index on an array-like that passes a predicate test + _.findIndex = createPredicateIndexFinder(1); + _.findLastIndex = createPredicateIndexFinder(-1); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = getLength(array); + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; + } + return low; + }; + + // Generator function to create the indexOf and lastIndexOf functions + function createIndexFinder(dir, predicateFind, sortedIndex) { + return function(array, item, idx) { + var i = 0, length = getLength(array); + if (typeof idx == 'number') { + if (dir > 0) { + i = idx >= 0 ? idx : Math.max(idx + length, i); + } else { + length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; + } + } else if (sortedIndex && idx && length) { + idx = sortedIndex(array, item); + return array[idx] === item ? idx : -1; + } + if (item !== item) { + idx = predicateFind(slice.call(array, i, length), _.isNaN); + return idx >= 0 ? idx + i : -1; + } + for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { + if (array[idx] === item) return idx; + } + return -1; + }; + } + + // Return the position of the first occurrence of an item in an array, + // or -1 if the item is not included in the array. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); + _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (stop == null) { + stop = start || 0; + start = 0; + } + step = step || 1; + + var length = Math.max(Math.ceil((stop - start) / step), 0); + var range = Array(length); + + for (var idx = 0; idx < length; idx++, start += step) { + range[idx] = start; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Determines whether to execute a function as a constructor + // or a normal function with the provided arguments + var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (_.isObject(result)) return result; + return self; + }; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if + // available. + _.bind = function(func, context) { + if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); + var args = slice.call(arguments, 2); + var bound = function() { + return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); + }; + return bound; + }; + + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. _ acts + // as a placeholder, allowing any combination of arguments to be pre-filled. + _.partial = function(func) { + var boundArgs = slice.call(arguments, 1); + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; + } + while (position < arguments.length) args.push(arguments[position++]); + return executeBound(func, bound, this, this, args); + }; + return bound; + }; + + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + _.bindAll = function(obj) { + var i, length = arguments.length, key; + if (length <= 1) throw new Error('bindAll must be passed function names'); + for (i = 1; i < length; i++) { + key = arguments[i]; + obj[key] = _.bind(obj[key], obj); + } + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memoize = function(key) { + var cache = memoize.cache; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); + if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); + return cache[address]; + }; + memoize.cache = {}; + return memoize; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ + return func.apply(null, args); + }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = _.partial(_.delay, _, 1); + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _.throttle = function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + if (!options) options = {}; + var later = function() { + previous = options.leading === false ? 0 : _.now(); + timeout = null; + result = func.apply(context, args); + if (!timeout) context = args = null; + }; + return function() { + var now = _.now(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0 || remaining > wait) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + previous = now; + result = func.apply(context, args); + if (!timeout) context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { + var timeout, args, context, timestamp, result; + + var later = function() { + var last = _.now() - timestamp; + + if (last < wait && last >= 0) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + if (!timeout) context = args = null; + } + } + }; + + return function() { + context = this; + args = arguments; + timestamp = _.now(); + var callNow = immediate && !timeout; + if (!timeout) timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + + return result; + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return _.partial(wrapper, func); + }; + + // Returns a negated version of the passed-in predicate. + _.negate = function(predicate) { + return function() { + return !predicate.apply(this, arguments); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var args = arguments; + var start = args.length - 1; + return function() { + var i = start; + var result = args[start].apply(this, arguments); + while (i--) result = args[i].call(this, result); + return result; + }; + }; + + // Returns a function that will only be executed on and after the Nth call. + _.after = function(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; + + // Returns a function that will only be executed up to (but not including) the Nth call. + _.before = function(times, func) { + var memo; + return function() { + if (--times > 0) { + memo = func.apply(this, arguments); + } + if (times <= 1) func = null; + return memo; + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = _.partial(_.before, 2); + + // Object Functions + // ---------------- + + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + function collectNonEnumProps(obj, keys) { + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { + keys.push(prop); + } + } + } + + // Retrieve the names of an object's own properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve all the property names of an object. + _.allKeys = function(obj) { + if (!_.isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; + }; + + // Returns the results of applying the iteratee to each element of the object + // In contrast to _.map it returns an object + _.mapObject = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = _.keys(obj), + length = keys.length, + results = {}, + currentKey; + for (var index = 0; index < length; index++) { + currentKey = keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Convert an object into a list of `[key, value]` pairs. + _.pairs = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var pairs = Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [keys[i], obj[keys[i]]]; + } + return pairs; + }; + + // Invert the keys and values of an object. The values must be serializable. + _.invert = function(obj) { + var result = {}; + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + result[obj[keys[i]]] = keys[i]; + } + return result; + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = createAssigner(_.allKeys); + + // Assigns a given object with all the own properties in the passed-in object(s) + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + _.extendOwn = _.assign = createAssigner(_.keys); + + // Returns the first key on an object that passes a predicate test + _.findKey = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = _.keys(obj), key; + for (var i = 0, length = keys.length; i < length; i++) { + key = keys[i]; + if (predicate(obj[key], key, obj)) return key; + } + }; + + // Return a copy of the object only containing the whitelisted properties. + _.pick = function(object, oiteratee, context) { + var result = {}, obj = object, iteratee, keys; + if (obj == null) return result; + if (_.isFunction(oiteratee)) { + keys = _.allKeys(obj); + iteratee = optimizeCb(oiteratee, context); + } else { + keys = flatten(arguments, false, false, 1); + iteratee = function(value, key, obj) { return key in obj; }; + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; + } + return result; + }; + + // Return a copy of the object without the blacklisted properties. + _.omit = function(obj, iteratee, context) { + if (_.isFunction(iteratee)) { + iteratee = _.negate(iteratee); + } else { + var keys = _.map(flatten(arguments, false, false, 1), String); + iteratee = function(value, key) { + return !_.contains(keys, key); + }; + } + return _.pick(obj, iteratee, context); + }; + + // Fill in a given object with default properties. + _.defaults = createAssigner(_.allKeys, true); + + // Creates an object that inherits from the given prototype object. + // If additional properties are provided then they will be added to the + // created object. + _.create = function(prototype, props) { + var result = baseCreate(prototype); + if (props) _.extendOwn(result, props); + return result; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Returns whether an object has a given set of `key:value` pairs. + _.isMatch = function(object, attrs) { + var keys = _.keys(attrs), length = keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; + } + return true; + }; + + + // Internal recursive comparison function for `isEqual`. + var eq = function(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + switch (className) { + // Strings, numbers, regular expressions, dates, and booleans are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + } + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && + _.isFunction(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + } + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } + + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var keys = _.keys(a), key; + length = keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (_.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (obj == null) return true; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) === '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. + _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) === '[object ' + name + ']'; + }; + }); + + // Define a fallback version of the method in browsers (ahem, IE < 9), where + // there isn't any inspectable "Arguments" type. + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return _.has(obj, 'callee'); + }; + } + + // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, + // IE 11 (#1621), and in Safari 8 (#1929). + if (typeof /./ != 'function' && typeof Int8Array != 'object') { + _.isFunction = function(obj) { + return typeof obj == 'function' || false; + }; + } + + // Is a given object a finite number? + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; + + // Is the given value `NaN`? (NaN is the only number which does not equal itself). + _.isNaN = function(obj) { + return _.isNumber(obj) && obj !== +obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Shortcut function for checking if an object has a given property directly + // on itself (in other words, not on a prototype). + _.has = function(obj, key) { + return obj != null && hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iteratees. + _.identity = function(value) { + return value; + }; + + // Predicate-generating functions. Often useful outside of Underscore. + _.constant = function(value) { + return function() { + return value; + }; + }; + + _.noop = function(){}; + + _.property = property; + + // Generates a function for a given object that returns a given property. + _.propertyOf = function(obj) { + return obj == null ? function(){} : function(key) { + return obj[key]; + }; + }; + + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + _.matcher = _.matches = function(attrs) { + attrs = _.extendOwn({}, attrs); + return function(obj) { + return _.isMatch(obj, attrs); + }; + }; + + // Run a function **n** times. + _.times = function(n, iteratee, context) { + var accum = Array(Math.max(0, n)); + iteratee = optimizeCb(iteratee, context, 1); + for (var i = 0; i < n; i++) accum[i] = iteratee(i); + return accum; + }; + + // Return a random integer between min and max (inclusive). + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; + + // A (possibly faster) way to get the current timestamp as an integer. + _.now = Date.now || function() { + return new Date().getTime(); + }; + + // List of HTML entities for escaping. + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + var unescapeMap = _.invert(escapeMap); + + // Functions for escaping and unescaping strings to/from HTML interpolation. + var createEscaper = function(map) { + var escaper = function(match) { + return map[match]; + }; + // Regexes for identifying a key that needs to be escaped + var source = '(?:' + _.keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function(string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; + }; + _.escape = createEscaper(escapeMap); + _.unescape = createEscaper(unescapeMap); + + // If the value of the named `property` is a function then invoke it with the + // `object` as context; otherwise, return it. + _.result = function(object, property, fallback) { + var value = object == null ? void 0 : object[property]; + if (value === void 0) { + value = fallback; + } + return _.isFunction(value) ? value.call(object) : value; + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escaper = /\\|'|\r|\n|\u2028|\u2029/g; + + var escapeChar = function(match) { + return '\\' + escapes[match]; + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + // NB: `oldSettings` only exists for backwards compatibility. + _.template = function(text, settings, oldSettings) { + if (!settings && oldSettings) settings = oldSettings; + settings = _.defaults({}, settings, _.templateSettings); + + // Combine delimiters into one regular expression via alternation. + var matcher = RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset).replace(escaper, escapeChar); + index = offset + match.length; + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } else if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } else if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + + // Adobe VMs need the match returned to produce the correct offest. + return match; + }); + source += "';\n"; + + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + 'return __p;\n'; + + try { + var render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + var template = function(data) { + return render.call(this, data, _); + }; + + // Provide the compiled source as a convenience for precompilation. + var argument = settings.variable || 'obj'; + template.source = 'function(' + argument + '){\n' + source + '}'; + + return template; + }; + + // Add a "chain" function. Start chaining a wrapped Underscore object. + _.chain = function(obj) { + var instance = _(obj); + instance._chain = true; + return instance; + }; + + // OOP + // --------------- + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + + // Helper function to continue chaining intermediate results. + var result = function(instance, obj) { + return instance._chain ? _(obj).chain() : obj; + }; + + // Add your own custom functions to the Underscore object. + _.mixin = function(obj) { + _.each(_.functions(obj), function(name) { + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result(this, func.apply(_, args)); + }; + }); + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; + return result(this, obj); + }; + }); + + // Add all accessor Array functions to the wrapper. + _.each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result(this, method.apply(this._wrapped, arguments)); + }; + }); + + // Extracts the result from a wrapped and chained object. + _.prototype.value = function() { + return this._wrapped; + }; + + // Provide unwrapping proxy for some methods used in engine operations + // such as arithmetic and JSON stringification. + _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; + + _.prototype.toString = function() { + return '' + this._wrapped; + }; + + // AMD registration happens at the end for compatibility with AMD loaders + // that may not enforce next-turn semantics on modules. Even though general + // practice for AMD registration is to be anonymous, underscore registers + // as a named module because, like jQuery, it is a base library that is + // popular enough to be bundled in a third party lib, but not be part of + // an AMD load request. Those cases could generate an error when an + // anonymous define() is called outside of a loader request. + if (typeof define === 'function' && define.amd) { + define('underscore', [], function() { + return _; + }); + } +}.call(this)); + +},{}],"/home/raskolnikov/dev/mixco/script/korg_nanokontrol2.mixco":[function(require,module,exports){ +var assert, b, c, mixco, v; + +mixco = require('mixco'); + +assert = mixco.util.assert; + +c = mixco.control; + +b = mixco.behaviour; + +v = mixco.value; + +mixco.script.register(module, { + info: { + name: '[mixco] Korg Nanokontrol 2', + author: 'Juan Pedro Bolivar Puente ', + wiki: 'https://sinusoid.es/mixco/script/korg_nanokontrol2.mixco.html', + forums: 'https://github.com/arximboldi/mixco/issues', + description: "Controller mapping for Korg Nanokontrol 2. Unlike\nother scripts that are oriented as a secondary\ncontroller, this provides basic deck controls, being\nusable as primary interface." + }, + constructor: function() { + var g; + this.cycle = b.modifier(); + c.control(0x2e).does(this.cycle); + this.backButton = c.control(0x3a); + this.fwdButton = c.control(0x3b); + this.nudgeDownButton = c.control(0x2b); + this.nudgeUpButton = c.control(0x2c); + this.marker = b.modifier(); + c.control(0x3C).does(this.marker); + g = "[Playlist]"; + c.control(0x3D).when(this.marker, g, "SelectPrevPlaylist")["else"](g, "SelectPrevTrack"); + c.control(0x3E).when(this.marker, g, "SelectNextPlaylist")["else"](g, "SelectNextTrack"); + this.loadTrack = c.control(0x2a); + this.sync = c.control(0x29); + this.syncTempo = c.control(0x2d); + g = "[Master]"; + c.input(0x06).does(g, "headVolume"); + c.input(0x05).does(g, "headMix"); + c.input(0x02).does(b.soft(g, "crossfader")); + c.input(0x01).does(b.soft(g, "balance")); + this.decks = b.chooser(); + this.addDeck(0); + return this.addDeck(1); + }, + addDeck: function(i) { + var chooseCycle, g, offset; + assert(i === 0 || i === 1); + g = "[Channel" + (i + 1) + "]"; + offset = i === 0 ? [3, 2, 1, 0] : [4, 5, 6, 7]; + c.input(0x10 + offset[0]).does(g, "filterLow"); + c.input(0x10 + offset[1]).does(g, "filterMid"); + c.input(0x10 + offset[2]).does(g, "filterHigh"); + c.input(0x10 + offset[3]).does(b.soft(g, "pregain")); + c.control(0x20 + offset[0]).does(this.decks.add(g, "pfl")); + c.control(0x30 + offset[0]).does(g, "cue_default", g, "cue_indicator"); + c.control(0x40 + offset[0]).does(g, "play"); + c.input(0x00 + offset[0]).does(g, "volume"); + c.control(0x20 + offset[3]).does(g, "bpm_tap", g, "beat_active"); + c.control(0x30 + offset[3]).does(g, "keylock"); + c.control(0x40 + offset[3]).does(g, "beats_translate_curpos"); + c.input(0x00 + offset[3]).does(b.soft(g, "rate")); + c.control(0x20 + offset[1]).when(this.cycle, g, "hotcue_1_activate", g, "hotcue_1_enabled")["else"].when(this.marker, g, "hotcue_1_clear", g, "hotcue_1_enabled")["else"](g, "beatloop_2_toggle", g, "beatloop_2_enabled"); + c.control(0x20 + offset[2]).when(this.cycle, g, "hotcue_2_activate", g, "hotcue_2_enabled")["else"].when(this.marker, g, "hotcue_2_clear", g, "hotcue_2_enabled")["else"](g, "beatloop_4_toggle", g, "beatloop_4_enabled"); + c.control(0x30 + offset[1]).when(this.cycle, g, "hotcue_3_activate", g, "hotcue_3_enabled")["else"].when(this.marker, g, "hotcue_3_clear", g, "hotcue_3_enabled")["else"](g, "beatloop_8_toggle", g, "beatloop_8_enabled"); + c.control(0x30 + offset[2]).when(this.cycle, g, "hotcue_4_activate", g, "hotcue_4_enabled")["else"].when(this.marker, g, "hotcue_4_clear", g, "hotcue_4_enabled")["else"](g, "beatloop_16_toggle", g, "beatloop_16_enabled"); + c.control(0x40 + offset[1]).when(this.cycle, g, "hotcue_5_activate", g, "hotcue_5_enabled")["else"].when(this.marker, g, "hotcue_5_clear", g, "hotcue_5_enabled")["else"](g, "loop_halve"); + c.control(0x40 + offset[2]).when(this.cycle, g, "hotcue_6_activate", g, "hotcue_6_enabled")["else"].when(this.marker, g, "hotcue_6_clear", g, "hotcue_6_enabled")["else"](g, "loop_double"); + chooseCycle = v.and(this.cycle, this.decks.activator(i)); + this.nudgeUpButton.when(chooseCycle, b.toggle(0, 0.5, g, "wheel"))["else"].when(this.decks.activator(i), b.toggle(0, 0.1, g, "wheel")); + this.nudgeDownButton.when(chooseCycle, b.toggle(0, -0.5, g, "wheel"))["else"].when(this.decks.activator(i), b.toggle(0, -0.1, g, "wheel")); + this.fwdButton.when(this.decks.activator(i), g, "fwd"); + this.backButton.when(this.decks.activator(i), g, "back"); + this.loadTrack.when(this.decks.activator(i), g, "LoadSelectedTrack"); + this.sync.when(this.decks.activator(i), g, "sync_enabled"); + return this.syncTempo.when(this.decks.activator(i), g, "beatsync"); + }, + init: function() { + return this.decks.activate(0); + } +}); + + +},{"mixco":2}],17:[function(require,module,exports){ +var _, assert, bind, copy, events, extend, factory, indent, isinstance, makeOptionsChooser, map, multi, option, ref, ref1, ref2, toOption, transform, value, + extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + slice = [].slice; + +events = require('events'); + +transform = require('./transform'); + +value = require('./value'); + +ref = require('./util'), indent = ref.indent, assert = ref.assert, factory = ref.factory, copy = ref.copy; + +ref1 = require('heterarchy'), multi = ref1.multi, isinstance = ref1.isinstance; + +_ = (ref2 = require('underscore'), extend = ref2.extend, bind = ref2.bind, map = ref2.map, ref2); + +exports.Actor = (function(superClass) { + extend1(Actor, superClass); + + function Actor() { + return Actor.__super__.constructor.apply(this, arguments); + } + + Actor.prototype.send = void 0; + + return Actor; + +})(events.EventEmitter); + +toOption = function(option) { + var result; + result = option; + if (isinstance(option, Function)) { + result = { + transform: option + }; + } + if ((result.transform != null) && (result.process == null)) { + result.process = result.transform.length === 1 ? function(ev, b) { + return ev.value = this.transform(ev.value); + } : function(ev, b) { + return ev.value = this.transform(ev.value, b.midiValue); + }; + } + return result; +}; + +option = exports.option = (function() { + var add, result, rot64; + result = {}; + add = function() { + var desc, i, mixxxName, name, names, option; + names = 2 <= arguments.length ? slice.call(arguments, 0, i = arguments.length - 1) : (i = 0, []), option = arguments[i++]; + mixxxName = names[0], name = names[1]; + desc = toOption(option); + desc.name = mixxxName; + result[name != null ? name : mixxxName] = desc; + return result; + }; + rot64 = function(sign) { + return function(v1, v0) { + var diff; + diff = v1 - (64..diff = diff === -1 || diff === 1 ? diff / 16.0 : diff - diff.sign()); + return (v0 + diff * sign).clamp(0, 127); + }; + }; + add('invert', function(v) { + return 127.0 - v; + }); + add('rot64', rot64(1)); + add('rot64inv', rot64(-1)); + add('rot64fast', function(v1, v0) { + return (v0 + (v1 - 64) * 1.5).clamp(0, 127); + }); + add('diff', function(v1, v0) { + return v0 + (v1 > 64 ? v1 - 128 : v1); + }); + add('button', function(v) { + return v !== 0; + }); + add('switch', function(v) { + return 1; + }); + result.switch_ = result["switch"]; + add('hercjog', function(v1, v0) { + return v0 + (v1 > 64 ? v1 - 128 : v1); + }); + add('spread64', function(v) { + return v - 64; + }); + add('selectknob', function(v) { + if (v > 64) { + return v - 128; + } else { + return v; + } + }); + return add('soft-takeover', 'softTakeover', { + enable: function(b) { + if (isinstance(b, exports.MapIn)) { + return b.script.mixxx.engine.softTakeover(b.group, b.key, true); + } + }, + disable: function(b) { + if (isinstance(b, exports.MapIn)) { + return b.script.mixxx.engine.softTakeover(b.group, b.key, false); + } + } + }); +})(); + +exports.makeOptionsChooser = makeOptionsChooser = function(obj) { + var key, opt, result; + result = {}; + for (key in option) { + opt = option[key]; + Object.defineProperty(result, key, { + get: (function(opt) { + return function() { + return obj.option(opt); + }; + })(opt) + }); + } + return result; +}; + +exports.Behaviour = (function(superClass) { + extend1(Behaviour, superClass); + + function Behaviour() { + return Behaviour.__super__.constructor.apply(this, arguments); + } + + Behaviour.prototype.enable = function(script, actor) { + var i, len, opt, ref3, results; + assert(this.actor == null); + assert(this.script == null); + this.script = script; + this.actor = actor; + this._eventListener = (function(_this) { + return function(ev) { + var i, len, opt, ref3; + if (_this._options != null) { + ev = copy(ev); + ref3 = _this._options; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (typeof opt.process === "function") { + opt.process(ev, _this); + } + } + } + return _this.onMidiEvent(ev); + }; + })(this); + actor.on('event', this._eventListener); + if (this._options != null) { + ref3 = this._options; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + results.push(typeof opt.enable === "function" ? opt.enable(this) : void 0); + } + return results; + } + }; + + Behaviour.prototype.disable = function(script, actor) { + var i, len, opt, ref3; + assert(this.script === script); + assert(this.actor === actor); + if (this._options != null) { + ref3 = this._options; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (typeof opt.disable === "function") { + opt.disable(this); + } + } + } + actor.removeListener('event', this._eventListener); + delete this.script; + return delete this.actor; + }; + + Behaviour.prototype.option = function() { + var i, len, opt, options, ref3; + options = 1 <= arguments.length ? slice.call(arguments, 0) : []; + for (i = 0, len = options.length; i < len; i++) { + opt = options[i]; + assert(opt); + } + (ref3 = (this._options != null ? this._options : this._options = [])).push.apply(ref3, map(options, toOption)); + return this; + }; + + Behaviour.property('options', function() { + return makeOptionsChooser(this); + }); + + Behaviour.prototype.directInMapping = function() { + return null; + }; + + Behaviour.prototype.directOutMapping = function() { + return null; + }; + + Behaviour.prototype.onMidiEvent = function(ev) { + return null; + }; + + Behaviour.prototype.getMidiValue = function() { + return this.value; + }; + + Behaviour.property('midiValue', function() { + return this.getMidiValue(); + }); + + return Behaviour; + +})(value.Value); + +exports.Call = (function(superClass) { + extend1(Call, superClass); + + function Call(onMidiEvent) { + this.onMidiEvent = onMidiEvent; + Call.__super__.constructor.call(this); + } + + return Call; + +})(exports.Behaviour); + +exports.call = factory(exports.Call); + +exports.Output = (function(superClass) { + extend1(Output, superClass); + + Output.prototype.minimum = 1; + + Output.prototype.maximum = void 0; + + function Output() { + Output.__super__.constructor.apply(this, arguments); + this.output = value.value(); + } + + Output.prototype.enable = function() { + Output.__super__.enable.apply(this, arguments); + if (this.actor.send != null) { + if (this._updateOutputCallback == null) { + this._updateOutputCallback = (function(_this) { + return function() { + return _this.updateOutput(); + }; + })(this); + } + this.output.on('value', this._updateOutputCallback); + } + if (this.actor.doSend != null) { + return this.updateOutput(this.actor.doSend); + } + }; + + Output.prototype.disable = function() { + if (this._updateOutputCallback != null) { + this.removeListener('value', this._updateOutputCallback); + this._updateOutputCallback = void 0; + } + return Output.__super__.disable.apply(this, arguments); + }; + + Output.prototype.updateOutput = function(sendfn) { + if (sendfn == null) { + sendfn = null; + } + if (sendfn == null) { + sendfn = this.actor.send; + } + return sendfn.call(this.actor, (Math.abs(this.output.value) >= this.minimum ? 'on' : 'off')); + }; + + return Output; + +})(exports.Behaviour); + +exports.Transform = (function(superClass) { + extend1(Transform, superClass); + + function Transform(transformer1, initial) { + this.transformer = transformer1; + if (initial == null) { + initial = void 0; + } + Transform.__super__.constructor.call(this, { + initial: initial + }); + } + + Transform.prototype.onMidiEvent = function(ev) { + var result; + result = this.transformer(ev, this.midiValue); + if (result != null) { + return this.output.value = this.value = result; + } + }; + + Transform.prototype.getMidiValue = function() { + var base, ref3; + return (ref3 = typeof (base = this.transformer).inverse === "function" ? base.inverse(this.value) : void 0) != null ? ref3 : this.value; + }; + + return Transform; + +})(exports.Output); + +exports.transform = factory(exports.Transform); + +exports.modifier = function() { + return exports.transform(transform.momentaryT, false); +}; + +exports["switch"] = function() { + return exports.transform(transform.binaryT, false); +}; + +exports.switch_ = exports["switch"]; + +exports.MapIn = (function(superClass) { + extend1(MapIn, superClass); + + function MapIn(ingroupOrParams, inkey) { + var ref3; + if (inkey == null) { + inkey = void 0; + } + MapIn.__super__.constructor.apply(this, arguments); + ref3 = !isinstance(ingroupOrParams, String) ? ingroupOrParams : { + group: ingroupOrParams, + key: inkey + }, this.group = ref3.group, this.key = ref3.key; + this._transform = transform.mappings[this.key]; + } + + MapIn.prototype.transform = function(trans) { + this._transform = trans; + return this; + }; + + MapIn.prototype.enable = function(script, actor) { + var engine; + MapIn.__super__.enable.apply(this, arguments); + engine = script.mixxx.engine; + this.value = engine.getValue(this.group, this.key); + if (this.listeners('value').length > 0) { + if (this._inHandler == null) { + this._inHandler = script.registerHandler((function(_this) { + return function(v) { + return _this.value = v; + }; + })(this)); + } + engine.connectControl(this.group, this.key, this._inHandler); + return this._inHandlerConnected = true; + } + }; + + MapIn.prototype.disable = function() { + if (this._inHandlerConnected != null) { + this.script.mixxx.engine.connectControl(this.group, this.key, this._inHandler, true); + this._inHandlerConnected = false; + } + return MapIn.__super__.disable.apply(this, arguments); + }; + + MapIn.prototype.directInMapping = function() { + if (this._transform === transform.mappings[this.key]) { + return { + group: this.group, + key: this.key + }; + } + }; + + MapIn.prototype.onMidiEvent = function(ev) { + var val; + val = this._transform(ev, this.midiValue); + if (val != null) { + this.script.mixxx.engine.setValue(this.group, this.key, val); + if (this.listeners('value').length === 0) { + return this.value = val; + } + } + }; + + MapIn.prototype.getMidiValue = function() { + var ref3, ref4; + return (ref3 = (ref4 = this._transform) != null ? typeof ref4.inverse === "function" ? ref4.inverse(this.value) : void 0 : void 0) != null ? ref3 : this.value; + }; + + return MapIn; + +})(exports.Behaviour); + +exports.mapIn = factory(exports.MapIn); + +exports.MapOut = (function(superClass) { + extend1(MapOut, superClass); + + function MapOut(outgroupOrParams, outkey) { + var ref3; + if (outkey == null) { + outkey = void 0; + } + MapOut.__super__.constructor.apply(this, arguments); + ref3 = !isinstance(outgroupOrParams, String) ? outgroupOrParams : { + outgroup: outgroupOrParams, + outkey: outkey + }, this.outgroup = ref3.outgroup, this.outkey = ref3.outkey; + } + + MapOut.prototype.meter = function(transformer) { + if (transformer == null) { + transformer = void 0; + } + this._outTransform = transformer; + if (this._outTransform == null) { + this._outTransform = transform.mappings[this.outkey].inverse; + } + this.updateOutput = function() { + return this.actor.send(Math.floor(this._outTransform(this.output.value))); + }; + return this; + }; + + MapOut.prototype.enable = function(script, actor) { + var engine; + MapOut.__super__.enable.apply(this, arguments); + engine = script.mixxx.engine; + this.output.value = engine.getValue(this.outgroup, this.outkey); + if (this.output.listeners('value').length > 0) { + if (this._outHandler == null) { + this._outHandler = script.registerHandler((function(_this) { + return function(v) { + return _this.output.value = v; + }; + })(this)); + } + engine.connectControl(this.outgroup, this.outkey, this._outHandler); + return this._outHandlerConnected = true; + } + }; + + MapOut.prototype.disable = function() { + if (this._outHandlerConnected != null) { + this.script.mixxx.engine.connectControl(this.outgroup, this.outkey, this._outHandler, true); + this._outHandlerConnected = false; + } + return MapOut.__super__.disable.apply(this, arguments); + }; + + MapOut.prototype.directOutMapping = function() { + if (this._outTransform == null) { + return { + group: this.outgroup, + key: this.outkey, + minimum: this.minimum + }; + } + }; + + return MapOut; + +})(exports.Output); + +exports.mapOut = factory(exports.MapOut); + +exports.Map = (function(superClass) { + extend1(Map, superClass); + + function Map(groupOrParams, key, outgroup, outkey) { + var params; + params = !isinstance(groupOrParams, String) ? groupOrParams : { + group: groupOrParams, + key: key, + outgroup: outgroup, + outkey: outkey + }; + if (params.outgroup == null) { + params.outgroup = params.group; + } + if (params.outkey == null) { + params.outkey = params.key; + } + Map.__super__.constructor.call(this, params); + } + + return Map; + +})(multi(exports.MapIn, exports.MapOut)); + +exports.map = factory(exports.Map); + +exports.toBehaviour = function() { + var args, behaviour; + behaviour = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + if (args.length > 0) { + return exports.map.apply(exports, [behaviour].concat(slice.call(args))); + } else { + return behaviour; + } +}; + +exports.soft = function() { + return exports.map.apply(exports, arguments).option(option.softTakeover); +}; + +exports.toggle = function() { + var args, offValue, onValue; + offValue = arguments[0], onValue = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; + return exports.map.apply(exports, args).transform(function(ev) { + if (ev.pressed) { + return onValue; + } else { + return offValue; + } + }); +}; + +exports.set = function() { + var args, valueToSet; + valueToSet = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.toggle.apply(exports, [valueToSet, null].concat(slice.call(args))); +}; + +exports.Chooser = (function(superClass) { + extend1(Chooser, superClass); + + function Chooser(arg) { + var ref3; + ref3 = arg != null ? arg : {}, this.autoExclusive = ref3.autoExclusive, this.onDisable = ref3.onDisable; + Chooser.__super__.constructor.apply(this, arguments); + this._selectedIndex = null; + this._chooseOptions = []; + this._chooseActivators = []; + this._chooseSelectors = []; + this._chooseHandles = []; + } + + Chooser.prototype.add = function(group, key, listen) { + var activator, idx; + if (listen == null) { + listen = null; + } + idx = this._chooseOptions.length; + activator = exports.map(group, key).transform((function(_this) { + return function(ev) { + if (ev.pressed) { + _this.activate(idx); + } + return null; + }; + })(this)); + this._chooseOptions.push([group, key, listen]); + this._chooseActivators.push(activator); + return activator; + }; + + Chooser.prototype.enable = function(script) { + var engine, group, i, key, len, listen, ref3, ref4; + Chooser.__super__.enable.apply(this, arguments); + if (this._updateValueHandler == null) { + this._updateValueHandler = script.registerHandler((function(_this) { + return function() { + return _this._updateValue(); + }; + })(this)); + } + engine = script.mixxx.engine; + ref3 = this._chooseOptions; + for (i = 0, len = ref3.length; i < len; i++) { + ref4 = ref3[i], group = ref4[0], key = ref4[1], listen = ref4[2]; + if (listen == null) { + listen = key; + } + engine.connectControl(group, listen, this._updateValueHandler); + } + return this._updateValue(); + }; + + Chooser.prototype.disable = function(script) { + var engine, group, i, key, len, listen, ref3, ref4; + assert(this._updateValueHandler); + engine = script.mixxx.engine; + ref3 = this._chooseOptions; + for (i = 0, len = ref3.length; i < len; i++) { + ref4 = ref3[i], group = ref4[0], key = ref4[1], listen = ref4[2]; + if (listen == null) { + listen = key; + } + engine.connectControl(group, listen, this._updateValueHandler, true); + } + return Chooser.__super__.disable.apply(this, arguments); + }; + + Chooser.prototype.activator = function(idx) { + assert((0 <= idx && idx < this._chooseOptions.length)); + return this._chooseActivators[idx]; + }; + + Chooser.prototype.selector = function() { + var select, selector; + select = (function(_this) { + return function(ev) { + var v; + v = (ev.value / 128.0 * _this._chooseOptions.length).clamp(0, _this._chooseOptions.length - 1); + _this._update({ + index: Math.floor(v) + }); + return v; + }; + })(this); + select.inverse = (function(_this) { + return function(v) { + return v / _this._chooseOptions.length * 128.0; + }; + })(this); + selector = extend(exports.transform(select), { + _updateValue: function(newv) { + if (Math.floor(newv) !== Math.floor(this.value)) { + return this.value = this.output.value = newv; + } + } + }); + this._chooseSelectors.push(selector); + return selector; + }; + + Chooser.prototype.momentary = function() { + return exports.action({ + press: (function(_this) { + return function() { + return _this._update({ + enable: true + }); + }; + })(this), + release: (function(_this) { + return function() { + return _this._update({ + enable: false + }); + }; + })(this) + }); + }; + + Chooser.prototype.activate = function(idx) { + this._update({ + index: idx, + enable: true + }); + return this; + }; + + Chooser.prototype.select = function(idx) { + if (this.actor != null) { + this._update({ + index: idx, + enable: true + }); + } else { + this._selectedIndex = idx; + } + return this; + }; + + Chooser.prototype.onMidiEvent = function(event) { + var enable; + if (event.pressed) { + enable = !this.value; + this._update({ + enable: enable + }); + if (!enable) { + return typeof this.onDisable === "function" ? this.onDisable() : void 0; + } + } + }; + + Chooser.prototype._update = function(arg) { + var enable, group, i, idx, index, key, len, listen, ref3, ref4, ref5, ref6, ref7, script; + ref3 = arg != null ? arg : {}, index = ref3.index, enable = ref3.enable; + if (enable == null) { + enable = this.value; + } + if (index == null) { + index = this._selectedIndex; + } + index = index != null ? index.clamp(0, this._chooseOptions.length - 1) : void 0; + if (index !== this._selectedIndex || enable !== this.value) { + script = (ref4 = this.script) != null ? ref4 : this._chooseActivators[index].script; + if (index != null) { + ref5 = this._chooseOptions[index], group = ref5[0], key = ref5[1], listen = ref5[2]; + script.mixxx.engine.setValue(group, key, enable); + } + if (!this.autoExclusive || !enable) { + ref6 = this._chooseOptions; + for (idx = i = 0, len = ref6.length; i < len; idx = ++i) { + ref7 = ref6[idx], group = ref7[0], key = ref7[1]; + if (idx !== index) { + script.mixxx.engine.setValue(group, key, false); + } + } + } + return this._selectedIndex = index; + } + }; + + Chooser.prototype._updateValue = function() { + var engine, i, len, ref3, selector; + if (this.script != null) { + engine = this.script.mixxx.engine; + this.value = this.output.value = _.some(this._chooseOptions, function(arg) { + var group, key, listen; + group = arg[0], key = arg[1], listen = arg[2]; + if (listen == null) { + listen = key; + } + return engine.getValue(group, listen); + }); + ref3 = this._chooseSelectors; + for (i = 0, len = ref3.length; i < len; i++) { + selector = ref3[i]; + selector._updateValue(this._selectedIndex); + } + } + return this; + }; + + return Chooser; + +})(exports.Output); + +exports.chooser = factory(exports.Chooser); + +exports.When = (function(superClass) { + extend1(When, superClass); + + function When() { + var _condition, base, wrapped; + _condition = arguments[0], wrapped = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this._condition = _condition; + this["else"] = (function(_this) { + return function() { + return _this._else.apply(_this, arguments); + }; + })(this); + this["else"].when = (function(_this) { + return function() { + return _this._elseWhen.apply(_this, arguments); + }; + })(this); + this.when = this["else"].when; + this.else_ = this["else"]; + When.__super__.constructor.call(this); + this._wrapped = exports.toBehaviour.apply(exports, wrapped); + this._condition.on('value', (function(_this) { + return function() { + return _this._update(); + }; + })(this)); + if (this._lastCondition !== 'no-more-negations') { + this._lastCondition = this._condition; + if ((base = this._lastCondition).negation == null) { + base.negation = value.not(this._condition); + } + } + } + + When.prototype.option = function() { + var ref3; + When.__super__.option.apply(this, arguments); + (ref3 = this._wrapped).option.apply(ref3, arguments); + return this; + }; + + When.prototype._elseWhen = function() { + var args, condition, nextCondition; + condition = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + assert(this._lastCondition != null, "Can not define more conditions after 'else'"); + nextCondition = value.and(condition, value.not(this._lastCondition)); + nextCondition.negation = value.and(this._lastCondition.negation, value.not(condition)); + this._lastCondition = nextCondition; + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(exports.When, [nextCondition].concat(slice.call(args)), function(){}); + }; + + When.prototype._else = function() { + var args, nextCondition; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastCondition != null, "Can not define more conditions after 'else'"); + nextCondition = this._lastCondition.negation; + nextCondition.negation = 'no-more-negations'; + delete this._lastCondition; + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(exports.When, [nextCondition].concat(slice.call(args)), function(){}); + }; + + When.prototype.enable = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + When.__super__.enable.apply(this, arguments); + this._enableOn = args; + this._enableRequested = true; + return this._update(); + }; + + When.prototype.disable = function() { + this._enableRequested = false; + this._update(); + return When.__super__.disable.apply(this, arguments); + }; + + When.prototype._update = function() { + var ref3, ref4; + this.value = this._enableRequested && this._condition.value; + if (this._wrapped.actor && !this.value) { + (ref3 = this._wrapped).disable.apply(ref3, this._enableOn); + } + if (!this._wrapped.actor && this.value) { + return (ref4 = this._wrapped).enable.apply(ref4, this._enableOn); + } + }; + + When.prototype.directOutMapping = function() { + return null; + }; + + When.prototype.directInMapping = function() { + return null; + }; + + return When; + +})(exports.Behaviour); + +exports.when = factory(exports.When); + +exports.Action = (function(superClass) { + extend1(Action, superClass); + + Action.prototype.minimum = true; + + function Action(action) { + this.action = action != null ? action : void 0; + Action.__super__.constructor.call(this); + if (this.onPress == null) { + this.onPress = this.action.press; + } + if (this.onRelease == null) { + this.onRelease = this.action.release; + } + } + + Action.prototype.onMidiEvent = function(ev) { + var val; + val = this.value = this.output.value = ev.pressed; + if (val) { + return typeof this.onPress === "function" ? this.onPress() : void 0; + } else { + return typeof this.onRelease === "function" ? this.onRelease() : void 0; + } + }; + + return Action; + +})(exports.Output); + +exports.action = factory(exports.Action); + +exports.punchIn = function(threshold, threshold2) { + var inThreshold, oldxfader; + if (threshold2 == null) { + threshold2 = void 0; + } + oldxfader = void 0; + inThreshold = function(newxfader, threshold) { + return (threshold < 0 && newxfader < threshold) || (threshold > 0 && newxfader > threshold); + }; + return exports.action({ + press: function() { + var engine, newxfader; + engine = this.script.mixxx.engine; + newxfader = engine.getValue("[Master]", "crossfader"); + if (inThreshold(newxfader, threshold) || ((threshold2 != null) && inThreshold(newxfader, threshold2))) { + oldxfader = newxfader; + return engine.setValue("[Master]", "crossfader", 0); + } + }, + release: function() { + var engine; + engine = this.script.mixxx.engine; + if (oldxfader != null) { + engine.setValue("[Master]", "crossfader", oldxfader); + return oldxfader = void 0; + } + } + }); +}; + +exports.scratchEnable = function(deck, intervalsPerRev, rpm, alpha, beta, ramp) { + if (intervalsPerRev == null) { + intervalsPerRev = 128 * 4; + } + if (rpm == null) { + rpm = 44.0; + } + if (alpha == null) { + alpha = 1.0 / 8.0; + } + if (beta == null) { + beta = 1.0 / 8.0 / 32.0; + } + if (ramp == null) { + ramp = true; + } + return exports.action({ + press: function() { + var enable; + enable = this.script.mixxx.engine.scratchEnable; + return enable(deck, intervalsPerRev, rpm, alpha, beta, ramp); + }, + release: function() { + return this.script.mixxx.engine.scratchDisable(deck, ramp); + } + }); +}; + +exports.scratchTick = function(deck, transform) { + if (transform == null) { + transform = function(x) { + return x; + }; + } + return exports.call(function(ev) { + var engine; + engine = this.script.mixxx.engine; + return engine.scratchTick(deck, transform(ev.value)); + }); +}; + +exports.spinback = function() { + var args, deck; + deck = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.modifier().on('value', function() { + var ref3; + return (ref3 = this.script.mixxx.engine).spinback.apply(ref3, [deck, this.value].concat(slice.call(args))); + }); +}; + +exports.brake = function() { + var args, deck; + deck = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.modifier().on('value', function() { + var ref3; + return (ref3 = this.script.mixxx.engine).brake.apply(ref3, [deck, this.value].concat(slice.call(args))); + }); +}; + +exports.playhead = function(g) { + return exports.mapOut(g, "playposition").meter((function() { + var step; + step = 0; + return function(pos) { + var duration, engine; + engine = this.script.mixxx.engine; + duration = (function() { + switch (false) { + case !!engine.getValue(g, "play"): + return void 0; + case !(pos > .9): + return 5; + case !(pos > .8): + return 9; + case !(pos > .75): + return 13; + default: + return void 0; + } + })(); + if (duration != null) { + step = (step + 1) % duration; + if (step > duration / 2) { + return 0; + } else { + return pos * 127; + } + } else { + step = 0; + return pos * 127; + } + }; + })()); +}; + +exports.beatEffect = function(channel, type) { + var i, len, result, size, sizes; + if (type == null) { + type = ''; + } + sizes = ["0.0625", "0.125", "0.25", "0.5", "1", "2", "4", "8", "16", "32", "64"]; + result = exports.chooser({ + autoExclusive: true, + onDisable: function() { + var engine; + engine = this.script.mixxx.engine; + if (type !== 'roll' && engine.getValue(channel, "loop_enabled")) { + return engine.setValue(channel, "reloop_exit", true); + } + } + }); + for (i = 0, len = sizes.length; i < len; i++) { + size = sizes[i]; + result.add(channel, "beatloop" + type + "_" + size + "_activate", "beatloop_" + size + "_enabled"); + } + return result.select(4); +}; + +exports.stutter = function(group, beats) { + var tick; + if (beats == null) { + beats = 0.25; + } + tick = function() { + var engine, gain, newgain; + engine = this.script.mixxx.engine; + gain = engine.getValue(group, "pregain"); + newgain = gain > 0 ? (this._oldgain = gain, 0) : this._oldgain; + return engine.setValue(group, "pregain", newgain); + }; + return exports.action({ + press: function() { + var bpm, delta, engine; + engine = this.script.mixxx.engine; + bpm = engine.getValue(group, "bpm"); + delta = beats * 60000 / bpm; + if (this._timerHandle == null) { + this._timerHandle = this.script.registerHandler(bind(tick, this)); + } + return this._timerId != null ? this._timerId : this._timerId = engine.beginTimer(delta, this._timerHandle); + }, + release: function() { + var engine; + engine = this.script.mixxx.engine; + engine.stopTimer(this._timerId); + if (this._oldgain != null) { + engine.setValue(group, "pregain", this._oldgain); + } + delete this._timerId; + return delete this._oldgain; + } + }); +}; + + +},{"./transform":21,"./util":22,"./value":23,"events":10,"heterarchy":13,"underscore":16}],18:[function(require,module,exports){ +var assert, exports, konsole; + +assert = require('./util').assert; + +konsole = this; + +exports = konsole; + +if (konsole.log == null) { + konsole.log = function() { + return print("" + arguments); + }; +} + +if (konsole.info == null) { + konsole.info = konsole.log; +} + +if (konsole.warn == null) { + konsole.warn = konsole.log; +} + +if (konsole.error == null) { + konsole.error = konsole.log; +} + +if (konsole.time == null) { + konsole.time = function() { + return assert(False, "time not implemented in konsole"); + }; +} + +if (konsole.timeEnd == null) { + konsole.timeEnd = function() { + return assert(False, "time not implemented in konsole"); + }; +} + +if (konsole.trace == null) { + konsole.trace = function() { + var err; + err = new Error(); + err.name = "Trace"; + err.message = "" + arguments; + return konsole.error(err.stack); + }; +} + +if (konsole.dir == null) { + konsole.dir = function() { + return konsole.log(object + "\n"); + }; +} + +if (konsole.assert == null) { + konsole.assert = assert; +} + + +},{"./util":22}],19:[function(require,module,exports){ +var MIDI_CC, MIDI_NOTE_OFF, MIDI_NOTE_ON, MIDI_PITCHBEND, assert, behaviour, ccIds, event, extend, factory, hexStr, indent, joinLn, midiId, multi, noteIds, noteOnIds, pbIds, ref, ref1, some, xmlTag, + slice = [].slice, + extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + +multi = require('heterarchy').multi; + +ref = require('./util'), indent = ref.indent, hexStr = ref.hexStr, assert = ref.assert, factory = ref.factory, xmlTag = ref.xmlTag, joinLn = ref.joinLn; + +behaviour = require('./behaviour'); + +ref1 = require('underscore'), some = ref1.some, extend = ref1.extend; + +exports.MIDI_NOTE_ON = MIDI_NOTE_ON = 0x9; + +exports.MIDI_NOTE_OFF = MIDI_NOTE_OFF = 0x8; + +exports.MIDI_CC = MIDI_CC = 0xB; + +exports.MIDI_PITCHBEND = MIDI_PITCHBEND = 0xE; + +midiId = function(message, midino, channel) { + if (message == null) { + message = MIDI_CC; + } + if (midino == null) { + midino = 0; + } + if (channel == null) { + channel = 0; + } + return { + message: message, + midino: midino, + channel: channel, + status: function() { + return (this.message << 4) | this.channel; + }, + configMidi: function(depth) { + return (indent(depth)) + "" + (hexStr(this.status())) + "\n" + (indent(depth)) + "" + (hexStr(this.midino)) + ""; + } + }; +}; + +exports.midiId = midiId; + +pbIds = function() { + return [midiId.apply(null, [MIDI_PITCHBEND, 0].concat(slice.call(arguments)))]; +}; + +noteOnIds = function() { + return [midiId.apply(null, [MIDI_NOTE_ON].concat(slice.call(arguments)))]; +}; + +noteIds = function() { + return [midiId.apply(null, [MIDI_NOTE_ON].concat(slice.call(arguments))), midiId.apply(null, [MIDI_NOTE_OFF].concat(slice.call(arguments)))]; +}; + +ccIds = function() { + return [midiId.apply(null, [MIDI_CC].concat(slice.call(arguments)))]; +}; + +exports.pbIds = pbIds; + +exports.noteOnIds = noteOnIds; + +exports.noteIds = noteIds; + +exports.ccIds = ccIds; + +exports.event = event = function(channel, control, value, status, group) { + return { + channel: channel, + control: control, + value: (function() { + switch (status >> 4) { + case MIDI_PITCHBEND: + return (value * 128.0 + control) / 128.0; + default: + return value; + } + })(), + status: status, + group: group, + message: function() { + return this.status >> 4; + }, + pressed: status >> 4 !== MIDI_NOTE_OFF && value + }; +}; + +exports.Control = (function(superClass) { + extend1(Control, superClass); + + function Control() { + var args, ids; + ids = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this.ids = ids != null ? ids : [midiId()]; + this["else"] = (function(_this) { + return function() { + return _this._else.apply(_this, arguments); + }; + })(this); + this["else"].when = (function(_this) { + return function() { + return _this._elseWhen.apply(_this, arguments); + }; + })(this); + this.else_ = this["else"]; + Control.__super__.constructor.call(this); + if (!(this.ids instanceof Array)) { + this.ids = ccIds.apply(null, [this.ids].concat(slice.call(args))); + } + this._behaviours = []; + if (typeof this._controlRegistry === "function") { + this._controlRegistry(this); + } + } + + Control.prototype.does = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit); + this._behaviours.push(this.registerBehaviour(behaviour.toBehaviour.apply(behaviour, args))); + return this; + }; + + Control.prototype.when = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit); + this._lastWhen = behaviour.when.apply(behaviour, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + return this; + }; + + Control.prototype._elseWhen = function() { + var args, ref2; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastWhen != null, "'elseWhen' must be preceded by 'when' or 'elseWhen'"); + this._lastWhen = (ref2 = this._lastWhen["else"]).when.apply(ref2, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + return this; + }; + + Control.prototype._else = function() { + var args, ref2; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastWhen != null, "'else' must be preceded by 'when' or 'elseWhen'"); + this._lastWhen = (ref2 = this._lastWhen)["else"].apply(ref2, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + this._lastWhen = void 0; + return this; + }; + + Control.prototype.init = function(script) { + var b, i, len, ref2; + this.script = script; + assert(!this._isInit); + ref2 = this._behaviours; + for (i = 0, len = ref2.length; i < len; i++) { + b = ref2[i]; + b.enable(script, this); + } + return this._isInit = true; + }; + + Control.prototype.shutdown = function(script) { + var b, i, len, ref2; + assert(script === this.script); + assert(this._isInit); + ref2 = this._behaviours; + for (i = 0, len = ref2.length; i < len; i++) { + b = ref2[i]; + b.disable(script, this); + } + this._isInit = false; + return delete this.script; + }; + + Control.prototype.registerBehaviour = function(b) { + return b; + }; + + Control.prototype.configInputs = function(depth, script) {}; + + Control.prototype.configOutputs = function(depth, script) {}; + + Control.prototype.setRegistry = function(registry) { + assert((this._controlRegistry == null) || (registry == null)); + return this._controlRegistry = registry; + }; + + return Control; + +})(behaviour.Actor); + +exports.InControl = (function(superClass) { + extend1(InControl, superClass); + + function InControl() { + return InControl.__super__.constructor.apply(this, arguments); + } + + InControl.prototype.init = function(script) { + InControl.__super__.init.apply(this, arguments); + if (this.needsHandler()) { + return script.registerHandler(((function(_this) { + return function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return _this.emit('event', event.apply(null, args)); + }; + })(this)), this.handlerId()); + } + }; + + InControl.prototype.option = function() { + var beh, i, len, options, ref2, ref3; + options = 1 <= arguments.length ? slice.call(arguments, 0) : []; + (ref2 = (this._options != null ? this._options : this._options = [])).push.apply(ref2, options); + ref3 = this._behaviours; + for (i = 0, len = ref3.length; i < len; i++) { + beh = ref3[i]; + beh.option.apply(beh, options); + } + return this; + }; + + InControl.property('options', function() { + return behaviour.makeOptionsChooser(this); + }); + + InControl.prototype.registerBehaviour = function(beh) { + if (this._options != null) { + beh.option.apply(beh, this._options); + } + return beh; + }; + + InControl.prototype.needsHandler = function() { + return this._behaviours.length !== 1 || !this._behaviours[0].directInMapping() || some(this._behaviours[0]._options, function(opt) { + return !opt.name; + }); + }; + + InControl.prototype.handlerId = function() { + return "x" + (this.ids[0].status().toString(16)) + "_x" + (this.ids[0].midino.toString(16)); + }; + + InControl.prototype.configInputs = function(depth, script) { + var id, mapping; + if (this.needsHandler()) { + mapping = { + group: "[Master]", + key: script.handlerKey(this.handlerId()) + }; + } else { + mapping = this._behaviours[0].directInMapping(); + } + return joinLn((function() { + var i, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + results.push(this.configInMapping(depth, mapping, id)); + } + return results; + }).call(this)); + }; + + InControl.prototype.configInMapping = function(depth, mapping, id) { + return (indent(depth)) + "\n" + (indent(depth + 1)) + "" + mapping.group + "\n" + (indent(depth + 1)) + "" + mapping.key + "\n" + (id.configMidi(depth + 1)) + "\n" + (indent(depth + 1)) + "\n" + (this.configOptions(depth + 2)) + "\n" + (indent(depth + 1)) + "\n" + (indent(depth)) + ""; + }; + + InControl.prototype.configOptions = function(depth) { + var opt, ref2; + if (this.needsHandler()) { + return (indent(depth)) + ""; + } else if (((ref2 = this._behaviours[0]._options) != null ? ref2.length : void 0) > 0) { + return joinLn((function() { + var i, len, ref3, results; + ref3 = this._behaviours[0]._options; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (opt.name != null) { + results.push((indent(depth)) + "<" + opt.name + "/>"); + } else { + results.push(void 0); + } + } + return results; + }).call(this)); + } else { + return (indent(depth)) + ""; + } + }; + + return InControl; + +})(exports.Control); + +exports.OutControl = (function(superClass) { + extend1(OutControl, superClass); + + function OutControl() { + OutControl.__super__.constructor.apply(this, arguments); + this._states = { + on: 0x7f, + off: 0x00, + disable: 0x00 + }; + } + + OutControl.prototype.send = function(state) { + return this.doSend(state); + }; + + OutControl.prototype.states = function(states) { + extend(this._states, states); + return this; + }; + + OutControl.prototype.doSend = function(state) { + var i, id, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + if (id.message !== MIDI_NOTE_OFF) { + if (state in this._states) { + results.push(this.script.mixxx.midi.sendShortMsg(id.status(), id.midino, this._states[state])); + } else { + results.push(this.script.mixxx.midi.sendShortMsg(id.status(), id.midino, state)); + } + } else { + results.push(void 0); + } + } + return results; + }; + + OutControl.prototype.init = function() { + if (!this.needsSend()) { + this.send = void 0; + } + return OutControl.__super__.init.apply(this, arguments); + }; + + OutControl.prototype.shutdown = function() { + this.doSend('disable'); + return OutControl.__super__.shutdown.apply(this, arguments); + }; + + OutControl.prototype.needsSend = function() { + return this._behaviours.length !== 1 || !this._behaviours[0].directOutMapping(); + }; + + OutControl.prototype.configOutputs = function(depth, script) { + var id, mapping; + mapping = !this.needsSend() && this._behaviours[0].directOutMapping(); + if (mapping) { + return joinLn((function() { + var i, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + results.push(this.configOutMapping(depth, mapping, id)); + } + return results; + }).call(this)); + } + }; + + OutControl.prototype.configOutMapping = function(depth, mapping, id) { + var options; + if (id.message !== MIDI_NOTE_OFF) { + options = joinLn([xmlTag('minimum', mapping.minimum, depth + 1), xmlTag('maximum', mapping.maximum, depth + 1)]); + return (indent(depth)) + "\n" + (indent(depth + 1)) + "" + mapping.group + "\n" + (indent(depth + 1)) + "" + mapping.key + "\n" + (id.configMidi(depth + 1)) + "\n" + (indent(depth + 1)) + "" + (hexStr(this._states['on'])) + "\n" + (indent(depth + 1)) + "" + (hexStr(this._states['off'])) + "\n" + options + "\n" + (indent(depth)) + ""; + } + }; + + return OutControl; + +})(exports.Control); + +exports.input = factory(exports.InControl); + +exports.output = factory(exports.OutControl); + +exports.InOutControl = (function(superClass) { + extend1(InOutControl, superClass); + + function InOutControl() { + return InOutControl.__super__.constructor.apply(this, arguments); + } + + return InOutControl; + +})(multi(exports.InControl, exports.OutControl)); + +exports.control = factory(exports.InOutControl); + + +},{"./behaviour":17,"./util":22,"heterarchy":13,"underscore":16}],20:[function(require,module,exports){ +(function (process){ +var Control, S, _, assert, basename, bind, catching, flatten, indent, issubclass, mro, ref, ref1, ref2, xmlEscape, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, + slice = [].slice; + +ref = require('underscore'), flatten = ref.flatten, bind = ref.bind; + +ref1 = require('heterarchy'), issubclass = ref1.issubclass, mro = ref1.mro; + +Control = require('./control').Control; + +ref2 = require('./util'), indent = ref2.indent, xmlEscape = ref2.xmlEscape, catching = ref2.catching, assert = ref2.assert; + +require('./console'); + +basename = require('path').basename; + +S = require('string'); + +_ = require('underscore'); + +exports.nameFromFilename = function(fname) { + var extensions, name; + extensions = [".mixco.coffee", ".mixco.litcoffee", ".mixco.js", ".mixco"]; + fname = basename(fname); + assert(_.some(extensions, function(x) { + return S(fname).endsWith(x); + }), "Script file name: " + fname + " must end in one of: " + extensions); + name = extensions.reduce((function(fname, ext) { + return fname.replace(ext, ""); + }), fname); + assert(name.match(/^[a-zA-Z_$][0-9a-zA-Z_$].*$/, "Script name must be a valid JavaScript identifier")); + return name; +}; + +exports.register = function(targetModule, scriptTypeOrDefinition) { + var instance, name, scriptType; + name = targetModule.filename != null ? exports.nameFromFilename(targetModule.filename) : typeof MIXCO_SCRIPT_FILENAME !== "undefined" && MIXCO_SCRIPT_FILENAME !== null ? exports.nameFromFilename(MIXCO_SCRIPT_FILENAME) : assert(false, "Invalid script"); + scriptType = issubclass(scriptTypeOrDefinition, exports.Script) ? scriptTypeOrDefinition : exports.create(scriptTypeOrDefinition); + instance = new scriptType; + instance.__registeredName = name; + targetModule.exports[name] = instance; + if (targetModule === require.main) { + return instance.main(); + } +}; + +exports.create = function(scriptDefinition) { + var NewScript, constructor, init, k, shutdown, special, v; + assert(scriptDefinition.constructor != null, "Script definition must have a constructor"); + constructor = scriptDefinition.constructor, init = scriptDefinition.init, shutdown = scriptDefinition.shutdown; + NewScript = (function(superClass) { + extend(NewScript, superClass); + + function NewScript() { + NewScript.__super__.constructor.apply(this, arguments); + try { + Control.prototype.setRegistry(bind(this.add, this)); + constructor.apply(this, arguments); + } finally { + Control.prototype.setRegistry(null); + } + this; + } + + NewScript.prototype.init = function() { + var ref3; + if ((ref3 = this.preinit) != null) { + ref3.apply(this, arguments); + } + NewScript.__super__.init.apply(this, arguments); + return init != null ? init.apply(this, arguments) : void 0; + }; + + NewScript.prototype.shutdown = function() { + var ref3; + if (shutdown != null) { + shutdown.apply(this, arguments); + } + NewScript.__super__.shutdown.apply(this, arguments); + return (ref3 = this.postshutdown) != null ? ref3.apply(this, arguments) : void 0; + }; + + return NewScript; + + })(exports.Script); + special = ['name', 'constructor', 'init', 'shutdown']; + for (k in scriptDefinition) { + v = scriptDefinition[k]; + if (indexOf.call(special, k) < 0) { + NewScript.prototype[k] = v; + } + } + return NewScript; +}; + +exports.Script = (function() { + Script.prototype.info = { + name: "[mixco] Generic Script", + author: "Juan Pedro Bolivar Puente ", + description: "", + forums: "", + wiki: "" + }; + + Script.property('name', { + get: function() { + assert(this.__registeredName, "Script must be registered"); + return this.__registeredName; + } + }); + + Script.prototype.add = function() { + var controls, ref3; + controls = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit, "Can only add controls in constructor"); + return (ref3 = this.controls).push.apply(ref3, flatten(controls)); + }; + + Script.prototype.init = catching(function() { + var control, i, len, ref3, results; + this._isInit = true; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.init(this)); + } + return results; + }); + + Script.prototype.shutdown = catching(function() { + var control, i, len, ref3; + ref3 = this.controls; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + control.shutdown(this); + } + return delete this._isInit; + }); + + function Script() { + this.controls = []; + } + + Script.prototype.mixxx = { + engine: (typeof engine !== "undefined" && engine !== null ? engine : void 0), + midi: (typeof midi !== "undefined" && midi !== null ? midi : void 0), + script: (typeof script !== "undefined" && script !== null ? script : void 0) + }; + + Script.prototype.main = function() { + var arg, i, len, ref3, results; + ref3 = process.argv; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + arg = ref3[i]; + if (arg === '-h' || arg === '--help') { + console.info(this.help()); + break; + } + if (arg === '-g' || arg === '--generate-config') { + console.info(this.config()); + break; + } else { + results.push(void 0); + } + } + return results; + }; + + Script.prototype.help = function() { + return "Mixxx Controller Script\n=======================\n\nName: " + this.info.name + "\nAuthor: " + this.info.author + "\nDescription: " + this.info.description + "\nForums: " + this.info.description + "\n\nUsage\n-----\n1. Generate Mixxx config:\n coffee " + this.name + ".coffee -g > " + this.name + ".xml\n\n2. Generate Mixxx script:\n coffee -c " + this.name + ".coffee"; + }; + + Script.prototype.config = function() { + return "\n\n" + (indent(1)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.name)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.author)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.description)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.wiki)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.forums)) + "\n" + (indent(1)) + "\n" + (indent(1)) + "\n" + (indent(2)) + "\n" + (indent(3)) + "\n" + (indent(2)) + "\n" + (indent(2)) + "\n" + (this.configInputs(3)) + "\n" + (indent(2)) + "\n" + (indent(2)) + "\n" + (this.configOutputs(3)) + "\n" + (indent(2)) + "\n" + (indent(1)) + "\n"; + }; + + Script.prototype.configInputs = function(depth) { + var control; + return ((function() { + var i, len, ref3, results; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.configInputs(depth, this)); + } + return results; + }).call(this)).filter(function(x) { + return x; + }).join('\n'); + }; + + Script.prototype.configOutputs = function(depth) { + var control; + return ((function() { + var i, len, ref3, results; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.configOutputs(depth, this)); + } + return results; + }).call(this)).filter(function(x) { + return x; + }).join('\n'); + }; + + Script.prototype._nextCallbackId = 1; + + Script.prototype.registerHandler = function(callback, id) { + var handlerName; + if (id == null) { + id = void 0; + } + id || (id = this._nextCallbackId++); + handlerName = "__handle_" + id; + assert(!this[handlerName], "Handlers can be registered only once (" + handlerName + ")"); + this[handlerName] = callback; + return this.handlerKey(id); + }; + + Script.prototype.handlerKey = function(id) { + if (id == null) { + id = void 0; + } + if (id == null) { + id = this._nextCallbackId - 1; + } + return this.name + ".__handle_" + id; + }; + + return Script; + +})(); + + +}).call(this,require('_process')) +},{"./console":18,"./control":19,"./util":22,"_process":12,"heterarchy":13,"path":11,"string":15,"underscore":16}],21:[function(require,module,exports){ +var binaryT, centeredT, defaultT, identityT, linearT, momentaryT, + slice = [].slice; + +exports.identity = function(v) { + return v; +}; + +exports.identity.inverse = exports.identity; + +exports.momentary = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } +}; + +exports.momentary.inverse = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } +}; + +exports.binary = function(v, oldv) { + if (v > 0) { + return !oldv; + } else { + return null; + } +}; + +exports.binary.inverse = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } +}; + +exports.linear = function(v, min, max) { + return min + v * (max - min); +}; + +exports.linear.inverse = function(v, min, max) { + return (v - min) / (max - min); +}; + +exports.centered = function(v, min, center, max) { + if (v < .5) { + return linear(v * 2, min, center); + } else { + return linear((v - .5) * 2, center, max); + } +}; + +exports.centered.inverse = function(v, min, center, max) { + if (v < center) { + return 0.5 * linear.inverse(v, min, center); + } else { + return 0.5 + 0.5 * linear.inverse(v, center, max); + } +}; + +exports.transform = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.value / 127.0].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return 127 * f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; +}; + +exports.transformI = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.value].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; +}; + +exports.transformB = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.pressed / 127.0].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return 127 * f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; +}; + +exports.identityT = identityT = exports.transformI(exports.identity); + +exports.momentaryT = momentaryT = exports.transformB(exports.momentary); + +exports.binaryT = binaryT = exports.transformB(exports.binary); + +exports.linearT = linearT = function() { + return exports.transform.apply(exports, [exports.linear].concat(slice.call(arguments))); +}; + +exports.centeredT = centeredT = function() { + return exports.transform.apply(exports, [exports.centered].concat(slice.call(arguments))); +}; + +exports.defaultT = defaultT = linearT(0.0, 1.0); + +exports.mappings = { + "beatloop_0.0625_activate": momentaryT, + "beatloop_0.0625_toggle": momentaryT, + "beatloop_0.125_activate": momentaryT, + "beatloop_0.125_toggle": momentaryT, + "beatloop_0.5_activate": momentaryT, + "beatloop_0.5_toggle": momentaryT, + "beatlooproll_0.0625_activate": momentaryT, + "beatlooproll_0.125_activate": momentaryT, + "beatlooproll_0.5_activate": momentaryT, + back: momentaryT, + balance: linearT(-1.0, 1.0), + beatloop_16_activate: momentaryT, + beatloop_16_toggle: momentaryT, + beatloop_1_activate: momentaryT, + beatloop_1_toggle: momentaryT, + beatloop_2_activate: momentaryT, + beatloop_2_toggle: momentaryT, + beatloop_32_activate: momentaryT, + beatloop_32_toggle: momentaryT, + beatloop_4_activate: momentaryT, + beatloop_4_toggle: momentaryT, + beatloop_8_activate: momentaryT, + beatloop_8_toggle: momentaryT, + beatlooproll_16_activate: momentaryT, + beatlooproll_1_activate: momentaryT, + beatlooproll_2_activate: momentaryT, + beatlooproll_32_activate: momentaryT, + beatlooproll_4_activate: momentaryT, + beatlooproll_8_activate: momentaryT, + beatloop_double: momentaryT, + beatloop_halve: momentaryT, + beatjump_4_forward: momentaryT, + beatjump_4_backward: momentaryT, + beatjump_1_forward: momentaryT, + beatjump_1_backward: momentaryT, + beats_translate_curpos: momentaryT, + beatsync: momentaryT, + beatsync_tempo: momentaryT, + crossfader: linearT(-1.0, 1.0), + cue_default: momentaryT, + eject: momentaryT, + enabled: binaryT, + filterHigh: centeredT(0.0, 1.0, 4.0), + filterHighKill: binaryT, + filterLow: centeredT(0.0, 1.0, 4.0), + filterLowKill: binaryT, + filterMid: centeredT(0.0, 1.0, 4.0), + filterMidKill: binaryT, + fwd: momentaryT, + headMix: centeredT(-1.0, 1.0), + headVolume: centeredT(0.0, 1.0, 5.0), + hotcue_1_activate: momentaryT, + hotcue_1_clear: momentaryT, + hotcue_2_activate: momentaryT, + hotcue_2_clear: momentaryT, + hotcue_3_activate: momentaryT, + hotcue_3_clear: momentaryT, + hotcue_4_activate: momentaryT, + hotcue_4_clear: momentaryT, + hotcue_5_activate: momentaryT, + hotcue_5_clear: momentaryT, + hotcue_6_activate: momentaryT, + hotcue_6_clear: momentaryT, + hotcue_7_activate: momentaryT, + hotcue_7_clear: momentaryT, + jog: identityT, + keylock: binaryT, + lfoDelay: linearT(50.0, 10000.0), + lfoDepth: defaultT, + lfoPeriod: linearT(50000.0, 2000000.0), + LoadSelectedTrack: momentaryT, + loop_double: momentaryT, + loop_enabled: binaryT, + loop_end_position: linearT, + loop_halve: momentaryT, + loop_in: momentaryT, + loop_out: momentaryT, + loop_start_position: linearT, + play: binaryT, + playposition: linearT(0.0, 1.0), + plf: binaryT, + pregain: centeredT(0.0, 1.0, 4.0), + pregain_toggle: binaryT, + rate: linearT(-1.0, 1.0), + rate_temp_down: momentaryT, + rate_temp_down_small: momentaryT, + rate_temp_up: momentaryT, + rate_temp_up_small: momentaryT, + reverse: binaryT, + scratch2: linearT(-3.0, 3.0), + scratch2_enable: binaryT, + SelectNextPlaylist: momentaryT, + SelectNextTrack: momentaryT, + SelectPrevPlaylist: momentaryT, + SelectPrevTrack: momentaryT, + SelectTrackKnob: identityT, + slip_enabled: binaryT, + super1: linearT(0.0, 10.0), + talkover: binaryT, + ToggleSelectedSidebarItem: momentaryT, + volume: defaultT, + VuMeter: defaultT, + VuMeterL: defaultT, + VuMeterR: defaultT, + wheel: linearT(-3.0, 3.0) +}; + + +},{}],22:[function(require,module,exports){ +Function.prototype.property = function(prop, desc) { + if (desc instanceof Function) { + desc = { + get: desc + }; + } + return Object.defineProperty(this.prototype, prop, desc); +}; + +Number.prototype.clamp = function(min, max) { + return Math.min(Math.max(this, min), max); +}; + +Number.prototype.sign = function() { + if (this < 0) { + return -1; + } else { + return 1; + } +}; + +Array.prototype.equals = function(other) { + return this.length === other.length && this.every(function(elem, i) { + return elem === other[i]; + }); +}; + +exports.copy = function(a, b) { + var k, v; + if (b == null) { + b = {}; + } + for (k in a) { + v = a[k]; + b[k] = v; + } + return b; +}; + +exports.catching = function(f) { + return function() { + var err, error1; + try { + return f.apply(this, arguments); + } catch (error1) { + err = error1; + return console.log("ERROR: " + err); + } + }; +}; + +exports.assert = function(value, error) { + if (error == null) { + error = void 0; + } + if (!value) { + throw new Error(error != null ? error : "Assertion failed"); + } +}; + +exports.xmlEscape = function(str) { + var ref; + return (ref = str != null ? str.replace('&', '&').replace('"', '"').replace('>', '>').replace('<', '<') : void 0) != null ? ref : ''; +}; + +exports.indent = function(depth) { + return Array(depth * 4).join(" "); +}; + +exports.hexStr = function(number) { + return "0x" + (number.toString(16)); +}; + +exports.xmlTag = function(str, value, indent) { + if (indent == null) { + indent = 0; + } + if (value != null) { + return (exports.indent(indent)) + "<" + str + ">" + value + ""; + } else { + return ""; + } +}; + +exports.joinLn = function(lines) { + return lines.filter(function(x) { + return x; + }).join('\n'); +}; + +exports.factory = function(Klass) { + return function() { + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(Klass, arguments, function(){}); + }; +}; + + +},{}],23:[function(require,module,exports){ +var events, factory, util, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + slice = [].slice; + +events = require('events'); + +util = require('./util'); + +factory = util.factory; + +exports.Value = (function(superClass) { + extend(Value, superClass); + + function Value(arg) { + var initial; + initial = (arg != null ? arg : {}).initial; + Value.__super__.constructor.apply(this, arguments); + this.setMaxListeners(0); + if (initial != null) { + this.value = initial; + } + } + + Value.property('value', { + get: function() { + return this._value; + }, + set: function(newValue) { + return this.setValue(newValue); + } + }); + + Value.prototype.setValue = function(newValue) { + if (this._value !== newValue) { + this._value = newValue; + this.emit('value', newValue); + } + return this._value; + }; + + return Value; + +})(events.EventEmitter); + +exports.value = factory(exports.Value); + +exports.Const = (function() { + Const.prototype.value = void 0; + + function Const(initial) { + if (initial == null) { + initial = void 0; + } + this.value = initial; + } + + Const.prototype.on = function() {}; + + Const.prototype.addListener = function() {}; + + Const.prototype.removeListener = function() {}; + + Const.prototype.listeners = function() { + return []; + }; + + return Const; + +})(); + +exports["const"] = factory(exports.Const); + +exports.Reduce = (function(superClass) { + extend(Reduce, superClass); + + function Reduce() { + var i, len, reduced, reducer, ref, v; + reducer = arguments[0], reduced = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this.reducer = reducer; + this.reduced = reduced; + Reduce.__super__.constructor.call(this); + ref = this.reduced; + for (i = 0, len = ref.length; i < len; i++) { + v = ref[i]; + v.on('value', (function(_this) { + return function() { + return _this.update(); + }; + })(this)); + } + this.update(); + } + + Reduce.prototype.update = function() { + return this.value = this.reduced.reduce((function(_this) { + return function(a, b) { + return exports["const"](_this.reducer(a.value, b.value)); + }; + })(this)).value; + }; + + return Reduce; + +})(exports.Value); + +exports.reduce = factory(exports.Reduce); + +exports.and = function() { + return exports.reduce.apply(exports, [(function(a, b) { + return a && b; + })].concat(slice.call(arguments))); +}; + +exports.or = function() { + return exports.reduce.apply(exports, [(function(a, b) { + return a || b; + })].concat(slice.call(arguments))); +}; + +exports.Transform = (function(superClass) { + extend(Transform, superClass); + + function Transform(transformer, transformed) { + this.transformer = transformer; + this.transformed = transformed; + Transform.__super__.constructor.call(this); + this.transformed.on('value', (function(_this) { + return function() { + return _this.update(); + }; + })(this)); + this.update(); + } + + Transform.prototype.update = function() { + return this.value = this.transformer(this.transformed.value); + }; + + return Transform; + +})(exports.Value); + +exports.transform = factory(exports.Transform); + +exports.not = function() { + return exports.transform.apply(exports, [(function(a) { + return !a; + })].concat(slice.call(arguments))); +}; + + +},{"./util":22,"events":10}]},{},[1]); + +korg_nanokontrol2 = require('/home/raskolnikov/dev/mixco/script/korg_nanokontrol2.mixco').korg_nanokontrol2; +/* End of Mixco generated script */ \ No newline at end of file diff --git a/res/controllers/korg_nanokontrol2.mixco.output.midi.xml b/res/controllers/korg_nanokontrol2.mixco.output.midi.xml new file mode 100644 index 000000000000..59ba1fd706bb --- /dev/null +++ b/res/controllers/korg_nanokontrol2.mixco.output.midi.xml @@ -0,0 +1,590 @@ + + + + Korg Nanokontrol 2 (alternative) + Juan Pedro Bolivar Puente <raskolnikov@gnu.org> + Controller mapping for Korg Nanokontrol 2. Unlike +other scripts that are oriented as a secondary +controller, this provides basic deck controls, being +usable as primary interface. + https://sinusoid.es/mixco/script/korg_nanokontrol2.mixco.html + https://github.com/arximboldi/mixco/issues + + + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x2e + 0xb0 + 0x2e + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x3a + 0xb0 + 0x3a + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x3b + 0xb0 + 0x3b + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x2b + 0xb0 + 0x2b + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x2c + 0xb0 + 0x2c + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x3c + 0xb0 + 0x3c + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x3d + 0xb0 + 0x3d + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x3e + 0xb0 + 0x3e + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x2a + 0xb0 + 0x2a + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x29 + 0xb0 + 0x29 + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x2d + 0xb0 + 0x2d + + + + + + [Master] + headVolume + 0xb0 + 0x6 + + + + + + [Master] + headMix + 0xb0 + 0x5 + + + + + + [Master] + crossfader + 0xb0 + 0x2 + + + + + + [Master] + balance + 0xb0 + 0x1 + + + + + + [Channel1] + filterLow + 0xb0 + 0x13 + + + + + + [Channel1] + filterMid + 0xb0 + 0x12 + + + + + + [Channel1] + filterHigh + 0xb0 + 0x11 + + + + + + [Channel1] + pregain + 0xb0 + 0x10 + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x23 + 0xb0 + 0x23 + + + + + + [Channel1] + cue_default + 0xb0 + 0x33 + + + + + + [Channel1] + play + 0xb0 + 0x43 + + + + + + [Channel1] + volume + 0xb0 + 0x3 + + + + + + [Channel1] + bpm_tap + 0xb0 + 0x20 + + + + + + [Channel1] + keylock + 0xb0 + 0x30 + + + + + + [Channel1] + beats_translate_curpos + 0xb0 + 0x40 + + + + + + [Channel1] + rate + 0xb0 + 0x0 + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x22 + 0xb0 + 0x22 + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x21 + 0xb0 + 0x21 + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x32 + 0xb0 + 0x32 + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x31 + 0xb0 + 0x31 + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x42 + 0xb0 + 0x42 + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x41 + 0xb0 + 0x41 + + + + + + [Channel2] + filterLow + 0xb0 + 0x14 + + + + + + [Channel2] + filterMid + 0xb0 + 0x15 + + + + + + [Channel2] + filterHigh + 0xb0 + 0x16 + + + + + + [Channel2] + pregain + 0xb0 + 0x17 + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x24 + 0xb0 + 0x24 + + + + + + [Channel2] + cue_default + 0xb0 + 0x34 + + + + + + [Channel2] + play + 0xb0 + 0x44 + + + + + + [Channel2] + volume + 0xb0 + 0x4 + + + + + + [Channel2] + bpm_tap + 0xb0 + 0x27 + + + + + + [Channel2] + keylock + 0xb0 + 0x37 + + + + + + [Channel2] + beats_translate_curpos + 0xb0 + 0x47 + + + + + + [Channel2] + rate + 0xb0 + 0x7 + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x25 + 0xb0 + 0x25 + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x26 + 0xb0 + 0x26 + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x35 + 0xb0 + 0x35 + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x36 + 0xb0 + 0x36 + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x45 + 0xb0 + 0x45 + + + + + + [Master] + korg_nanokontrol2.__handle_xb0_x46 + 0xb0 + 0x46 + + + + + + + + [Channel1] + pfl + 0xb0 + 0x23 + 0x7f + 0x0 + 1 + + + [Channel1] + cue_indicator + 0xb0 + 0x33 + 0x7f + 0x0 + 1 + + + [Channel1] + play + 0xb0 + 0x43 + 0x7f + 0x0 + 1 + + + [Channel1] + beat_active + 0xb0 + 0x20 + 0x7f + 0x0 + 1 + + + [Channel1] + keylock + 0xb0 + 0x30 + 0x7f + 0x0 + 1 + + + [Channel1] + beats_translate_curpos + 0xb0 + 0x40 + 0x7f + 0x0 + 1 + + + [Channel2] + pfl + 0xb0 + 0x24 + 0x7f + 0x0 + 1 + + + [Channel2] + cue_indicator + 0xb0 + 0x34 + 0x7f + 0x0 + 1 + + + [Channel2] + play + 0xb0 + 0x44 + 0x7f + 0x0 + 1 + + + [Channel2] + beat_active + 0xb0 + 0x27 + 0x7f + 0x0 + 1 + + + [Channel2] + keylock + 0xb0 + 0x37 + 0x7f + 0x0 + 1 + + + [Channel2] + beats_translate_curpos + 0xb0 + 0x47 + 0x7f + 0x0 + 1 + + + + diff --git a/res/controllers/maudio_xponent.mixco.output.js b/res/controllers/maudio_xponent.mixco.output.js new file mode 100644 index 000000000000..826896f03a19 --- /dev/null +++ b/res/controllers/maudio_xponent.mixco.output.js @@ -0,0 +1,8271 @@ +/* + * File generated with Mixco framework version: 2.0.2 + * More info at: + */ + +MIXCO_SCRIPT_FILENAME = '/home/raskolnikov/dev/mixco/script/maudio_xponent.mixco.litcoffee'; + +require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 64 ? v1 - 128 : v1); + }); + add('button', function(v) { + return v !== 0; + }); + add('switch', function(v) { + return 1; + }); + result.switch_ = result["switch"]; + add('hercjog', function(v1, v0) { + return v0 + (v1 > 64 ? v1 - 128 : v1); + }); + add('spread64', function(v) { + return v - 64; + }); + add('selectknob', function(v) { + if (v > 64) { + return v - 128; + } else { + return v; + } + }); + return add('soft-takeover', 'softTakeover', { + enable: function(b) { + if (isinstance(b, exports.MapIn)) { + return b.script.mixxx.engine.softTakeover(b.group, b.key, true); + } + }, + disable: function(b) { + if (isinstance(b, exports.MapIn)) { + return b.script.mixxx.engine.softTakeover(b.group, b.key, false); + } + } + }); + })(); + + exports.makeOptionsChooser = makeOptionsChooser = function(obj) { + var key, opt, result; + result = {}; + for (key in option) { + opt = option[key]; + Object.defineProperty(result, key, { + get: (function(opt) { + return function() { + return obj.option(opt); + }; + })(opt) + }); + } + return result; + }; + + exports.Behaviour = (function(superClass) { + extend1(Behaviour, superClass); + + function Behaviour() { + return Behaviour.__super__.constructor.apply(this, arguments); + } + + Behaviour.prototype.enable = function(script, actor) { + var i, len, opt, ref3, results; + assert(this.actor == null); + assert(this.script == null); + this.script = script; + this.actor = actor; + this._eventListener = (function(_this) { + return function(ev) { + var i, len, opt, ref3; + if (_this._options != null) { + ev = copy(ev); + ref3 = _this._options; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (typeof opt.process === "function") { + opt.process(ev, _this); + } + } + } + return _this.onMidiEvent(ev); + }; + })(this); + actor.on('event', this._eventListener); + if (this._options != null) { + ref3 = this._options; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + results.push(typeof opt.enable === "function" ? opt.enable(this) : void 0); + } + return results; + } + }; + + Behaviour.prototype.disable = function(script, actor) { + var i, len, opt, ref3; + assert(this.script === script); + assert(this.actor === actor); + if (this._options != null) { + ref3 = this._options; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (typeof opt.disable === "function") { + opt.disable(this); + } + } + } + actor.removeListener('event', this._eventListener); + delete this.script; + return delete this.actor; + }; + + Behaviour.prototype.option = function() { + var i, len, opt, options, ref3; + options = 1 <= arguments.length ? slice.call(arguments, 0) : []; + for (i = 0, len = options.length; i < len; i++) { + opt = options[i]; + assert(opt); + } + (ref3 = (this._options != null ? this._options : this._options = [])).push.apply(ref3, map(options, toOption)); + return this; + }; + + Behaviour.property('options', function() { + return makeOptionsChooser(this); + }); + + Behaviour.prototype.directInMapping = function() { + return null; + }; + + Behaviour.prototype.directOutMapping = function() { + return null; + }; + + Behaviour.prototype.onMidiEvent = function(ev) { + return null; + }; + + Behaviour.prototype.getMidiValue = function() { + return this.value; + }; + + Behaviour.property('midiValue', function() { + return this.getMidiValue(); + }); + + return Behaviour; + + })(value.Value); + + exports.Call = (function(superClass) { + extend1(Call, superClass); + + function Call(onMidiEvent) { + this.onMidiEvent = onMidiEvent; + Call.__super__.constructor.call(this); + } + + return Call; + + })(exports.Behaviour); + + exports.call = factory(exports.Call); + + exports.Output = (function(superClass) { + extend1(Output, superClass); + + Output.prototype.minimum = 1; + + Output.prototype.maximum = void 0; + + function Output() { + Output.__super__.constructor.apply(this, arguments); + this.output = value.value(); + } + + Output.prototype.enable = function() { + Output.__super__.enable.apply(this, arguments); + if (this.actor.send != null) { + if (this._updateOutputCallback == null) { + this._updateOutputCallback = (function(_this) { + return function() { + return _this.updateOutput(); + }; + })(this); + } + this.output.on('value', this._updateOutputCallback); + } + if (this.actor.doSend != null) { + return this.updateOutput(this.actor.doSend); + } + }; + + Output.prototype.disable = function() { + if (this._updateOutputCallback != null) { + this.removeListener('value', this._updateOutputCallback); + this._updateOutputCallback = void 0; + } + return Output.__super__.disable.apply(this, arguments); + }; + + Output.prototype.updateOutput = function(sendfn) { + if (sendfn == null) { + sendfn = null; + } + if (sendfn == null) { + sendfn = this.actor.send; + } + return sendfn.call(this.actor, (Math.abs(this.output.value) >= this.minimum ? 'on' : 'off')); + }; + + return Output; + + })(exports.Behaviour); + + exports.Transform = (function(superClass) { + extend1(Transform, superClass); + + function Transform(transformer1, initial) { + this.transformer = transformer1; + if (initial == null) { + initial = void 0; + } + Transform.__super__.constructor.call(this, { + initial: initial + }); + } + + Transform.prototype.onMidiEvent = function(ev) { + var result; + result = this.transformer(ev, this.midiValue); + if (result != null) { + return this.output.value = this.value = result; + } + }; + + Transform.prototype.getMidiValue = function() { + var base, ref3; + return (ref3 = typeof (base = this.transformer).inverse === "function" ? base.inverse(this.value) : void 0) != null ? ref3 : this.value; + }; + + return Transform; + + })(exports.Output); + + exports.transform = factory(exports.Transform); + + exports.modifier = function() { + return exports.transform(transform.momentaryT, false); + }; + + exports["switch"] = function() { + return exports.transform(transform.binaryT, false); + }; + + exports.switch_ = exports["switch"]; + + exports.MapIn = (function(superClass) { + extend1(MapIn, superClass); + + function MapIn(ingroupOrParams, inkey) { + var ref3; + if (inkey == null) { + inkey = void 0; + } + MapIn.__super__.constructor.apply(this, arguments); + ref3 = !isinstance(ingroupOrParams, String) ? ingroupOrParams : { + group: ingroupOrParams, + key: inkey + }, this.group = ref3.group, this.key = ref3.key; + this._transform = transform.mappings[this.key]; + } + + MapIn.prototype.transform = function(trans) { + this._transform = trans; + return this; + }; + + MapIn.prototype.enable = function(script, actor) { + var engine; + MapIn.__super__.enable.apply(this, arguments); + engine = script.mixxx.engine; + this.value = engine.getValue(this.group, this.key); + if (this.listeners('value').length > 0) { + if (this._inHandler == null) { + this._inHandler = script.registerHandler((function(_this) { + return function(v) { + return _this.value = v; + }; + })(this)); + } + engine.connectControl(this.group, this.key, this._inHandler); + return this._inHandlerConnected = true; + } + }; + + MapIn.prototype.disable = function() { + if (this._inHandlerConnected != null) { + this.script.mixxx.engine.connectControl(this.group, this.key, this._inHandler, true); + this._inHandlerConnected = false; + } + return MapIn.__super__.disable.apply(this, arguments); + }; + + MapIn.prototype.directInMapping = function() { + if (this._transform === transform.mappings[this.key]) { + return { + group: this.group, + key: this.key + }; + } + }; + + MapIn.prototype.onMidiEvent = function(ev) { + var val; + val = this._transform(ev, this.midiValue); + if (val != null) { + this.script.mixxx.engine.setValue(this.group, this.key, val); + if (this.listeners('value').length === 0) { + return this.value = val; + } + } + }; + + MapIn.prototype.getMidiValue = function() { + var ref3, ref4; + return (ref3 = (ref4 = this._transform) != null ? typeof ref4.inverse === "function" ? ref4.inverse(this.value) : void 0 : void 0) != null ? ref3 : this.value; + }; + + return MapIn; + + })(exports.Behaviour); + + exports.mapIn = factory(exports.MapIn); + + exports.MapOut = (function(superClass) { + extend1(MapOut, superClass); + + function MapOut(outgroupOrParams, outkey) { + var ref3; + if (outkey == null) { + outkey = void 0; + } + MapOut.__super__.constructor.apply(this, arguments); + ref3 = !isinstance(outgroupOrParams, String) ? outgroupOrParams : { + outgroup: outgroupOrParams, + outkey: outkey + }, this.outgroup = ref3.outgroup, this.outkey = ref3.outkey; + } + + MapOut.prototype.meter = function(transformer) { + if (transformer == null) { + transformer = void 0; + } + this._outTransform = transformer; + if (this._outTransform == null) { + this._outTransform = transform.mappings[this.outkey].inverse; + } + this.updateOutput = function() { + return this.actor.send(Math.floor(this._outTransform(this.output.value))); + }; + return this; + }; + + MapOut.prototype.enable = function(script, actor) { + var engine; + MapOut.__super__.enable.apply(this, arguments); + engine = script.mixxx.engine; + this.output.value = engine.getValue(this.outgroup, this.outkey); + if (this.output.listeners('value').length > 0) { + if (this._outHandler == null) { + this._outHandler = script.registerHandler((function(_this) { + return function(v) { + return _this.output.value = v; + }; + })(this)); + } + engine.connectControl(this.outgroup, this.outkey, this._outHandler); + return this._outHandlerConnected = true; + } + }; + + MapOut.prototype.disable = function() { + if (this._outHandlerConnected != null) { + this.script.mixxx.engine.connectControl(this.outgroup, this.outkey, this._outHandler, true); + this._outHandlerConnected = false; + } + return MapOut.__super__.disable.apply(this, arguments); + }; + + MapOut.prototype.directOutMapping = function() { + if (this._outTransform == null) { + return { + group: this.outgroup, + key: this.outkey, + minimum: this.minimum + }; + } + }; + + return MapOut; + + })(exports.Output); + + exports.mapOut = factory(exports.MapOut); + + exports.Map = (function(superClass) { + extend1(Map, superClass); + + function Map(groupOrParams, key, outgroup, outkey) { + var params; + params = !isinstance(groupOrParams, String) ? groupOrParams : { + group: groupOrParams, + key: key, + outgroup: outgroup, + outkey: outkey + }; + if (params.outgroup == null) { + params.outgroup = params.group; + } + if (params.outkey == null) { + params.outkey = params.key; + } + Map.__super__.constructor.call(this, params); + } + + return Map; + + })(multi(exports.MapIn, exports.MapOut)); + + exports.map = factory(exports.Map); + + exports.toBehaviour = function() { + var args, behaviour; + behaviour = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + if (args.length > 0) { + return exports.map.apply(exports, [behaviour].concat(slice.call(args))); + } else { + return behaviour; + } + }; + + exports.soft = function() { + return exports.map.apply(exports, arguments).option(option.softTakeover); + }; + + exports.toggle = function() { + var args, offValue, onValue; + offValue = arguments[0], onValue = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; + return exports.map.apply(exports, args).transform(function(ev) { + if (ev.pressed) { + return onValue; + } else { + return offValue; + } + }); + }; + + exports.set = function() { + var args, valueToSet; + valueToSet = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.toggle.apply(exports, [valueToSet, null].concat(slice.call(args))); + }; + + exports.Chooser = (function(superClass) { + extend1(Chooser, superClass); + + function Chooser(arg) { + var ref3; + ref3 = arg != null ? arg : {}, this.autoExclusive = ref3.autoExclusive, this.onDisable = ref3.onDisable; + Chooser.__super__.constructor.apply(this, arguments); + this._selectedIndex = null; + this._chooseOptions = []; + this._chooseActivators = []; + this._chooseSelectors = []; + this._chooseHandles = []; + } + + Chooser.prototype.add = function(group, key, listen) { + var activator, idx; + if (listen == null) { + listen = null; + } + idx = this._chooseOptions.length; + activator = exports.map(group, key).transform((function(_this) { + return function(ev) { + if (ev.pressed) { + _this.activate(idx); + } + return null; + }; + })(this)); + this._chooseOptions.push([group, key, listen]); + this._chooseActivators.push(activator); + return activator; + }; + + Chooser.prototype.enable = function(script) { + var engine, group, i, key, len, listen, ref3, ref4; + Chooser.__super__.enable.apply(this, arguments); + if (this._updateValueHandler == null) { + this._updateValueHandler = script.registerHandler((function(_this) { + return function() { + return _this._updateValue(); + }; + })(this)); + } + engine = script.mixxx.engine; + ref3 = this._chooseOptions; + for (i = 0, len = ref3.length; i < len; i++) { + ref4 = ref3[i], group = ref4[0], key = ref4[1], listen = ref4[2]; + if (listen == null) { + listen = key; + } + engine.connectControl(group, listen, this._updateValueHandler); + } + return this._updateValue(); + }; + + Chooser.prototype.disable = function(script) { + var engine, group, i, key, len, listen, ref3, ref4; + assert(this._updateValueHandler); + engine = script.mixxx.engine; + ref3 = this._chooseOptions; + for (i = 0, len = ref3.length; i < len; i++) { + ref4 = ref3[i], group = ref4[0], key = ref4[1], listen = ref4[2]; + if (listen == null) { + listen = key; + } + engine.connectControl(group, listen, this._updateValueHandler, true); + } + return Chooser.__super__.disable.apply(this, arguments); + }; + + Chooser.prototype.activator = function(idx) { + assert((0 <= idx && idx < this._chooseOptions.length)); + return this._chooseActivators[idx]; + }; + + Chooser.prototype.selector = function() { + var select, selector; + select = (function(_this) { + return function(ev) { + var v; + v = (ev.value / 128.0 * _this._chooseOptions.length).clamp(0, _this._chooseOptions.length - 1); + _this._update({ + index: Math.floor(v) + }); + return v; + }; + })(this); + select.inverse = (function(_this) { + return function(v) { + return v / _this._chooseOptions.length * 128.0; + }; + })(this); + selector = extend(exports.transform(select), { + _updateValue: function(newv) { + if (Math.floor(newv) !== Math.floor(this.value)) { + return this.value = this.output.value = newv; + } + } + }); + this._chooseSelectors.push(selector); + return selector; + }; + + Chooser.prototype.momentary = function() { + return exports.action({ + press: (function(_this) { + return function() { + return _this._update({ + enable: true + }); + }; + })(this), + release: (function(_this) { + return function() { + return _this._update({ + enable: false + }); + }; + })(this) + }); + }; + + Chooser.prototype.activate = function(idx) { + this._update({ + index: idx, + enable: true + }); + return this; + }; + + Chooser.prototype.select = function(idx) { + if (this.actor != null) { + this._update({ + index: idx, + enable: true + }); + } else { + this._selectedIndex = idx; + } + return this; + }; + + Chooser.prototype.onMidiEvent = function(event) { + var enable; + if (event.pressed) { + enable = !this.value; + this._update({ + enable: enable + }); + if (!enable) { + return typeof this.onDisable === "function" ? this.onDisable() : void 0; + } + } + }; + + Chooser.prototype._update = function(arg) { + var enable, group, i, idx, index, key, len, listen, ref3, ref4, ref5, ref6, ref7, script; + ref3 = arg != null ? arg : {}, index = ref3.index, enable = ref3.enable; + if (enable == null) { + enable = this.value; + } + if (index == null) { + index = this._selectedIndex; + } + index = index != null ? index.clamp(0, this._chooseOptions.length - 1) : void 0; + if (index !== this._selectedIndex || enable !== this.value) { + script = (ref4 = this.script) != null ? ref4 : this._chooseActivators[index].script; + if (index != null) { + ref5 = this._chooseOptions[index], group = ref5[0], key = ref5[1], listen = ref5[2]; + script.mixxx.engine.setValue(group, key, enable); + } + if (!this.autoExclusive || !enable) { + ref6 = this._chooseOptions; + for (idx = i = 0, len = ref6.length; i < len; idx = ++i) { + ref7 = ref6[idx], group = ref7[0], key = ref7[1]; + if (idx !== index) { + script.mixxx.engine.setValue(group, key, false); + } + } + } + return this._selectedIndex = index; + } + }; + + Chooser.prototype._updateValue = function() { + var engine, i, len, ref3, selector; + if (this.script != null) { + engine = this.script.mixxx.engine; + this.value = this.output.value = _.some(this._chooseOptions, function(arg) { + var group, key, listen; + group = arg[0], key = arg[1], listen = arg[2]; + if (listen == null) { + listen = key; + } + return engine.getValue(group, listen); + }); + ref3 = this._chooseSelectors; + for (i = 0, len = ref3.length; i < len; i++) { + selector = ref3[i]; + selector._updateValue(this._selectedIndex); + } + } + return this; + }; + + return Chooser; + + })(exports.Output); + + exports.chooser = factory(exports.Chooser); + + exports.When = (function(superClass) { + extend1(When, superClass); + + function When() { + var _condition, base, wrapped; + _condition = arguments[0], wrapped = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this._condition = _condition; + this["else"] = (function(_this) { + return function() { + return _this._else.apply(_this, arguments); + }; + })(this); + this["else"].when = (function(_this) { + return function() { + return _this._elseWhen.apply(_this, arguments); + }; + })(this); + this.when = this["else"].when; + this.else_ = this["else"]; + When.__super__.constructor.call(this); + this._wrapped = exports.toBehaviour.apply(exports, wrapped); + this._condition.on('value', (function(_this) { + return function() { + return _this._update(); + }; + })(this)); + if (this._lastCondition !== 'no-more-negations') { + this._lastCondition = this._condition; + if ((base = this._lastCondition).negation == null) { + base.negation = value.not(this._condition); + } + } + } + + When.prototype.option = function() { + var ref3; + When.__super__.option.apply(this, arguments); + (ref3 = this._wrapped).option.apply(ref3, arguments); + return this; + }; + + When.prototype._elseWhen = function() { + var args, condition, nextCondition; + condition = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + assert(this._lastCondition != null, "Can not define more conditions after 'else'"); + nextCondition = value.and(condition, value.not(this._lastCondition)); + nextCondition.negation = value.and(this._lastCondition.negation, value.not(condition)); + this._lastCondition = nextCondition; + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(exports.When, [nextCondition].concat(slice.call(args)), function(){}); + }; + + When.prototype._else = function() { + var args, nextCondition; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastCondition != null, "Can not define more conditions after 'else'"); + nextCondition = this._lastCondition.negation; + nextCondition.negation = 'no-more-negations'; + delete this._lastCondition; + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(exports.When, [nextCondition].concat(slice.call(args)), function(){}); + }; + + When.prototype.enable = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + When.__super__.enable.apply(this, arguments); + this._enableOn = args; + this._enableRequested = true; + return this._update(); + }; + + When.prototype.disable = function() { + this._enableRequested = false; + this._update(); + return When.__super__.disable.apply(this, arguments); + }; + + When.prototype._update = function() { + var ref3, ref4; + this.value = this._enableRequested && this._condition.value; + if (this._wrapped.actor && !this.value) { + (ref3 = this._wrapped).disable.apply(ref3, this._enableOn); + } + if (!this._wrapped.actor && this.value) { + return (ref4 = this._wrapped).enable.apply(ref4, this._enableOn); + } + }; + + When.prototype.directOutMapping = function() { + return null; + }; + + When.prototype.directInMapping = function() { + return null; + }; + + return When; + + })(exports.Behaviour); + + exports.when = factory(exports.When); + + exports.Action = (function(superClass) { + extend1(Action, superClass); + + Action.prototype.minimum = true; + + function Action(action) { + this.action = action != null ? action : void 0; + Action.__super__.constructor.call(this); + if (this.onPress == null) { + this.onPress = this.action.press; + } + if (this.onRelease == null) { + this.onRelease = this.action.release; + } + } + + Action.prototype.onMidiEvent = function(ev) { + var val; + val = this.value = this.output.value = ev.pressed; + if (val) { + return typeof this.onPress === "function" ? this.onPress() : void 0; + } else { + return typeof this.onRelease === "function" ? this.onRelease() : void 0; + } + }; + + return Action; + + })(exports.Output); + + exports.action = factory(exports.Action); + + exports.punchIn = function(threshold, threshold2) { + var inThreshold, oldxfader; + if (threshold2 == null) { + threshold2 = void 0; + } + oldxfader = void 0; + inThreshold = function(newxfader, threshold) { + return (threshold < 0 && newxfader < threshold) || (threshold > 0 && newxfader > threshold); + }; + return exports.action({ + press: function() { + var engine, newxfader; + engine = this.script.mixxx.engine; + newxfader = engine.getValue("[Master]", "crossfader"); + if (inThreshold(newxfader, threshold) || ((threshold2 != null) && inThreshold(newxfader, threshold2))) { + oldxfader = newxfader; + return engine.setValue("[Master]", "crossfader", 0); + } + }, + release: function() { + var engine; + engine = this.script.mixxx.engine; + if (oldxfader != null) { + engine.setValue("[Master]", "crossfader", oldxfader); + return oldxfader = void 0; + } + } + }); + }; + + exports.scratchEnable = function(deck, intervalsPerRev, rpm, alpha, beta, ramp) { + if (intervalsPerRev == null) { + intervalsPerRev = 128 * 4; + } + if (rpm == null) { + rpm = 44.0; + } + if (alpha == null) { + alpha = 1.0 / 8.0; + } + if (beta == null) { + beta = 1.0 / 8.0 / 32.0; + } + if (ramp == null) { + ramp = true; + } + return exports.action({ + press: function() { + var enable; + enable = this.script.mixxx.engine.scratchEnable; + return enable(deck, intervalsPerRev, rpm, alpha, beta, ramp); + }, + release: function() { + return this.script.mixxx.engine.scratchDisable(deck, ramp); + } + }); + }; + + exports.scratchTick = function(deck, transform) { + if (transform == null) { + transform = function(x) { + return x; + }; + } + return exports.call(function(ev) { + var engine; + engine = this.script.mixxx.engine; + return engine.scratchTick(deck, transform(ev.value)); + }); + }; + + exports.spinback = function() { + var args, deck; + deck = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.modifier().on('value', function() { + var ref3; + return (ref3 = this.script.mixxx.engine).spinback.apply(ref3, [deck, this.value].concat(slice.call(args))); + }); + }; + + exports.brake = function() { + var args, deck; + deck = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.modifier().on('value', function() { + var ref3; + return (ref3 = this.script.mixxx.engine).brake.apply(ref3, [deck, this.value].concat(slice.call(args))); + }); + }; + + exports.playhead = function(g) { + return exports.mapOut(g, "playposition").meter((function() { + var step; + step = 0; + return function(pos) { + var duration, engine; + engine = this.script.mixxx.engine; + duration = (function() { + switch (false) { + case !!engine.getValue(g, "play"): + return void 0; + case !(pos > .9): + return 5; + case !(pos > .8): + return 9; + case !(pos > .75): + return 13; + default: + return void 0; + } + })(); + if (duration != null) { + step = (step + 1) % duration; + if (step > duration / 2) { + return 0; + } else { + return pos * 127; + } + } else { + step = 0; + return pos * 127; + } + }; + })()); + }; + + exports.beatEffect = function(channel, type) { + var i, len, result, size, sizes; + if (type == null) { + type = ''; + } + sizes = ["0.0625", "0.125", "0.25", "0.5", "1", "2", "4", "8", "16", "32", "64"]; + result = exports.chooser({ + autoExclusive: true, + onDisable: function() { + var engine; + engine = this.script.mixxx.engine; + if (type !== 'roll' && engine.getValue(channel, "loop_enabled")) { + return engine.setValue(channel, "reloop_exit", true); + } + } + }); + for (i = 0, len = sizes.length; i < len; i++) { + size = sizes[i]; + result.add(channel, "beatloop" + type + "_" + size + "_activate", "beatloop_" + size + "_enabled"); + } + return result.select(4); + }; + + exports.stutter = function(group, beats) { + var tick; + if (beats == null) { + beats = 0.25; + } + tick = function() { + var engine, gain, newgain; + engine = this.script.mixxx.engine; + gain = engine.getValue(group, "pregain"); + newgain = gain > 0 ? (this._oldgain = gain, 0) : this._oldgain; + return engine.setValue(group, "pregain", newgain); + }; + return exports.action({ + press: function() { + var bpm, delta, engine; + engine = this.script.mixxx.engine; + bpm = engine.getValue(group, "bpm"); + delta = beats * 60000 / bpm; + if (this._timerHandle == null) { + this._timerHandle = this.script.registerHandler(bind(tick, this)); + } + return this._timerId != null ? this._timerId : this._timerId = engine.beginTimer(delta, this._timerHandle); + }, + release: function() { + var engine; + engine = this.script.mixxx.engine; + engine.stopTimer(this._timerId); + if (this._oldgain != null) { + engine.setValue(group, "pregain", this._oldgain); + } + delete this._timerId; + return delete this._oldgain; + } + }); + }; + +}).call(this); + +},{"./transform":7,"./util":8,"./value":9,"events":10,"heterarchy":13,"underscore":16}],4:[function(require,module,exports){ +// Generated by CoffeeScript 1.10.0 +(function() { + var assert, exports, konsole; + + assert = require('./util').assert; + + konsole = this; + + exports = konsole; + + if (konsole.log == null) { + konsole.log = function() { + return print("" + arguments); + }; + } + + if (konsole.info == null) { + konsole.info = konsole.log; + } + + if (konsole.warn == null) { + konsole.warn = konsole.log; + } + + if (konsole.error == null) { + konsole.error = konsole.log; + } + + if (konsole.time == null) { + konsole.time = function() { + return assert(False, "time not implemented in konsole"); + }; + } + + if (konsole.timeEnd == null) { + konsole.timeEnd = function() { + return assert(False, "time not implemented in konsole"); + }; + } + + if (konsole.trace == null) { + konsole.trace = function() { + var err; + err = new Error(); + err.name = "Trace"; + err.message = "" + arguments; + return konsole.error(err.stack); + }; + } + + if (konsole.dir == null) { + konsole.dir = function() { + return konsole.log(object + "\n"); + }; + } + + if (konsole.assert == null) { + konsole.assert = assert; + } + +}).call(this); + +},{"./util":8}],5:[function(require,module,exports){ +// Generated by CoffeeScript 1.10.0 +(function() { + var MIDI_CC, MIDI_NOTE_OFF, MIDI_NOTE_ON, MIDI_PITCHBEND, assert, behaviour, ccIds, event, extend, factory, hexStr, indent, joinLn, midiId, multi, noteIds, noteOnIds, pbIds, ref, ref1, some, xmlTag, + slice = [].slice, + extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + multi = require('heterarchy').multi; + + ref = require('./util'), indent = ref.indent, hexStr = ref.hexStr, assert = ref.assert, factory = ref.factory, xmlTag = ref.xmlTag, joinLn = ref.joinLn; + + behaviour = require('./behaviour'); + + ref1 = require('underscore'), some = ref1.some, extend = ref1.extend; + + exports.MIDI_NOTE_ON = MIDI_NOTE_ON = 0x9; + + exports.MIDI_NOTE_OFF = MIDI_NOTE_OFF = 0x8; + + exports.MIDI_CC = MIDI_CC = 0xB; + + exports.MIDI_PITCHBEND = MIDI_PITCHBEND = 0xE; + + midiId = function(message, midino, channel) { + if (message == null) { + message = MIDI_CC; + } + if (midino == null) { + midino = 0; + } + if (channel == null) { + channel = 0; + } + return { + message: message, + midino: midino, + channel: channel, + status: function() { + return (this.message << 4) | this.channel; + }, + configMidi: function(depth) { + return (indent(depth)) + "" + (hexStr(this.status())) + "\n" + (indent(depth)) + "" + (hexStr(this.midino)) + ""; + } + }; + }; + + exports.midiId = midiId; + + pbIds = function() { + return [midiId.apply(null, [MIDI_PITCHBEND, 0].concat(slice.call(arguments)))]; + }; + + noteOnIds = function() { + return [midiId.apply(null, [MIDI_NOTE_ON].concat(slice.call(arguments)))]; + }; + + noteIds = function() { + return [midiId.apply(null, [MIDI_NOTE_ON].concat(slice.call(arguments))), midiId.apply(null, [MIDI_NOTE_OFF].concat(slice.call(arguments)))]; + }; + + ccIds = function() { + return [midiId.apply(null, [MIDI_CC].concat(slice.call(arguments)))]; + }; + + exports.pbIds = pbIds; + + exports.noteOnIds = noteOnIds; + + exports.noteIds = noteIds; + + exports.ccIds = ccIds; + + exports.event = event = function(channel, control, value, status, group) { + return { + channel: channel, + control: control, + value: (function() { + switch (status >> 4) { + case MIDI_PITCHBEND: + return (value * 128.0 + control) / 128.0; + default: + return value; + } + })(), + status: status, + group: group, + message: function() { + return this.status >> 4; + }, + pressed: status >> 4 !== MIDI_NOTE_OFF && value + }; + }; + + exports.Control = (function(superClass) { + extend1(Control, superClass); + + function Control() { + var args, ids; + ids = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this.ids = ids != null ? ids : [midiId()]; + this["else"] = (function(_this) { + return function() { + return _this._else.apply(_this, arguments); + }; + })(this); + this["else"].when = (function(_this) { + return function() { + return _this._elseWhen.apply(_this, arguments); + }; + })(this); + this.else_ = this["else"]; + Control.__super__.constructor.call(this); + if (!(this.ids instanceof Array)) { + this.ids = ccIds.apply(null, [this.ids].concat(slice.call(args))); + } + this._behaviours = []; + if (typeof this._controlRegistry === "function") { + this._controlRegistry(this); + } + } + + Control.prototype.does = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit); + this._behaviours.push(this.registerBehaviour(behaviour.toBehaviour.apply(behaviour, args))); + return this; + }; + + Control.prototype.when = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit); + this._lastWhen = behaviour.when.apply(behaviour, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + return this; + }; + + Control.prototype._elseWhen = function() { + var args, ref2; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastWhen != null, "'elseWhen' must be preceded by 'when' or 'elseWhen'"); + this._lastWhen = (ref2 = this._lastWhen["else"]).when.apply(ref2, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + return this; + }; + + Control.prototype._else = function() { + var args, ref2; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastWhen != null, "'else' must be preceded by 'when' or 'elseWhen'"); + this._lastWhen = (ref2 = this._lastWhen)["else"].apply(ref2, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + this._lastWhen = void 0; + return this; + }; + + Control.prototype.init = function(script) { + var b, i, len, ref2; + this.script = script; + assert(!this._isInit); + ref2 = this._behaviours; + for (i = 0, len = ref2.length; i < len; i++) { + b = ref2[i]; + b.enable(script, this); + } + return this._isInit = true; + }; + + Control.prototype.shutdown = function(script) { + var b, i, len, ref2; + assert(script === this.script); + assert(this._isInit); + ref2 = this._behaviours; + for (i = 0, len = ref2.length; i < len; i++) { + b = ref2[i]; + b.disable(script, this); + } + this._isInit = false; + return delete this.script; + }; + + Control.prototype.registerBehaviour = function(b) { + return b; + }; + + Control.prototype.configInputs = function(depth, script) {}; + + Control.prototype.configOutputs = function(depth, script) {}; + + Control.prototype.setRegistry = function(registry) { + assert((this._controlRegistry == null) || (registry == null)); + return this._controlRegistry = registry; + }; + + return Control; + + })(behaviour.Actor); + + exports.InControl = (function(superClass) { + extend1(InControl, superClass); + + function InControl() { + return InControl.__super__.constructor.apply(this, arguments); + } + + InControl.prototype.init = function(script) { + InControl.__super__.init.apply(this, arguments); + if (this.needsHandler()) { + return script.registerHandler(((function(_this) { + return function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return _this.emit('event', event.apply(null, args)); + }; + })(this)), this.handlerId()); + } + }; + + InControl.prototype.option = function() { + var beh, i, len, options, ref2, ref3; + options = 1 <= arguments.length ? slice.call(arguments, 0) : []; + (ref2 = (this._options != null ? this._options : this._options = [])).push.apply(ref2, options); + ref3 = this._behaviours; + for (i = 0, len = ref3.length; i < len; i++) { + beh = ref3[i]; + beh.option.apply(beh, options); + } + return this; + }; + + InControl.property('options', function() { + return behaviour.makeOptionsChooser(this); + }); + + InControl.prototype.registerBehaviour = function(beh) { + if (this._options != null) { + beh.option.apply(beh, this._options); + } + return beh; + }; + + InControl.prototype.needsHandler = function() { + return this._behaviours.length !== 1 || !this._behaviours[0].directInMapping() || some(this._behaviours[0]._options, function(opt) { + return !opt.name; + }); + }; + + InControl.prototype.handlerId = function() { + return "x" + (this.ids[0].status().toString(16)) + "_x" + (this.ids[0].midino.toString(16)); + }; + + InControl.prototype.configInputs = function(depth, script) { + var id, mapping; + if (this.needsHandler()) { + mapping = { + group: "[Master]", + key: script.handlerKey(this.handlerId()) + }; + } else { + mapping = this._behaviours[0].directInMapping(); + } + return joinLn((function() { + var i, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + results.push(this.configInMapping(depth, mapping, id)); + } + return results; + }).call(this)); + }; + + InControl.prototype.configInMapping = function(depth, mapping, id) { + return (indent(depth)) + "\n" + (indent(depth + 1)) + "" + mapping.group + "\n" + (indent(depth + 1)) + "" + mapping.key + "\n" + (id.configMidi(depth + 1)) + "\n" + (indent(depth + 1)) + "\n" + (this.configOptions(depth + 2)) + "\n" + (indent(depth + 1)) + "\n" + (indent(depth)) + ""; + }; + + InControl.prototype.configOptions = function(depth) { + var opt, ref2; + if (this.needsHandler()) { + return (indent(depth)) + ""; + } else if (((ref2 = this._behaviours[0]._options) != null ? ref2.length : void 0) > 0) { + return joinLn((function() { + var i, len, ref3, results; + ref3 = this._behaviours[0]._options; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (opt.name != null) { + results.push((indent(depth)) + "<" + opt.name + "/>"); + } else { + results.push(void 0); + } + } + return results; + }).call(this)); + } else { + return (indent(depth)) + ""; + } + }; + + return InControl; + + })(exports.Control); + + exports.OutControl = (function(superClass) { + extend1(OutControl, superClass); + + function OutControl() { + OutControl.__super__.constructor.apply(this, arguments); + this._states = { + on: 0x7f, + off: 0x00, + disable: 0x00 + }; + } + + OutControl.prototype.send = function(state) { + return this.doSend(state); + }; + + OutControl.prototype.states = function(states) { + extend(this._states, states); + return this; + }; + + OutControl.prototype.doSend = function(state) { + var i, id, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + if (id.message !== MIDI_NOTE_OFF) { + if (state in this._states) { + results.push(this.script.mixxx.midi.sendShortMsg(id.status(), id.midino, this._states[state])); + } else { + results.push(this.script.mixxx.midi.sendShortMsg(id.status(), id.midino, state)); + } + } else { + results.push(void 0); + } + } + return results; + }; + + OutControl.prototype.init = function() { + if (!this.needsSend()) { + this.send = void 0; + } + return OutControl.__super__.init.apply(this, arguments); + }; + + OutControl.prototype.shutdown = function() { + this.doSend('disable'); + return OutControl.__super__.shutdown.apply(this, arguments); + }; + + OutControl.prototype.needsSend = function() { + return this._behaviours.length !== 1 || !this._behaviours[0].directOutMapping(); + }; + + OutControl.prototype.configOutputs = function(depth, script) { + var id, mapping; + mapping = !this.needsSend() && this._behaviours[0].directOutMapping(); + if (mapping) { + return joinLn((function() { + var i, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + results.push(this.configOutMapping(depth, mapping, id)); + } + return results; + }).call(this)); + } + }; + + OutControl.prototype.configOutMapping = function(depth, mapping, id) { + var options; + if (id.message !== MIDI_NOTE_OFF) { + options = joinLn([xmlTag('minimum', mapping.minimum, depth + 1), xmlTag('maximum', mapping.maximum, depth + 1)]); + return (indent(depth)) + "\n" + (indent(depth + 1)) + "" + mapping.group + "\n" + (indent(depth + 1)) + "" + mapping.key + "\n" + (id.configMidi(depth + 1)) + "\n" + (indent(depth + 1)) + "" + (hexStr(this._states['on'])) + "\n" + (indent(depth + 1)) + "" + (hexStr(this._states['off'])) + "\n" + options + "\n" + (indent(depth)) + ""; + } + }; + + return OutControl; + + })(exports.Control); + + exports.input = factory(exports.InControl); + + exports.output = factory(exports.OutControl); + + exports.InOutControl = (function(superClass) { + extend1(InOutControl, superClass); + + function InOutControl() { + return InOutControl.__super__.constructor.apply(this, arguments); + } + + return InOutControl; + + })(multi(exports.InControl, exports.OutControl)); + + exports.control = factory(exports.InOutControl); + +}).call(this); + +},{"./behaviour":3,"./util":8,"heterarchy":13,"underscore":16}],6:[function(require,module,exports){ +(function (process){ +// Generated by CoffeeScript 1.10.0 +(function() { + var Control, S, _, assert, basename, bind, catching, flatten, indent, issubclass, mro, ref, ref1, ref2, xmlEscape, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, + slice = [].slice; + + ref = require('underscore'), flatten = ref.flatten, bind = ref.bind; + + ref1 = require('heterarchy'), issubclass = ref1.issubclass, mro = ref1.mro; + + Control = require('./control').Control; + + ref2 = require('./util'), indent = ref2.indent, xmlEscape = ref2.xmlEscape, catching = ref2.catching, assert = ref2.assert; + + require('./console'); + + basename = require('path').basename; + + S = require('string'); + + _ = require('underscore'); + + exports.nameFromFilename = function(fname) { + var extensions, name; + extensions = [".mixco.coffee", ".mixco.litcoffee", ".mixco.js", ".mixco"]; + fname = basename(fname); + assert(_.some(extensions, function(x) { + return S(fname).endsWith(x); + }), "Script file name: " + fname + " must end in one of: " + extensions); + name = extensions.reduce((function(fname, ext) { + return fname.replace(ext, ""); + }), fname); + assert(name.match(/^[a-zA-Z_$][0-9a-zA-Z_$].*$/, "Script name must be a valid JavaScript identifier")); + return name; + }; + + exports.register = function(targetModule, scriptTypeOrDefinition) { + var instance, name, scriptType; + name = targetModule.filename != null ? exports.nameFromFilename(targetModule.filename) : typeof MIXCO_SCRIPT_FILENAME !== "undefined" && MIXCO_SCRIPT_FILENAME !== null ? exports.nameFromFilename(MIXCO_SCRIPT_FILENAME) : assert(false, "Invalid script"); + scriptType = issubclass(scriptTypeOrDefinition, exports.Script) ? scriptTypeOrDefinition : exports.create(scriptTypeOrDefinition); + instance = new scriptType; + instance.__registeredName = name; + targetModule.exports[name] = instance; + if (targetModule === require.main) { + return instance.main(); + } + }; + + exports.create = function(scriptDefinition) { + var NewScript, constructor, init, k, shutdown, special, v; + assert(scriptDefinition.constructor != null, "Script definition must have a constructor"); + constructor = scriptDefinition.constructor, init = scriptDefinition.init, shutdown = scriptDefinition.shutdown; + NewScript = (function(superClass) { + extend(NewScript, superClass); + + function NewScript() { + NewScript.__super__.constructor.apply(this, arguments); + try { + Control.prototype.setRegistry(bind(this.add, this)); + constructor.apply(this, arguments); + } finally { + Control.prototype.setRegistry(null); + } + this; + } + + NewScript.prototype.init = function() { + var ref3; + if ((ref3 = this.preinit) != null) { + ref3.apply(this, arguments); + } + NewScript.__super__.init.apply(this, arguments); + return init != null ? init.apply(this, arguments) : void 0; + }; + + NewScript.prototype.shutdown = function() { + var ref3; + if (shutdown != null) { + shutdown.apply(this, arguments); + } + NewScript.__super__.shutdown.apply(this, arguments); + return (ref3 = this.postshutdown) != null ? ref3.apply(this, arguments) : void 0; + }; + + return NewScript; + + })(exports.Script); + special = ['name', 'constructor', 'init', 'shutdown']; + for (k in scriptDefinition) { + v = scriptDefinition[k]; + if (indexOf.call(special, k) < 0) { + NewScript.prototype[k] = v; + } + } + return NewScript; + }; + + exports.Script = (function() { + Script.prototype.info = { + name: "[mixco] Generic Script", + author: "Juan Pedro Bolivar Puente ", + description: "", + forums: "", + wiki: "" + }; + + Script.property('name', { + get: function() { + assert(this.__registeredName, "Script must be registered"); + return this.__registeredName; + } + }); + + Script.prototype.add = function() { + var controls, ref3; + controls = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit, "Can only add controls in constructor"); + return (ref3 = this.controls).push.apply(ref3, flatten(controls)); + }; + + Script.prototype.init = catching(function() { + var control, i, len, ref3, results; + this._isInit = true; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.init(this)); + } + return results; + }); + + Script.prototype.shutdown = catching(function() { + var control, i, len, ref3; + ref3 = this.controls; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + control.shutdown(this); + } + return delete this._isInit; + }); + + function Script() { + this.controls = []; + } + + Script.prototype.mixxx = { + engine: (typeof engine !== "undefined" && engine !== null ? engine : void 0), + midi: (typeof midi !== "undefined" && midi !== null ? midi : void 0), + script: (typeof script !== "undefined" && script !== null ? script : void 0) + }; + + Script.prototype.main = function() { + var arg, i, len, ref3, results; + ref3 = process.argv; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + arg = ref3[i]; + if (arg === '-h' || arg === '--help') { + console.info(this.help()); + break; + } + if (arg === '-g' || arg === '--generate-config') { + console.info(this.config()); + break; + } else { + results.push(void 0); + } + } + return results; + }; + + Script.prototype.help = function() { + return "Mixxx Controller Script\n=======================\n\nName: " + this.info.name + "\nAuthor: " + this.info.author + "\nDescription: " + this.info.description + "\nForums: " + this.info.description + "\n\nUsage\n-----\n1. Generate Mixxx config:\n coffee " + this.name + ".coffee -g > " + this.name + ".xml\n\n2. Generate Mixxx script:\n coffee -c " + this.name + ".coffee"; + }; + + Script.prototype.config = function() { + return "\n\n" + (indent(1)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.name)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.author)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.description)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.wiki)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.forums)) + "\n" + (indent(1)) + "\n" + (indent(1)) + "\n" + (indent(2)) + "\n" + (indent(3)) + "\n" + (indent(2)) + "\n" + (indent(2)) + "\n" + (this.configInputs(3)) + "\n" + (indent(2)) + "\n" + (indent(2)) + "\n" + (this.configOutputs(3)) + "\n" + (indent(2)) + "\n" + (indent(1)) + "\n"; + }; + + Script.prototype.configInputs = function(depth) { + var control; + return ((function() { + var i, len, ref3, results; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.configInputs(depth, this)); + } + return results; + }).call(this)).filter(function(x) { + return x; + }).join('\n'); + }; + + Script.prototype.configOutputs = function(depth) { + var control; + return ((function() { + var i, len, ref3, results; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.configOutputs(depth, this)); + } + return results; + }).call(this)).filter(function(x) { + return x; + }).join('\n'); + }; + + Script.prototype._nextCallbackId = 1; + + Script.prototype.registerHandler = function(callback, id) { + var handlerName; + if (id == null) { + id = void 0; + } + id || (id = this._nextCallbackId++); + handlerName = "__handle_" + id; + assert(!this[handlerName], "Handlers can be registered only once (" + handlerName + ")"); + this[handlerName] = callback; + return this.handlerKey(id); + }; + + Script.prototype.handlerKey = function(id) { + if (id == null) { + id = void 0; + } + if (id == null) { + id = this._nextCallbackId - 1; + } + return this.name + ".__handle_" + id; + }; + + return Script; + + })(); + +}).call(this); + +}).call(this,require('_process')) +},{"./console":4,"./control":5,"./util":8,"_process":12,"heterarchy":13,"path":11,"string":15,"underscore":16}],7:[function(require,module,exports){ +// Generated by CoffeeScript 1.10.0 +(function() { + var binaryT, centeredT, defaultT, identityT, linearT, momentaryT, + slice = [].slice; + + exports.identity = function(v) { + return v; + }; + + exports.identity.inverse = exports.identity; + + exports.momentary = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } + }; + + exports.momentary.inverse = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } + }; + + exports.binary = function(v, oldv) { + if (v > 0) { + return !oldv; + } else { + return null; + } + }; + + exports.binary.inverse = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } + }; + + exports.linear = function(v, min, max) { + return min + v * (max - min); + }; + + exports.linear.inverse = function(v, min, max) { + return (v - min) / (max - min); + }; + + exports.centered = function(v, min, center, max) { + if (v < .5) { + return linear(v * 2, min, center); + } else { + return linear((v - .5) * 2, center, max); + } + }; + + exports.centered.inverse = function(v, min, center, max) { + if (v < center) { + return 0.5 * linear.inverse(v, min, center); + } else { + return 0.5 + 0.5 * linear.inverse(v, center, max); + } + }; + + exports.transform = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.value / 127.0].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return 127 * f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; + }; + + exports.transformI = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.value].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; + }; + + exports.transformB = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.pressed / 127.0].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return 127 * f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; + }; + + exports.identityT = identityT = exports.transformI(exports.identity); + + exports.momentaryT = momentaryT = exports.transformB(exports.momentary); + + exports.binaryT = binaryT = exports.transformB(exports.binary); + + exports.linearT = linearT = function() { + return exports.transform.apply(exports, [exports.linear].concat(slice.call(arguments))); + }; + + exports.centeredT = centeredT = function() { + return exports.transform.apply(exports, [exports.centered].concat(slice.call(arguments))); + }; + + exports.defaultT = defaultT = linearT(0.0, 1.0); + + exports.mappings = { + "beatloop_0.0625_activate": momentaryT, + "beatloop_0.0625_toggle": momentaryT, + "beatloop_0.125_activate": momentaryT, + "beatloop_0.125_toggle": momentaryT, + "beatloop_0.5_activate": momentaryT, + "beatloop_0.5_toggle": momentaryT, + "beatlooproll_0.0625_activate": momentaryT, + "beatlooproll_0.125_activate": momentaryT, + "beatlooproll_0.5_activate": momentaryT, + back: momentaryT, + balance: linearT(-1.0, 1.0), + beatloop_16_activate: momentaryT, + beatloop_16_toggle: momentaryT, + beatloop_1_activate: momentaryT, + beatloop_1_toggle: momentaryT, + beatloop_2_activate: momentaryT, + beatloop_2_toggle: momentaryT, + beatloop_32_activate: momentaryT, + beatloop_32_toggle: momentaryT, + beatloop_4_activate: momentaryT, + beatloop_4_toggle: momentaryT, + beatloop_8_activate: momentaryT, + beatloop_8_toggle: momentaryT, + beatlooproll_16_activate: momentaryT, + beatlooproll_1_activate: momentaryT, + beatlooproll_2_activate: momentaryT, + beatlooproll_32_activate: momentaryT, + beatlooproll_4_activate: momentaryT, + beatlooproll_8_activate: momentaryT, + beatloop_double: momentaryT, + beatloop_halve: momentaryT, + beatjump_4_forward: momentaryT, + beatjump_4_backward: momentaryT, + beatjump_1_forward: momentaryT, + beatjump_1_backward: momentaryT, + beats_translate_curpos: momentaryT, + beatsync: momentaryT, + beatsync_tempo: momentaryT, + crossfader: linearT(-1.0, 1.0), + cue_default: momentaryT, + eject: momentaryT, + enabled: binaryT, + filterHigh: centeredT(0.0, 1.0, 4.0), + filterHighKill: binaryT, + filterLow: centeredT(0.0, 1.0, 4.0), + filterLowKill: binaryT, + filterMid: centeredT(0.0, 1.0, 4.0), + filterMidKill: binaryT, + fwd: momentaryT, + headMix: centeredT(-1.0, 1.0), + headVolume: centeredT(0.0, 1.0, 5.0), + hotcue_1_activate: momentaryT, + hotcue_1_clear: momentaryT, + hotcue_2_activate: momentaryT, + hotcue_2_clear: momentaryT, + hotcue_3_activate: momentaryT, + hotcue_3_clear: momentaryT, + hotcue_4_activate: momentaryT, + hotcue_4_clear: momentaryT, + hotcue_5_activate: momentaryT, + hotcue_5_clear: momentaryT, + hotcue_6_activate: momentaryT, + hotcue_6_clear: momentaryT, + hotcue_7_activate: momentaryT, + hotcue_7_clear: momentaryT, + jog: identityT, + keylock: binaryT, + lfoDelay: linearT(50.0, 10000.0), + lfoDepth: defaultT, + lfoPeriod: linearT(50000.0, 2000000.0), + LoadSelectedTrack: momentaryT, + loop_double: momentaryT, + loop_enabled: binaryT, + loop_end_position: linearT, + loop_halve: momentaryT, + loop_in: momentaryT, + loop_out: momentaryT, + loop_start_position: linearT, + play: binaryT, + playposition: linearT(0.0, 1.0), + plf: binaryT, + pregain: centeredT(0.0, 1.0, 4.0), + pregain_toggle: binaryT, + rate: linearT(-1.0, 1.0), + rate_temp_down: momentaryT, + rate_temp_down_small: momentaryT, + rate_temp_up: momentaryT, + rate_temp_up_small: momentaryT, + reverse: binaryT, + scratch2: linearT(-3.0, 3.0), + scratch2_enable: binaryT, + SelectNextPlaylist: momentaryT, + SelectNextTrack: momentaryT, + SelectPrevPlaylist: momentaryT, + SelectPrevTrack: momentaryT, + SelectTrackKnob: identityT, + slip_enabled: binaryT, + super1: linearT(0.0, 10.0), + talkover: binaryT, + ToggleSelectedSidebarItem: momentaryT, + volume: defaultT, + VuMeter: defaultT, + VuMeterL: defaultT, + VuMeterR: defaultT, + wheel: linearT(-3.0, 3.0) + }; + +}).call(this); + +},{}],8:[function(require,module,exports){ +// Generated by CoffeeScript 1.10.0 +(function() { + Function.prototype.property = function(prop, desc) { + if (desc instanceof Function) { + desc = { + get: desc + }; + } + return Object.defineProperty(this.prototype, prop, desc); + }; + + Number.prototype.clamp = function(min, max) { + return Math.min(Math.max(this, min), max); + }; + + Number.prototype.sign = function() { + if (this < 0) { + return -1; + } else { + return 1; + } + }; + + Array.prototype.equals = function(other) { + return this.length === other.length && this.every(function(elem, i) { + return elem === other[i]; + }); + }; + + exports.copy = function(a, b) { + var k, v; + if (b == null) { + b = {}; + } + for (k in a) { + v = a[k]; + b[k] = v; + } + return b; + }; + + exports.catching = function(f) { + return function() { + var err, error1; + try { + return f.apply(this, arguments); + } catch (error1) { + err = error1; + return console.log("ERROR: " + err); + } + }; + }; + + exports.assert = function(value, error) { + if (error == null) { + error = void 0; + } + if (!value) { + throw new Error(error != null ? error : "Assertion failed"); + } + }; + + exports.xmlEscape = function(str) { + var ref; + return (ref = str != null ? str.replace('&', '&').replace('"', '"').replace('>', '>').replace('<', '<') : void 0) != null ? ref : ''; + }; + + exports.indent = function(depth) { + return Array(depth * 4).join(" "); + }; + + exports.hexStr = function(number) { + return "0x" + (number.toString(16)); + }; + + exports.xmlTag = function(str, value, indent) { + if (indent == null) { + indent = 0; + } + if (value != null) { + return (exports.indent(indent)) + "<" + str + ">" + value + ""; + } else { + return ""; + } + }; + + exports.joinLn = function(lines) { + return lines.filter(function(x) { + return x; + }).join('\n'); + }; + + exports.factory = function(Klass) { + return function() { + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(Klass, arguments, function(){}); + }; + }; + +}).call(this); + +},{}],9:[function(require,module,exports){ +// Generated by CoffeeScript 1.10.0 +(function() { + var events, factory, util, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + slice = [].slice; + + events = require('events'); + + util = require('./util'); + + factory = util.factory; + + exports.Value = (function(superClass) { + extend(Value, superClass); + + function Value(arg) { + var initial; + initial = (arg != null ? arg : {}).initial; + Value.__super__.constructor.apply(this, arguments); + this.setMaxListeners(0); + if (initial != null) { + this.value = initial; + } + } + + Value.property('value', { + get: function() { + return this._value; + }, + set: function(newValue) { + return this.setValue(newValue); + } + }); + + Value.prototype.setValue = function(newValue) { + if (this._value !== newValue) { + this._value = newValue; + this.emit('value', newValue); + } + return this._value; + }; + + return Value; + + })(events.EventEmitter); + + exports.value = factory(exports.Value); + + exports.Const = (function() { + Const.prototype.value = void 0; + + function Const(initial) { + if (initial == null) { + initial = void 0; + } + this.value = initial; + } + + Const.prototype.on = function() {}; + + Const.prototype.addListener = function() {}; + + Const.prototype.removeListener = function() {}; + + Const.prototype.listeners = function() { + return []; + }; + + return Const; + + })(); + + exports["const"] = factory(exports.Const); + + exports.Reduce = (function(superClass) { + extend(Reduce, superClass); + + function Reduce() { + var i, len, reduced, reducer, ref, v; + reducer = arguments[0], reduced = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this.reducer = reducer; + this.reduced = reduced; + Reduce.__super__.constructor.call(this); + ref = this.reduced; + for (i = 0, len = ref.length; i < len; i++) { + v = ref[i]; + v.on('value', (function(_this) { + return function() { + return _this.update(); + }; + })(this)); + } + this.update(); + } + + Reduce.prototype.update = function() { + return this.value = this.reduced.reduce((function(_this) { + return function(a, b) { + return exports["const"](_this.reducer(a.value, b.value)); + }; + })(this)).value; + }; + + return Reduce; + + })(exports.Value); + + exports.reduce = factory(exports.Reduce); + + exports.and = function() { + return exports.reduce.apply(exports, [(function(a, b) { + return a && b; + })].concat(slice.call(arguments))); + }; + + exports.or = function() { + return exports.reduce.apply(exports, [(function(a, b) { + return a || b; + })].concat(slice.call(arguments))); + }; + + exports.Transform = (function(superClass) { + extend(Transform, superClass); + + function Transform(transformer, transformed) { + this.transformer = transformer; + this.transformed = transformed; + Transform.__super__.constructor.call(this); + this.transformed.on('value', (function(_this) { + return function() { + return _this.update(); + }; + })(this)); + this.update(); + } + + Transform.prototype.update = function() { + return this.value = this.transformer(this.transformed.value); + }; + + return Transform; + + })(exports.Value); + + exports.transform = factory(exports.Transform); + + exports.not = function() { + return exports.transform.apply(exports, [(function(a) { + return !a; + })].concat(slice.call(arguments))); + }; + +}).call(this); + +},{"./util":8,"events":10}],10:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +},{}],11:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// resolves . and .. elements in a path array with directory names there +// must be no slashes, empty elements, or device names (c:\) in the array +// (so also no leading and trailing slashes - it does not distinguish +// relative and absolute paths) +function normalizeArray(parts, allowAboveRoot) { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + + return parts; +} + +// Split a filename into [root, dir, basename, ext], unix version +// 'root' is just a slash, or nothing. +var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +var splitPath = function(filename) { + return splitPathRe.exec(filename).slice(1); +}; + +// path.resolve([from ...], to) +// posix version +exports.resolve = function() { + var resolvedPath = '', + resolvedAbsolute = false; + + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? arguments[i] : process.cwd(); + + // Skip empty and invalid entries + if (typeof path !== 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + continue; + } + + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path.charAt(0) === '/'; + } + + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + + // Normalize the path + resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { + return !!p; + }), !resolvedAbsolute).join('/'); + + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; +}; + +// path.normalize(path) +// posix version +exports.normalize = function(path) { + var isAbsolute = exports.isAbsolute(path), + trailingSlash = substr(path, -1) === '/'; + + // Normalize the path + path = normalizeArray(filter(path.split('/'), function(p) { + return !!p; + }), !isAbsolute).join('/'); + + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + + return (isAbsolute ? '/' : '') + path; +}; + +// posix version +exports.isAbsolute = function(path) { + return path.charAt(0) === '/'; +}; + +// posix version +exports.join = function() { + var paths = Array.prototype.slice.call(arguments, 0); + return exports.normalize(filter(paths, function(p, index) { + if (typeof p !== 'string') { + throw new TypeError('Arguments to path.join must be strings'); + } + return p; + }).join('/')); +}; + + +// path.relative(from, to) +// posix version +exports.relative = function(from, to) { + from = exports.resolve(from).substr(1); + to = exports.resolve(to).substr(1); + + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + + var end = arr.length - 1; + for (; end >= 0; end--) { + if (arr[end] !== '') break; + } + + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + + var fromParts = trim(from.split('/')); + var toParts = trim(to.split('/')); + + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + + return outputParts.join('/'); +}; + +exports.sep = '/'; +exports.delimiter = ':'; + +exports.dirname = function(path) { + var result = splitPath(path), + root = result[0], + dir = result[1]; + + if (!root && !dir) { + // No dirname whatsoever + return '.'; + } + + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.substr(0, dir.length - 1); + } + + return root + dir; +}; + + +exports.basename = function(path, ext) { + var f = splitPath(path)[2]; + // TODO: make this comparison case-insensitive on windows? + if (ext && f.substr(-1 * ext.length) === ext) { + f = f.substr(0, f.length - ext.length); + } + return f; +}; + + +exports.extname = function(path) { + return splitPath(path)[3]; +}; + +function filter (xs, f) { + if (xs.filter) return xs.filter(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (f(xs[i], i, xs)) res.push(xs[i]); + } + return res; +} + +// String.prototype.substr - negative index don't work in IE8 +var substr = 'ab'.substr(-1) === 'b' + ? function (str, start, len) { return str.substr(start, len) } + : function (str, start, len) { + if (start < 0) start = str.length + start; + return str.substr(start, len); + } +; + +}).call(this,require('_process')) +},{"_process":12}],12:[function(require,module,exports){ +// shim for using process in browser +var process = module.exports = {}; + +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. + +var cachedSetTimeout; +var cachedClearTimeout; + +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + +} +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],13:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.3 +(function() { + var assert, copyOwn, every, find, generate, head, hierarchy, inherited, isEmpty, isEqual, isJavaScriptClass, map, memoize, merge, mro, partial, ref, reject, reparent, some, tail, without, + slice = [].slice, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + + ref = require('underscore'), head = ref.head, tail = ref.tail, map = ref.map, find = ref.find, some = ref.some, without = ref.without, isEmpty = ref.isEmpty, every = ref.every, memoize = ref.memoize, reject = ref.reject, partial = ref.partial, isEqual = ref.isEqual; + + assert = function(value, error) { + if (error == null) { + error = void 0; + } + if (!value) { + throw new Error(error != null ? error : "Assertion failed"); + } + }; + + exports.multi = function() { + var bases; + bases = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return generate(merge(map(bases, mro).concat([bases]))); + }; + + generate = memoize(function(linearization) { + var next, result; + next = head(linearization); + if (isEqual(linearization, hierarchy(next))) { + return next; + } else { + return result = (function(superClass) { + var class1; + + extend(result, superClass); + + function result() { + return class1.apply(this, arguments); + } + + result.prototype.__mro__ = linearization; + + class1 = reparent(next, result, next.prototype.constructor); + + copyOwn(next, result); + + copyOwn(next.prototype, result.prototype, partial(reparent, next, result)); + + return result; + + })(generate(tail(linearization))); + } + }); + + copyOwn = function(from, to, project) { + var key, value; + if (project == null) { + project = function(x) { + return x; + }; + } + for (key in from) { + if (!hasProp.call(from, key)) continue; + value = from[key]; + if (!to.hasOwnProperty(key)) { + to[key] = project(value); + } + } + return to; + }; + + reparent = function(oldklass, newklass, value) { + var newsuper, oldsuper, superctor; + if (!(value instanceof Function)) { + return value; + } else if (value === oldklass.prototype.constructor && inherited(oldklass) === Object) { + superctor = inherited(newklass).prototype.constructor; + return function() { + superctor.apply(this, arguments); + return value.apply(this, arguments); + }; + } else { + newsuper = inherited(newklass).prototype; + oldsuper = oldklass.__super__; + return function() { + oldklass.__super__ = newsuper; + try { + return value.apply(this, arguments); + } finally { + oldklass.__super__ = oldsuper; + } + }; + } + }; + + merge = function(inputs) { + var next, results; + results = []; + while (!isEmpty(inputs)) { + next = find(map(inputs, head), function(candidate) { + return every(inputs, function(input) { + return indexOf.call(tail(input), candidate) < 0; + }); + }); + assert(next != null, "Inconsistent multiple inheritance"); + inputs = reject(map(inputs, function(lst) { + return without(lst, next); + }), isEmpty); + results.push(next); + } + return results; + }; + + isJavaScriptClass = function(cls) { + return cls === Array || cls === Boolean || cls === Date || cls === Error || cls === Function || cls === Number || cls === RegExp || cls === String || cls === Object; + }; + + exports.mro = mro = function(cls) { + var result; + if ((cls == null) || (cls.prototype == null)) { + return []; + } else if (!cls.prototype.hasOwnProperty('__mro__')) { + result = [cls].concat(mro(inherited(cls))); + if (!isJavaScriptClass(cls)) { + cls.prototype.__mro__ = result; + } + return result; + } else { + return cls.prototype.__mro__; + } + }; + + exports.inherited = inherited = function(cls) { + var ref1; + return (ref1 = Object.getPrototypeOf(cls.prototype)) != null ? ref1.constructor : void 0; + }; + + exports.hierarchy = hierarchy = function(cls) { + if (cls == null) { + return []; + } else { + return [cls].concat(hierarchy(inherited(cls))); + } + }; + + exports.isinstance = function() { + var classes, obj; + obj = arguments[0], classes = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.issubclass.apply(exports, [obj != null ? obj.constructor : void 0].concat(slice.call(classes))); + }; + + exports.issubclass = function() { + var classes, klass, linearization; + klass = arguments[0], classes = 2 <= arguments.length ? slice.call(arguments, 1) : []; + linearization = mro(klass); + return some(classes, function(cls) { + return indexOf.call(linearization, cls) >= 0; + }); + }; + +}).call(this); + +},{"underscore":16}],14:[function(require,module,exports){ +function count(self, substr) { + var count = 0 + var pos = self.indexOf(substr) + + while (pos >= 0) { + count += 1 + pos = self.indexOf(substr, pos + 1) + } + + return count +} + +module.exports = count +},{}],15:[function(require,module,exports){ +/* +string.js - Copyright (C) 2012-2014, JP Richardson +*/ + +!(function() { + "use strict"; + + var VERSION = '3.1.3'; + + var ENTITIES = {}; + + // from http://semplicewebsites.com/removing-accents-javascript + var latin_map={"Á":"A","Ă":"A","Ắ":"A","Ặ":"A","Ằ":"A","Ẳ":"A","Ẵ":"A","Ǎ":"A","Â":"A","Ấ":"A","Ậ":"A","Ầ":"A","Ẩ":"A","Ẫ":"A","Ä":"A","Ǟ":"A","Ȧ":"A","Ǡ":"A","Ạ":"A","Ȁ":"A","À":"A","Ả":"A","Ȃ":"A","Ā":"A","Ą":"A","Å":"A","Ǻ":"A","Ḁ":"A","Ⱥ":"A","Ã":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ḃ":"B","Ḅ":"B","Ɓ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ć":"C","Č":"C","Ç":"C","Ḉ":"C","Ĉ":"C","Ċ":"C","Ƈ":"C","Ȼ":"C","Ď":"D","Ḑ":"D","Ḓ":"D","Ḋ":"D","Ḍ":"D","Ɗ":"D","Ḏ":"D","Dz":"D","Dž":"D","Đ":"D","Ƌ":"D","DZ":"DZ","DŽ":"DZ","É":"E","Ĕ":"E","Ě":"E","Ȩ":"E","Ḝ":"E","Ê":"E","Ế":"E","Ệ":"E","Ề":"E","Ể":"E","Ễ":"E","Ḙ":"E","Ë":"E","Ė":"E","Ẹ":"E","Ȅ":"E","È":"E","Ẻ":"E","Ȇ":"E","Ē":"E","Ḗ":"E","Ḕ":"E","Ę":"E","Ɇ":"E","Ẽ":"E","Ḛ":"E","Ꝫ":"ET","Ḟ":"F","Ƒ":"F","Ǵ":"G","Ğ":"G","Ǧ":"G","Ģ":"G","Ĝ":"G","Ġ":"G","Ɠ":"G","Ḡ":"G","Ǥ":"G","Ḫ":"H","Ȟ":"H","Ḩ":"H","Ĥ":"H","Ⱨ":"H","Ḧ":"H","Ḣ":"H","Ḥ":"H","Ħ":"H","Í":"I","Ĭ":"I","Ǐ":"I","Î":"I","Ï":"I","Ḯ":"I","İ":"I","Ị":"I","Ȉ":"I","Ì":"I","Ỉ":"I","Ȋ":"I","Ī":"I","Į":"I","Ɨ":"I","Ĩ":"I","Ḭ":"I","Ꝺ":"D","Ꝼ":"F","Ᵹ":"G","Ꞃ":"R","Ꞅ":"S","Ꞇ":"T","Ꝭ":"IS","Ĵ":"J","Ɉ":"J","Ḱ":"K","Ǩ":"K","Ķ":"K","Ⱪ":"K","Ꝃ":"K","Ḳ":"K","Ƙ":"K","Ḵ":"K","Ꝁ":"K","Ꝅ":"K","Ĺ":"L","Ƚ":"L","Ľ":"L","Ļ":"L","Ḽ":"L","Ḷ":"L","Ḹ":"L","Ⱡ":"L","Ꝉ":"L","Ḻ":"L","Ŀ":"L","Ɫ":"L","Lj":"L","Ł":"L","LJ":"LJ","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ń":"N","Ň":"N","Ņ":"N","Ṋ":"N","Ṅ":"N","Ṇ":"N","Ǹ":"N","Ɲ":"N","Ṉ":"N","Ƞ":"N","Nj":"N","Ñ":"N","NJ":"NJ","Ó":"O","Ŏ":"O","Ǒ":"O","Ô":"O","Ố":"O","Ộ":"O","Ồ":"O","Ổ":"O","Ỗ":"O","Ö":"O","Ȫ":"O","Ȯ":"O","Ȱ":"O","Ọ":"O","Ő":"O","Ȍ":"O","Ò":"O","Ỏ":"O","Ơ":"O","Ớ":"O","Ợ":"O","Ờ":"O","Ở":"O","Ỡ":"O","Ȏ":"O","Ꝋ":"O","Ꝍ":"O","Ō":"O","Ṓ":"O","Ṑ":"O","Ɵ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Õ":"O","Ṍ":"O","Ṏ":"O","Ȭ":"O","Ƣ":"OI","Ꝏ":"OO","Ɛ":"E","Ɔ":"O","Ȣ":"OU","Ṕ":"P","Ṗ":"P","Ꝓ":"P","Ƥ":"P","Ꝕ":"P","Ᵽ":"P","Ꝑ":"P","Ꝙ":"Q","Ꝗ":"Q","Ŕ":"R","Ř":"R","Ŗ":"R","Ṙ":"R","Ṛ":"R","Ṝ":"R","Ȑ":"R","Ȓ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꜿ":"C","Ǝ":"E","Ś":"S","Ṥ":"S","Š":"S","Ṧ":"S","Ş":"S","Ŝ":"S","Ș":"S","Ṡ":"S","Ṣ":"S","Ṩ":"S","ẞ":"SS","Ť":"T","Ţ":"T","Ṱ":"T","Ț":"T","Ⱦ":"T","Ṫ":"T","Ṭ":"T","Ƭ":"T","Ṯ":"T","Ʈ":"T","Ŧ":"T","Ɐ":"A","Ꞁ":"L","Ɯ":"M","Ʌ":"V","Ꜩ":"TZ","Ú":"U","Ŭ":"U","Ǔ":"U","Û":"U","Ṷ":"U","Ü":"U","Ǘ":"U","Ǚ":"U","Ǜ":"U","Ǖ":"U","Ṳ":"U","Ụ":"U","Ű":"U","Ȕ":"U","Ù":"U","Ủ":"U","Ư":"U","Ứ":"U","Ự":"U","Ừ":"U","Ử":"U","Ữ":"U","Ȗ":"U","Ū":"U","Ṻ":"U","Ų":"U","Ů":"U","Ũ":"U","Ṹ":"U","Ṵ":"U","Ꝟ":"V","Ṿ":"V","Ʋ":"V","Ṽ":"V","Ꝡ":"VY","Ẃ":"W","Ŵ":"W","Ẅ":"W","Ẇ":"W","Ẉ":"W","Ẁ":"W","Ⱳ":"W","Ẍ":"X","Ẋ":"X","Ý":"Y","Ŷ":"Y","Ÿ":"Y","Ẏ":"Y","Ỵ":"Y","Ỳ":"Y","Ƴ":"Y","Ỷ":"Y","Ỿ":"Y","Ȳ":"Y","Ɏ":"Y","Ỹ":"Y","Ź":"Z","Ž":"Z","Ẑ":"Z","Ⱬ":"Z","Ż":"Z","Ẓ":"Z","Ȥ":"Z","Ẕ":"Z","Ƶ":"Z","IJ":"IJ","Œ":"OE","ᴀ":"A","ᴁ":"AE","ʙ":"B","ᴃ":"B","ᴄ":"C","ᴅ":"D","ᴇ":"E","ꜰ":"F","ɢ":"G","ʛ":"G","ʜ":"H","ɪ":"I","ʁ":"R","ᴊ":"J","ᴋ":"K","ʟ":"L","ᴌ":"L","ᴍ":"M","ɴ":"N","ᴏ":"O","ɶ":"OE","ᴐ":"O","ᴕ":"OU","ᴘ":"P","ʀ":"R","ᴎ":"N","ᴙ":"R","ꜱ":"S","ᴛ":"T","ⱻ":"E","ᴚ":"R","ᴜ":"U","ᴠ":"V","ᴡ":"W","ʏ":"Y","ᴢ":"Z","á":"a","ă":"a","ắ":"a","ặ":"a","ằ":"a","ẳ":"a","ẵ":"a","ǎ":"a","â":"a","ấ":"a","ậ":"a","ầ":"a","ẩ":"a","ẫ":"a","ä":"a","ǟ":"a","ȧ":"a","ǡ":"a","ạ":"a","ȁ":"a","à":"a","ả":"a","ȃ":"a","ā":"a","ą":"a","ᶏ":"a","ẚ":"a","å":"a","ǻ":"a","ḁ":"a","ⱥ":"a","ã":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ḃ":"b","ḅ":"b","ɓ":"b","ḇ":"b","ᵬ":"b","ᶀ":"b","ƀ":"b","ƃ":"b","ɵ":"o","ć":"c","č":"c","ç":"c","ḉ":"c","ĉ":"c","ɕ":"c","ċ":"c","ƈ":"c","ȼ":"c","ď":"d","ḑ":"d","ḓ":"d","ȡ":"d","ḋ":"d","ḍ":"d","ɗ":"d","ᶑ":"d","ḏ":"d","ᵭ":"d","ᶁ":"d","đ":"d","ɖ":"d","ƌ":"d","ı":"i","ȷ":"j","ɟ":"j","ʄ":"j","dz":"dz","dž":"dz","é":"e","ĕ":"e","ě":"e","ȩ":"e","ḝ":"e","ê":"e","ế":"e","ệ":"e","ề":"e","ể":"e","ễ":"e","ḙ":"e","ë":"e","ė":"e","ẹ":"e","ȅ":"e","è":"e","ẻ":"e","ȇ":"e","ē":"e","ḗ":"e","ḕ":"e","ⱸ":"e","ę":"e","ᶒ":"e","ɇ":"e","ẽ":"e","ḛ":"e","ꝫ":"et","ḟ":"f","ƒ":"f","ᵮ":"f","ᶂ":"f","ǵ":"g","ğ":"g","ǧ":"g","ģ":"g","ĝ":"g","ġ":"g","ɠ":"g","ḡ":"g","ᶃ":"g","ǥ":"g","ḫ":"h","ȟ":"h","ḩ":"h","ĥ":"h","ⱨ":"h","ḧ":"h","ḣ":"h","ḥ":"h","ɦ":"h","ẖ":"h","ħ":"h","ƕ":"hv","í":"i","ĭ":"i","ǐ":"i","î":"i","ï":"i","ḯ":"i","ị":"i","ȉ":"i","ì":"i","ỉ":"i","ȋ":"i","ī":"i","į":"i","ᶖ":"i","ɨ":"i","ĩ":"i","ḭ":"i","ꝺ":"d","ꝼ":"f","ᵹ":"g","ꞃ":"r","ꞅ":"s","ꞇ":"t","ꝭ":"is","ǰ":"j","ĵ":"j","ʝ":"j","ɉ":"j","ḱ":"k","ǩ":"k","ķ":"k","ⱪ":"k","ꝃ":"k","ḳ":"k","ƙ":"k","ḵ":"k","ᶄ":"k","ꝁ":"k","ꝅ":"k","ĺ":"l","ƚ":"l","ɬ":"l","ľ":"l","ļ":"l","ḽ":"l","ȴ":"l","ḷ":"l","ḹ":"l","ⱡ":"l","ꝉ":"l","ḻ":"l","ŀ":"l","ɫ":"l","ᶅ":"l","ɭ":"l","ł":"l","lj":"lj","ſ":"s","ẜ":"s","ẛ":"s","ẝ":"s","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ᵯ":"m","ᶆ":"m","ń":"n","ň":"n","ņ":"n","ṋ":"n","ȵ":"n","ṅ":"n","ṇ":"n","ǹ":"n","ɲ":"n","ṉ":"n","ƞ":"n","ᵰ":"n","ᶇ":"n","ɳ":"n","ñ":"n","nj":"nj","ó":"o","ŏ":"o","ǒ":"o","ô":"o","ố":"o","ộ":"o","ồ":"o","ổ":"o","ỗ":"o","ö":"o","ȫ":"o","ȯ":"o","ȱ":"o","ọ":"o","ő":"o","ȍ":"o","ò":"o","ỏ":"o","ơ":"o","ớ":"o","ợ":"o","ờ":"o","ở":"o","ỡ":"o","ȏ":"o","ꝋ":"o","ꝍ":"o","ⱺ":"o","ō":"o","ṓ":"o","ṑ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","õ":"o","ṍ":"o","ṏ":"o","ȭ":"o","ƣ":"oi","ꝏ":"oo","ɛ":"e","ᶓ":"e","ɔ":"o","ᶗ":"o","ȣ":"ou","ṕ":"p","ṗ":"p","ꝓ":"p","ƥ":"p","ᵱ":"p","ᶈ":"p","ꝕ":"p","ᵽ":"p","ꝑ":"p","ꝙ":"q","ʠ":"q","ɋ":"q","ꝗ":"q","ŕ":"r","ř":"r","ŗ":"r","ṙ":"r","ṛ":"r","ṝ":"r","ȑ":"r","ɾ":"r","ᵳ":"r","ȓ":"r","ṟ":"r","ɼ":"r","ᵲ":"r","ᶉ":"r","ɍ":"r","ɽ":"r","ↄ":"c","ꜿ":"c","ɘ":"e","ɿ":"r","ś":"s","ṥ":"s","š":"s","ṧ":"s","ş":"s","ŝ":"s","ș":"s","ṡ":"s","ṣ":"s","ṩ":"s","ʂ":"s","ᵴ":"s","ᶊ":"s","ȿ":"s","ɡ":"g","ß":"ss","ᴑ":"o","ᴓ":"o","ᴝ":"u","ť":"t","ţ":"t","ṱ":"t","ț":"t","ȶ":"t","ẗ":"t","ⱦ":"t","ṫ":"t","ṭ":"t","ƭ":"t","ṯ":"t","ᵵ":"t","ƫ":"t","ʈ":"t","ŧ":"t","ᵺ":"th","ɐ":"a","ᴂ":"ae","ǝ":"e","ᵷ":"g","ɥ":"h","ʮ":"h","ʯ":"h","ᴉ":"i","ʞ":"k","ꞁ":"l","ɯ":"m","ɰ":"m","ᴔ":"oe","ɹ":"r","ɻ":"r","ɺ":"r","ⱹ":"r","ʇ":"t","ʌ":"v","ʍ":"w","ʎ":"y","ꜩ":"tz","ú":"u","ŭ":"u","ǔ":"u","û":"u","ṷ":"u","ü":"u","ǘ":"u","ǚ":"u","ǜ":"u","ǖ":"u","ṳ":"u","ụ":"u","ű":"u","ȕ":"u","ù":"u","ủ":"u","ư":"u","ứ":"u","ự":"u","ừ":"u","ử":"u","ữ":"u","ȗ":"u","ū":"u","ṻ":"u","ų":"u","ᶙ":"u","ů":"u","ũ":"u","ṹ":"u","ṵ":"u","ᵫ":"ue","ꝸ":"um","ⱴ":"v","ꝟ":"v","ṿ":"v","ʋ":"v","ᶌ":"v","ⱱ":"v","ṽ":"v","ꝡ":"vy","ẃ":"w","ŵ":"w","ẅ":"w","ẇ":"w","ẉ":"w","ẁ":"w","ⱳ":"w","ẘ":"w","ẍ":"x","ẋ":"x","ᶍ":"x","ý":"y","ŷ":"y","ÿ":"y","ẏ":"y","ỵ":"y","ỳ":"y","ƴ":"y","ỷ":"y","ỿ":"y","ȳ":"y","ẙ":"y","ɏ":"y","ỹ":"y","ź":"z","ž":"z","ẑ":"z","ʑ":"z","ⱬ":"z","ż":"z","ẓ":"z","ȥ":"z","ẕ":"z","ᵶ":"z","ᶎ":"z","ʐ":"z","ƶ":"z","ɀ":"z","ff":"ff","ffi":"ffi","ffl":"ffl","fi":"fi","fl":"fl","ij":"ij","œ":"oe","st":"st","ₐ":"a","ₑ":"e","ᵢ":"i","ⱼ":"j","ₒ":"o","ᵣ":"r","ᵤ":"u","ᵥ":"v","ₓ":"x"}; + +//****************************************************************************** +// Added an initialize function which is essentially the code from the S +// constructor. Now, the S constructor calls this and a new method named +// setValue calls it as well. The setValue function allows constructors for +// modules that extend string.js to set the initial value of an object without +// knowing the internal workings of string.js. +// +// Also, all methods which return a new S object now call: +// +// return new this.constructor(s); +// +// instead of: +// +// return new S(s); +// +// This allows extended objects to keep their proper instanceOf and constructor. +//****************************************************************************** + + function initialize (object, s) { + if (s !== null && s !== undefined) { + if (typeof s === 'string') + object.s = s; + else + object.s = s.toString(); + } else { + object.s = s; //null or undefined + } + + object.orig = s; //original object, currently only used by toCSV() and toBoolean() + + if (s !== null && s !== undefined) { + if (object.__defineGetter__) { + object.__defineGetter__('length', function() { + return object.s.length; + }) + } else { + object.length = s.length; + } + } else { + object.length = -1; + } + } + + function S(s) { + initialize(this, s); + } + + var __nsp = String.prototype; + var __sp = S.prototype = { + + between: function(left, right) { + var s = this.s; + var startPos = s.indexOf(left); + var endPos = s.indexOf(right, startPos + left.length); + if (endPos == -1 && right != null) + return new this.constructor('') + else if (endPos == -1 && right == null) + return new this.constructor(s.substring(startPos + left.length)) + else + return new this.constructor(s.slice(startPos + left.length, endPos)); + }, + + //# modified slightly from https://github.com/epeli/underscore.string + camelize: function() { + var s = this.trim().s.replace(/(\-|_|\s)+(.)?/g, function(mathc, sep, c) { + return (c ? c.toUpperCase() : ''); + }); + return new this.constructor(s); + }, + + capitalize: function() { + return new this.constructor(this.s.substr(0, 1).toUpperCase() + this.s.substring(1).toLowerCase()); + }, + + charAt: function(index) { + return this.s.charAt(index); + }, + + chompLeft: function(prefix) { + var s = this.s; + if (s.indexOf(prefix) === 0) { + s = s.slice(prefix.length); + return new this.constructor(s); + } else { + return this; + } + }, + + chompRight: function(suffix) { + if (this.endsWith(suffix)) { + var s = this.s; + s = s.slice(0, s.length - suffix.length); + return new this.constructor(s); + } else { + return this; + } + }, + + //#thanks Google + collapseWhitespace: function() { + var s = this.s.replace(/[\s\xa0]+/g, ' ').replace(/^\s+|\s+$/g, ''); + return new this.constructor(s); + }, + + contains: function(ss) { + return this.s.indexOf(ss) >= 0; + }, + + count: function(ss) { + return require('./_count')(this.s, ss) + }, + + //#modified from https://github.com/epeli/underscore.string + dasherize: function() { + var s = this.trim().s.replace(/[_\s]+/g, '-').replace(/([A-Z])/g, '-$1').replace(/-+/g, '-').toLowerCase(); + return new this.constructor(s); + }, + + latinise: function() { + var s = this.replace(/[^A-Za-z0-9\[\] ]/g, function(x) { return latin_map[x] || x; }); + return new this.constructor(s); + }, + + decodeHtmlEntities: function() { //https://github.com/substack/node-ent/blob/master/index.js + var s = this.s; + s = s.replace(/&#(\d+);?/g, function (_, code) { + return String.fromCharCode(code); + }) + .replace(/&#[xX]([A-Fa-f0-9]+);?/g, function (_, hex) { + return String.fromCharCode(parseInt(hex, 16)); + }) + .replace(/&([^;\W]+;?)/g, function (m, e) { + var ee = e.replace(/;$/, ''); + var target = ENTITIES[e] || (e.match(/;$/) && ENTITIES[ee]); + + if (typeof target === 'number') { + return String.fromCharCode(target); + } + else if (typeof target === 'string') { + return target; + } + else { + return m; + } + }) + + return new this.constructor(s); + }, + + endsWith: function() { + var suffixes = Array.prototype.slice.call(arguments, 0); + for (var i = 0; i < suffixes.length; ++i) { + var l = this.s.length - suffixes[i].length; + if (l >= 0 && this.s.indexOf(suffixes[i], l) === l) return true; + } + return false; + }, + + escapeHTML: function() { //from underscore.string + return new this.constructor(this.s.replace(/[&<>"']/g, function(m){ return '&' + reversedEscapeChars[m] + ';'; })); + }, + + ensureLeft: function(prefix) { + var s = this.s; + if (s.indexOf(prefix) === 0) { + return this; + } else { + return new this.constructor(prefix + s); + } + }, + + ensureRight: function(suffix) { + var s = this.s; + if (this.endsWith(suffix)) { + return this; + } else { + return new this.constructor(s + suffix); + } + }, + + humanize: function() { //modified from underscore.string + if (this.s === null || this.s === undefined) + return new this.constructor('') + var s = this.underscore().replace(/_id$/,'').replace(/_/g, ' ').trim().capitalize() + return new this.constructor(s) + }, + + isAlpha: function() { + return !/[^a-z\xDF-\xFF]|^$/.test(this.s.toLowerCase()); + }, + + isAlphaNumeric: function() { + return !/[^0-9a-z\xDF-\xFF]/.test(this.s.toLowerCase()); + }, + + isEmpty: function() { + return this.s === null || this.s === undefined ? true : /^[\s\xa0]*$/.test(this.s); + }, + + isLower: function() { + return this.isAlpha() && this.s.toLowerCase() === this.s; + }, + + isNumeric: function() { + return !/[^0-9]/.test(this.s); + }, + + isUpper: function() { + return this.isAlpha() && this.s.toUpperCase() === this.s; + }, + + left: function(N) { + if (N >= 0) { + var s = this.s.substr(0, N); + return new this.constructor(s); + } else { + return this.right(-N); + } + }, + + lines: function() { //convert windows newlines to unix newlines then convert to an Array of lines + return this.replaceAll('\r\n', '\n').s.split('\n'); + }, + + pad: function(len, ch) { //https://github.com/component/pad + if (ch == null) ch = ' '; + if (this.s.length >= len) return new this.constructor(this.s); + len = len - this.s.length; + var left = Array(Math.ceil(len / 2) + 1).join(ch); + var right = Array(Math.floor(len / 2) + 1).join(ch); + return new this.constructor(left + this.s + right); + }, + + padLeft: function(len, ch) { //https://github.com/component/pad + if (ch == null) ch = ' '; + if (this.s.length >= len) return new this.constructor(this.s); + return new this.constructor(Array(len - this.s.length + 1).join(ch) + this.s); + }, + + padRight: function(len, ch) { //https://github.com/component/pad + if (ch == null) ch = ' '; + if (this.s.length >= len) return new this.constructor(this.s); + return new this.constructor(this.s + Array(len - this.s.length + 1).join(ch)); + }, + + parseCSV: function(delimiter, qualifier, escape, lineDelimiter) { //try to parse no matter what + delimiter = delimiter || ','; + escape = escape || '\\' + if (typeof qualifier == 'undefined') + qualifier = '"'; + + var i = 0, fieldBuffer = [], fields = [], len = this.s.length, inField = false, inUnqualifiedString = false, self = this; + var ca = function(i){return self.s.charAt(i)}; + if (typeof lineDelimiter !== 'undefined') var rows = []; + + if (!qualifier) + inField = true; + + while (i < len) { + var current = ca(i); + switch (current) { + case escape: + //fix for issues #32 and #35 + if (inField && ((escape !== qualifier) || ca(i+1) === qualifier)) { + i += 1; + fieldBuffer.push(ca(i)); + break; + } + if (escape !== qualifier) break; + case qualifier: + inField = !inField; + break; + case delimiter: + if(inUnqualifiedString) { + inField=false; + inUnqualifiedString=false; + } + if (inField && qualifier) + fieldBuffer.push(current); + else { + fields.push(fieldBuffer.join('')) + fieldBuffer.length = 0; + } + break; + case lineDelimiter: + if(inUnqualifiedString) { + inField=false; + inUnqualifiedString=false; + fields.push(fieldBuffer.join('')) + rows.push(fields); + fields = []; + fieldBuffer.length = 0; + } + else if (inField) { + fieldBuffer.push(current); + } else { + if (rows) { + fields.push(fieldBuffer.join('')) + rows.push(fields); + fields = []; + fieldBuffer.length = 0; + } + } + break; + case ' ': + if (inField) + fieldBuffer.push(current); + break; + default: + if (inField) + fieldBuffer.push(current); + else if(current!==qualifier) { + fieldBuffer.push(current); + inField=true; + inUnqualifiedString=true; + } + break; + } + i += 1; + } + + fields.push(fieldBuffer.join('')); + if (rows) { + rows.push(fields); + return rows; + } + return fields; + }, + + replaceAll: function(ss, r) { + //var s = this.s.replace(new RegExp(ss, 'g'), r); + var s = this.s.split(ss).join(r) + return new this.constructor(s); + }, + + strip: function() { + var ss = this.s; + for(var i= 0, n=arguments.length; i= 0) { + var s = this.s.substr(this.s.length - N, N); + return new this.constructor(s); + } else { + return this.left(-N); + } + }, + + setValue: function (s) { + initialize(this, s); + return this; + }, + + slugify: function() { + var sl = (new S(new S(this.s).latinise().s.replace(/[^\w\s-]/g, '').toLowerCase())).dasherize().s; + if (sl.charAt(0) === '-') + sl = sl.substr(1); + return new this.constructor(sl); + }, + + startsWith: function() { + var prefixes = Array.prototype.slice.call(arguments, 0); + for (var i = 0; i < prefixes.length; ++i) { + if (this.s.lastIndexOf(prefixes[i], 0) === 0) return true; + } + return false; + }, + + stripPunctuation: function() { + //return new this.constructor(this.s.replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()]/g,"")); + return new this.constructor(this.s.replace(/[^\w\s]|_/g, "").replace(/\s+/g, " ")); + }, + + stripTags: function() { //from sugar.js + var s = this.s, args = arguments.length > 0 ? arguments : ['']; + multiArgs(args, function(tag) { + s = s.replace(RegExp('<\/?' + tag + '[^<>]*>', 'gi'), ''); + }); + return new this.constructor(s); + }, + + template: function(values, opening, closing) { + var s = this.s + var opening = opening || Export.TMPL_OPEN + var closing = closing || Export.TMPL_CLOSE + + var open = opening.replace(/[-[\]()*\s]/g, "\\$&").replace(/\$/g, '\\$') + var close = closing.replace(/[-[\]()*\s]/g, "\\$&").replace(/\$/g, '\\$') + var r = new RegExp(open + '(.+?)' + close, 'g') + //, r = /\{\{(.+?)\}\}/g + var matches = s.match(r) || []; + + matches.forEach(function(match) { + var key = match.substring(opening.length, match.length - closing.length).trim();//chop {{ and }} + var value = typeof values[key] == 'undefined' ? '' : values[key]; + s = s.replace(match, value); + }); + return new this.constructor(s); + }, + + times: function(n) { + return new this.constructor(new Array(n + 1).join(this.s)); + }, + + toBoolean: function() { + if (typeof this.orig === 'string') { + var s = this.s.toLowerCase(); + return s === 'true' || s === 'yes' || s === 'on' || s === '1'; + } else + return this.orig === true || this.orig === 1; + }, + + toFloat: function(precision) { + var num = parseFloat(this.s) + if (precision) + return parseFloat(num.toFixed(precision)) + else + return num + }, + + toInt: function() { //thanks Google + // If the string starts with '0x' or '-0x', parse as hex. + return /^\s*-?0x/i.test(this.s) ? parseInt(this.s, 16) : parseInt(this.s, 10) + }, + + trim: function() { + var s; + if (typeof __nsp.trim === 'undefined') + s = this.s.replace(/(^\s*|\s*$)/g, '') + else + s = this.s.trim() + return new this.constructor(s); + }, + + trimLeft: function() { + var s; + if (__nsp.trimLeft) + s = this.s.trimLeft(); + else + s = this.s.replace(/(^\s*)/g, ''); + return new this.constructor(s); + }, + + trimRight: function() { + var s; + if (__nsp.trimRight) + s = this.s.trimRight(); + else + s = this.s.replace(/\s+$/, ''); + return new this.constructor(s); + }, + + truncate: function(length, pruneStr) { //from underscore.string, author: github.com/rwz + var str = this.s; + + length = ~~length; + pruneStr = pruneStr || '...'; + + if (str.length <= length) return new this.constructor(str); + + var tmpl = function(c){ return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' '; }, + template = str.slice(0, length+1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA' + + if (template.slice(template.length-2).match(/\w\w/)) + template = template.replace(/\s*\S+$/, ''); + else + template = new S(template.slice(0, template.length-1)).trimRight().s; + + return (template+pruneStr).length > str.length ? new S(str) : new S(str.slice(0, template.length)+pruneStr); + }, + + toCSV: function() { + var delim = ',', qualifier = '"', escape = '\\', encloseNumbers = true, keys = false; + var dataArray = []; + + function hasVal(it) { + return it !== null && it !== ''; + } + + if (typeof arguments[0] === 'object') { + delim = arguments[0].delimiter || delim; + delim = arguments[0].separator || delim; + qualifier = arguments[0].qualifier || qualifier; + encloseNumbers = !!arguments[0].encloseNumbers; + escape = arguments[0].escape || escape; + keys = !!arguments[0].keys; + } else if (typeof arguments[0] === 'string') { + delim = arguments[0]; + } + + if (typeof arguments[1] === 'string') + qualifier = arguments[1]; + + if (arguments[1] === null) + qualifier = null; + + if (this.orig instanceof Array) + dataArray = this.orig; + else { //object + for (var key in this.orig) + if (this.orig.hasOwnProperty(key)) + if (keys) + dataArray.push(key); + else + dataArray.push(this.orig[key]); + } + + var rep = escape + qualifier; + var buildString = []; + for (var i = 0; i < dataArray.length; ++i) { + var shouldQualify = hasVal(qualifier) + if (typeof dataArray[i] == 'number') + shouldQualify &= encloseNumbers; + + if (shouldQualify) + buildString.push(qualifier); + + if (dataArray[i] !== null && dataArray[i] !== undefined) { + var d = new S(dataArray[i]).replaceAll(qualifier, rep).s; + buildString.push(d); + } else + buildString.push('') + + if (shouldQualify) + buildString.push(qualifier); + + if (delim) + buildString.push(delim); + } + + //chop last delim + //console.log(buildString.length) + buildString.length = buildString.length - 1; + return new this.constructor(buildString.join('')); + }, + + toString: function() { + return this.s; + }, + + //#modified from https://github.com/epeli/underscore.string + underscore: function() { + var s = this.trim().s.replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/([A-Z\d]+)([A-Z][a-z])/,'$1_$2').replace(/[-\s]+/g, '_').toLowerCase(); + return new this.constructor(s); + }, + + unescapeHTML: function() { //from underscore.string + return new this.constructor(this.s.replace(/\&([^;]+);/g, function(entity, entityCode){ + var match; + + if (entityCode in escapeChars) { + return escapeChars[entityCode]; + } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) { + return String.fromCharCode(parseInt(match[1], 16)); + } else if (match = entityCode.match(/^#(\d+)$/)) { + return String.fromCharCode(~~match[1]); + } else { + return entity; + } + })); + }, + + valueOf: function() { + return this.s.valueOf(); + }, + + //#Added a New Function called wrapHTML. + wrapHTML: function (tagName, tagAttrs) { + var s = this.s, el = (tagName == null) ? 'span' : tagName, elAttr = '', wrapped = ''; + if(typeof tagAttrs == 'object') for(var prop in tagAttrs) elAttr += ' ' + prop + '="' +(new this.constructor(tagAttrs[prop])).escapeHTML() + '"'; + s = wrapped.concat('<', el, elAttr, '>', this, ''); + return new this.constructor(s); + } + } + + var methodsAdded = []; + function extendPrototype() { + for (var name in __sp) { + (function(name){ + var func = __sp[name]; + if (!__nsp.hasOwnProperty(name)) { + methodsAdded.push(name); + __nsp[name] = function() { + String.prototype.s = this; + return func.apply(this, arguments); + } + } + })(name); + } + } + + function restorePrototype() { + for (var i = 0; i < methodsAdded.length; ++i) + delete String.prototype[methodsAdded[i]]; + methodsAdded.length = 0; + } + + +/************************************* +/* Attach Native JavaScript String Properties +/*************************************/ + + var nativeProperties = getNativeStringProperties(); + for (var name in nativeProperties) { + (function(name) { + var stringProp = __nsp[name]; + if (typeof stringProp == 'function') { + //console.log(stringProp) + if (!__sp[name]) { + if (nativeProperties[name] === 'string') { + __sp[name] = function() { + //console.log(name) + return new this.constructor(stringProp.apply(this, arguments)); + } + } else { + __sp[name] = stringProp; + } + } + } + })(name); + } + + +/************************************* +/* Function Aliases +/*************************************/ + + __sp.repeat = __sp.times; + __sp.include = __sp.contains; + __sp.toInteger = __sp.toInt; + __sp.toBool = __sp.toBoolean; + __sp.decodeHTMLEntities = __sp.decodeHtmlEntities //ensure consistent casing scheme of 'HTML' + + +//****************************************************************************** +// Set the constructor. Without this, string.js objects are instances of +// Object instead of S. +//****************************************************************************** + + __sp.constructor = S; + + +/************************************* +/* Private Functions +/*************************************/ + + function getNativeStringProperties() { + var names = getNativeStringPropertyNames(); + var retObj = {}; + + for (var i = 0; i < names.length; ++i) { + var name = names[i]; + var func = __nsp[name]; + try { + // #127: pass extra parameter to keep shelljs happy + var type = typeof func.apply('test', ['string']); + retObj[name] = type; + } catch (e) {} + } + return retObj; + } + + function getNativeStringPropertyNames() { + var results = []; + if (Object.getOwnPropertyNames) { + results = Object.getOwnPropertyNames(__nsp); + results.splice(results.indexOf('valueOf'), 1); + results.splice(results.indexOf('toString'), 1); + return results; + } else { //meant for legacy cruft, this could probably be made more efficient + var stringNames = {}; + var objectNames = []; + for (var name in String.prototype) + stringNames[name] = name; + + for (var name in Object.prototype) + delete stringNames[name]; + + //stringNames['toString'] = 'toString'; //this was deleted with the rest of the object names + for (var name in stringNames) { + results.push(name); + } + return results; + } + } + + function Export(str) { + return new S(str); + }; + + //attach exports to StringJSWrapper + Export.extendPrototype = extendPrototype; + Export.restorePrototype = restorePrototype; + Export.VERSION = VERSION; + Export.TMPL_OPEN = '{{'; + Export.TMPL_CLOSE = '}}'; + Export.ENTITIES = ENTITIES; + + + +/************************************* +/* Exports +/*************************************/ + + if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { + module.exports = Export; + + } else { + + if(typeof define === "function" && define.amd) { + define([], function() { + return Export; + }); + } else { + window.S = Export; + } + } + + +/************************************* +/* 3rd Party Private Functions +/*************************************/ + + //from sugar.js + function multiArgs(args, fn) { + var result = [], i; + for(i = 0; i < args.length; i++) { + result.push(args[i]); + if(fn) fn.call(args, args[i], i); + } + return result; + } + + //from underscore.string + var escapeChars = { + lt: '<', + gt: '>', + quot: '"', + apos: "'", + amp: '&' + }; + + function escapeRegExp (s) { + // most part from https://github.com/skulpt/skulpt/blob/ecaf75e69c2e539eff124b2ab45df0b01eaf2295/src/str.js#L242 + var c; + var i; + var ret = []; + var re = /^[A-Za-z0-9]+$/; + s = ensureString(s); + for (i = 0; i < s.length; ++i) { + c = s.charAt(i); + + if (re.test(c)) { + ret.push(c); + } + else { + if (c === "\\000") { + ret.push("\\000"); + } + else { + ret.push("\\" + c); + } + } + } + return ret.join(""); + } + + function ensureString(string) { + return string == null ? '' : '' + string; + } + + //from underscore.string + var reversedEscapeChars = {}; + for(var key in escapeChars){ reversedEscapeChars[escapeChars[key]] = key; } + + ENTITIES = { + "amp" : "&", + "gt" : ">", + "lt" : "<", + "quot" : "\"", + "apos" : "'", + "AElig" : 198, + "Aacute" : 193, + "Acirc" : 194, + "Agrave" : 192, + "Aring" : 197, + "Atilde" : 195, + "Auml" : 196, + "Ccedil" : 199, + "ETH" : 208, + "Eacute" : 201, + "Ecirc" : 202, + "Egrave" : 200, + "Euml" : 203, + "Iacute" : 205, + "Icirc" : 206, + "Igrave" : 204, + "Iuml" : 207, + "Ntilde" : 209, + "Oacute" : 211, + "Ocirc" : 212, + "Ograve" : 210, + "Oslash" : 216, + "Otilde" : 213, + "Ouml" : 214, + "THORN" : 222, + "Uacute" : 218, + "Ucirc" : 219, + "Ugrave" : 217, + "Uuml" : 220, + "Yacute" : 221, + "aacute" : 225, + "acirc" : 226, + "aelig" : 230, + "agrave" : 224, + "aring" : 229, + "atilde" : 227, + "auml" : 228, + "ccedil" : 231, + "eacute" : 233, + "ecirc" : 234, + "egrave" : 232, + "eth" : 240, + "euml" : 235, + "iacute" : 237, + "icirc" : 238, + "igrave" : 236, + "iuml" : 239, + "ntilde" : 241, + "oacute" : 243, + "ocirc" : 244, + "ograve" : 242, + "oslash" : 248, + "otilde" : 245, + "ouml" : 246, + "szlig" : 223, + "thorn" : 254, + "uacute" : 250, + "ucirc" : 251, + "ugrave" : 249, + "uuml" : 252, + "yacute" : 253, + "yuml" : 255, + "copy" : 169, + "reg" : 174, + "nbsp" : 160, + "iexcl" : 161, + "cent" : 162, + "pound" : 163, + "curren" : 164, + "yen" : 165, + "brvbar" : 166, + "sect" : 167, + "uml" : 168, + "ordf" : 170, + "laquo" : 171, + "not" : 172, + "shy" : 173, + "macr" : 175, + "deg" : 176, + "plusmn" : 177, + "sup1" : 185, + "sup2" : 178, + "sup3" : 179, + "acute" : 180, + "micro" : 181, + "para" : 182, + "middot" : 183, + "cedil" : 184, + "ordm" : 186, + "raquo" : 187, + "frac14" : 188, + "frac12" : 189, + "frac34" : 190, + "iquest" : 191, + "times" : 215, + "divide" : 247, + "OElig;" : 338, + "oelig;" : 339, + "Scaron;" : 352, + "scaron;" : 353, + "Yuml;" : 376, + "fnof;" : 402, + "circ;" : 710, + "tilde;" : 732, + "Alpha;" : 913, + "Beta;" : 914, + "Gamma;" : 915, + "Delta;" : 916, + "Epsilon;" : 917, + "Zeta;" : 918, + "Eta;" : 919, + "Theta;" : 920, + "Iota;" : 921, + "Kappa;" : 922, + "Lambda;" : 923, + "Mu;" : 924, + "Nu;" : 925, + "Xi;" : 926, + "Omicron;" : 927, + "Pi;" : 928, + "Rho;" : 929, + "Sigma;" : 931, + "Tau;" : 932, + "Upsilon;" : 933, + "Phi;" : 934, + "Chi;" : 935, + "Psi;" : 936, + "Omega;" : 937, + "alpha;" : 945, + "beta;" : 946, + "gamma;" : 947, + "delta;" : 948, + "epsilon;" : 949, + "zeta;" : 950, + "eta;" : 951, + "theta;" : 952, + "iota;" : 953, + "kappa;" : 954, + "lambda;" : 955, + "mu;" : 956, + "nu;" : 957, + "xi;" : 958, + "omicron;" : 959, + "pi;" : 960, + "rho;" : 961, + "sigmaf;" : 962, + "sigma;" : 963, + "tau;" : 964, + "upsilon;" : 965, + "phi;" : 966, + "chi;" : 967, + "psi;" : 968, + "omega;" : 969, + "thetasym;" : 977, + "upsih;" : 978, + "piv;" : 982, + "ensp;" : 8194, + "emsp;" : 8195, + "thinsp;" : 8201, + "zwnj;" : 8204, + "zwj;" : 8205, + "lrm;" : 8206, + "rlm;" : 8207, + "ndash;" : 8211, + "mdash;" : 8212, + "lsquo;" : 8216, + "rsquo;" : 8217, + "sbquo;" : 8218, + "ldquo;" : 8220, + "rdquo;" : 8221, + "bdquo;" : 8222, + "dagger;" : 8224, + "Dagger;" : 8225, + "bull;" : 8226, + "hellip;" : 8230, + "permil;" : 8240, + "prime;" : 8242, + "Prime;" : 8243, + "lsaquo;" : 8249, + "rsaquo;" : 8250, + "oline;" : 8254, + "frasl;" : 8260, + "euro;" : 8364, + "image;" : 8465, + "weierp;" : 8472, + "real;" : 8476, + "trade;" : 8482, + "alefsym;" : 8501, + "larr;" : 8592, + "uarr;" : 8593, + "rarr;" : 8594, + "darr;" : 8595, + "harr;" : 8596, + "crarr;" : 8629, + "lArr;" : 8656, + "uArr;" : 8657, + "rArr;" : 8658, + "dArr;" : 8659, + "hArr;" : 8660, + "forall;" : 8704, + "part;" : 8706, + "exist;" : 8707, + "empty;" : 8709, + "nabla;" : 8711, + "isin;" : 8712, + "notin;" : 8713, + "ni;" : 8715, + "prod;" : 8719, + "sum;" : 8721, + "minus;" : 8722, + "lowast;" : 8727, + "radic;" : 8730, + "prop;" : 8733, + "infin;" : 8734, + "ang;" : 8736, + "and;" : 8743, + "or;" : 8744, + "cap;" : 8745, + "cup;" : 8746, + "int;" : 8747, + "there4;" : 8756, + "sim;" : 8764, + "cong;" : 8773, + "asymp;" : 8776, + "ne;" : 8800, + "equiv;" : 8801, + "le;" : 8804, + "ge;" : 8805, + "sub;" : 8834, + "sup;" : 8835, + "nsub;" : 8836, + "sube;" : 8838, + "supe;" : 8839, + "oplus;" : 8853, + "otimes;" : 8855, + "perp;" : 8869, + "sdot;" : 8901, + "lceil;" : 8968, + "rceil;" : 8969, + "lfloor;" : 8970, + "rfloor;" : 8971, + "lang;" : 9001, + "rang;" : 9002, + "loz;" : 9674, + "spades;" : 9824, + "clubs;" : 9827, + "hearts;" : 9829, + "diams;" : 9830 + } + + +}).call(this); + +},{"./_count":14}],16:[function(require,module,exports){ +// Underscore.js 1.8.3 +// http://underscorejs.org +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `exports` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var + push = ArrayProto.push, + slice = ArrayProto.slice, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind, + nativeCreate = Object.create; + + // Naked function reference for surrogate-prototype-swapping. + var Ctor = function(){}; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.8.3'; + + // Internal function that returns an efficient (for current engines) version + // of the passed-in callback, to be repeatedly applied in other Underscore + // functions. + var optimizeCb = function(func, context, argCount) { + if (context === void 0) return func; + switch (argCount == null ? 3 : argCount) { + case 1: return function(value) { + return func.call(context, value); + }; + case 2: return function(value, other) { + return func.call(context, value, other); + }; + case 3: return function(value, index, collection) { + return func.call(context, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(context, accumulator, value, index, collection); + }; + } + return function() { + return func.apply(context, arguments); + }; + }; + + // A mostly-internal function to generate callbacks that can be applied + // to each element in a collection, returning the desired result — either + // identity, an arbitrary callback, a property matcher, or a property accessor. + var cb = function(value, context, argCount) { + if (value == null) return _.identity; + if (_.isFunction(value)) return optimizeCb(value, context, argCount); + if (_.isObject(value)) return _.matcher(value); + return _.property(value); + }; + _.iteratee = function(value, context) { + return cb(value, context, Infinity); + }; + + // An internal function for creating assigner functions. + var createAssigner = function(keysFunc, undefinedOnly) { + return function(obj) { + var length = arguments.length; + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; + } + } + return obj; + }; + }; + + // An internal function for creating a new object that inherits from another. + var baseCreate = function(prototype) { + if (!_.isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + }; + + var property = function(key) { + return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + }; + + // Helper for collection methods to determine whether a collection + // should be iterated as an array or as an object + // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + var getLength = property('length'); + var isArrayLike = function(collection) { + var length = getLength(collection); + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + }; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles raw objects in addition to array-likes. Treats all + // sparse array-likes as if they were dense. + _.each = _.forEach = function(obj, iteratee, context) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { + iteratee(obj[i], i, obj); + } + } else { + var keys = _.keys(obj); + for (i = 0, length = keys.length; i < length; i++) { + iteratee(obj[keys[i]], keys[i], obj); + } + } + return obj; + }; + + // Return the results of applying the iteratee to each element. + _.map = _.collect = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + results = Array(length); + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + results[index] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Create a reducing function iterating left or right. + function createReduce(dir) { + // Optimized iterator function as using arguments.length + // in the main function will deoptimize the, see #1991. + function iterator(obj, iteratee, memo, keys, index, length) { + for (; index >= 0 && index < length; index += dir) { + var currentKey = keys ? keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + } + + return function(obj, iteratee, memo, context) { + iteratee = optimizeCb(iteratee, context, 4); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + index = dir > 0 ? 0 : length - 1; + // Determine the initial value if none is provided. + if (arguments.length < 3) { + memo = obj[keys ? keys[index] : index]; + index += dir; + } + return iterator(obj, iteratee, memo, keys, index, length); + }; + } + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. + _.reduce = _.foldl = _.inject = createReduce(1); + + // The right-associative version of reduce, also known as `foldr`. + _.reduceRight = _.foldr = createReduce(-1); + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, predicate, context) { + var key; + if (isArrayLike(obj)) { + key = _.findIndex(obj, predicate, context); + } else { + key = _.findKey(obj, predicate, context); + } + if (key !== void 0 && key !== -1) return obj[key]; + }; + + // Return all the elements that pass a truth test. + // Aliased as `select`. + _.filter = _.select = function(obj, predicate, context) { + var results = []; + predicate = cb(predicate, context); + _.each(obj, function(value, index, list) { + if (predicate(value, index, list)) results.push(value); + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, predicate, context) { + return _.filter(obj, _.negate(cb(predicate)), context); + }; + + // Determine whether all of the elements match a truth test. + // Aliased as `all`. + _.every = _.all = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (!predicate(obj[currentKey], currentKey, obj)) return false; + } + return true; + }; + + // Determine if at least one element in the object matches a truth test. + // Aliased as `any`. + _.some = _.any = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (predicate(obj[currentKey], currentKey, obj)) return true; + } + return false; + }; + + // Determine if the array or object contains a given item (using `===`). + // Aliased as `includes` and `include`. + _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + if (typeof fromIndex != 'number' || guard) fromIndex = 0; + return _.indexOf(obj, item, fromIndex) >= 0; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + var func = isFunc ? method : value[method]; + return func == null ? func : func.apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, _.property(key)); + }; + + // Convenience version of a common use case of `filter`: selecting only objects + // containing specific `key:value` pairs. + _.where = function(obj, attrs) { + return _.filter(obj, _.matcher(attrs)); + }; + + // Convenience version of a common use case of `find`: getting the first object + // containing specific `key:value` pairs. + _.findWhere = function(obj, attrs) { + return _.find(obj, _.matcher(attrs)); + }; + + // Return the maximum element (or element-based computation). + _.max = function(obj, iteratee, context) { + var result = -Infinity, lastComputed = -Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value > result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed > lastComputed || computed === -Infinity && result === -Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iteratee, context) { + var result = Infinity, lastComputed = Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value < result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed < lastComputed || computed === Infinity && result === Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Shuffle a collection, using the modern version of the + // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + _.shuffle = function(obj) { + var set = isArrayLike(obj) ? obj : _.values(obj); + var length = set.length; + var shuffled = Array(length); + for (var index = 0, rand; index < length; index++) { + rand = _.random(0, index); + if (rand !== index) shuffled[index] = shuffled[rand]; + shuffled[rand] = set[index]; + } + return shuffled; + }; + + // Sample **n** random values from a collection. + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `map`. + _.sample = function(obj, n, guard) { + if (n == null || guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + return obj[_.random(obj.length - 1)]; + } + return _.shuffle(obj).slice(0, Math.max(0, n)); + }; + + // Sort the object's values by a criterion produced by an iteratee. + _.sortBy = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value: value, + index: index, + criteria: iteratee(value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + }; + + // An internal function used for aggregate "group by" operations. + var group = function(behavior) { + return function(obj, iteratee, context) { + var result = {}; + iteratee = cb(iteratee, context); + _.each(obj, function(value, index) { + var key = iteratee(value, index, obj); + behavior(result, value, key); + }); + return result; + }; + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = group(function(result, value, key) { + if (_.has(result, key)) result[key].push(value); else result[key] = [value]; + }); + + // Indexes the object's values by a criterion, similar to `groupBy`, but for + // when you know that your index values will be unique. + _.indexBy = group(function(result, value, key) { + result[key] = value; + }); + + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + _.countBy = group(function(result, value, key) { + if (_.has(result, key)) result[key]++; else result[key] = 1; + }); + + // Safely create a real, live array from anything iterable. + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (isArrayLike(obj)) return _.map(obj, _.identity); + return _.values(obj); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + if (obj == null) return 0; + return isArrayLike(obj) ? obj.length : _.keys(obj).length; + }; + + // Split a collection into two arrays: one whose elements all satisfy the given + // predicate, and one whose elements all do not satisfy the predicate. + _.partition = function(obj, predicate, context) { + predicate = cb(predicate, context); + var pass = [], fail = []; + _.each(obj, function(value, key, obj) { + (predicate(value, key, obj) ? pass : fail).push(value); + }); + return [pass, fail]; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head` and `take`. The **guard** check + // allows it to work with `_.map`. + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[0]; + return _.initial(array, array.length - n); + }; + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. + _.initial = function(array, n, guard) { + return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. + _.last = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[array.length - 1]; + return _.rest(array, Math.max(0, array.length - n)); + }; + + // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. + // Especially useful on the arguments object. Passing an **n** will return + // the rest N values in the array. + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, n == null || guard ? 1 : n); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, _.identity); + }; + + // Internal implementation of a recursive `flatten` function. + var flatten = function(input, shallow, strict, startIndex) { + var output = [], idx = 0; + for (var i = startIndex || 0, length = getLength(input); i < length; i++) { + var value = input[i]; + if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { + //flatten current level of array or arguments object + if (!shallow) value = flatten(value, shallow, strict); + var j = 0, len = value.length; + output.length += len; + while (j < len) { + output[idx++] = value[j++]; + } + } else if (!strict) { + output[idx++] = value; + } + } + return output; + }; + + // Flatten out an array, either recursively (by default), or just one level. + _.flatten = function(array, shallow) { + return flatten(array, shallow, false); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iteratee, context) { + if (!_.isBoolean(isSorted)) { + context = iteratee; + iteratee = isSorted; + isSorted = false; + } + if (iteratee != null) iteratee = cb(iteratee, context); + var result = []; + var seen = []; + for (var i = 0, length = getLength(array); i < length; i++) { + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; + if (isSorted) { + if (!i || seen !== computed) result.push(value); + seen = computed; + } else if (iteratee) { + if (!_.contains(seen, computed)) { + seen.push(computed); + result.push(value); + } + } else if (!_.contains(result, value)) { + result.push(value); + } + } + return result; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(flatten(arguments, true, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersection = function(array) { + var result = []; + var argsLength = arguments.length; + for (var i = 0, length = getLength(array); i < length; i++) { + var item = array[i]; + if (_.contains(result, item)) continue; + for (var j = 1; j < argsLength; j++) { + if (!_.contains(arguments[j], item)) break; + } + if (j === argsLength) result.push(item); + } + return result; + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = flatten(arguments, true, true, 1); + return _.filter(array, function(value){ + return !_.contains(rest, value); + }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + return _.unzip(arguments); + }; + + // Complement of _.zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices + _.unzip = function(array) { + var length = array && _.max(array, getLength).length || 0; + var result = Array(length); + + for (var index = 0; index < length; index++) { + result[index] = _.pluck(array, index); + } + return result; + }; + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. + _.object = function(list, values) { + var result = {}; + for (var i = 0, length = getLength(list); i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; + + // Generator function to create the findIndex and findLastIndex functions + function createPredicateIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; + } + + // Returns the first index on an array-like that passes a predicate test + _.findIndex = createPredicateIndexFinder(1); + _.findLastIndex = createPredicateIndexFinder(-1); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = getLength(array); + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; + } + return low; + }; + + // Generator function to create the indexOf and lastIndexOf functions + function createIndexFinder(dir, predicateFind, sortedIndex) { + return function(array, item, idx) { + var i = 0, length = getLength(array); + if (typeof idx == 'number') { + if (dir > 0) { + i = idx >= 0 ? idx : Math.max(idx + length, i); + } else { + length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; + } + } else if (sortedIndex && idx && length) { + idx = sortedIndex(array, item); + return array[idx] === item ? idx : -1; + } + if (item !== item) { + idx = predicateFind(slice.call(array, i, length), _.isNaN); + return idx >= 0 ? idx + i : -1; + } + for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { + if (array[idx] === item) return idx; + } + return -1; + }; + } + + // Return the position of the first occurrence of an item in an array, + // or -1 if the item is not included in the array. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); + _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (stop == null) { + stop = start || 0; + start = 0; + } + step = step || 1; + + var length = Math.max(Math.ceil((stop - start) / step), 0); + var range = Array(length); + + for (var idx = 0; idx < length; idx++, start += step) { + range[idx] = start; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Determines whether to execute a function as a constructor + // or a normal function with the provided arguments + var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (_.isObject(result)) return result; + return self; + }; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if + // available. + _.bind = function(func, context) { + if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); + var args = slice.call(arguments, 2); + var bound = function() { + return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); + }; + return bound; + }; + + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. _ acts + // as a placeholder, allowing any combination of arguments to be pre-filled. + _.partial = function(func) { + var boundArgs = slice.call(arguments, 1); + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; + } + while (position < arguments.length) args.push(arguments[position++]); + return executeBound(func, bound, this, this, args); + }; + return bound; + }; + + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + _.bindAll = function(obj) { + var i, length = arguments.length, key; + if (length <= 1) throw new Error('bindAll must be passed function names'); + for (i = 1; i < length; i++) { + key = arguments[i]; + obj[key] = _.bind(obj[key], obj); + } + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memoize = function(key) { + var cache = memoize.cache; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); + if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); + return cache[address]; + }; + memoize.cache = {}; + return memoize; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ + return func.apply(null, args); + }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = _.partial(_.delay, _, 1); + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _.throttle = function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + if (!options) options = {}; + var later = function() { + previous = options.leading === false ? 0 : _.now(); + timeout = null; + result = func.apply(context, args); + if (!timeout) context = args = null; + }; + return function() { + var now = _.now(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0 || remaining > wait) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + previous = now; + result = func.apply(context, args); + if (!timeout) context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { + var timeout, args, context, timestamp, result; + + var later = function() { + var last = _.now() - timestamp; + + if (last < wait && last >= 0) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + if (!timeout) context = args = null; + } + } + }; + + return function() { + context = this; + args = arguments; + timestamp = _.now(); + var callNow = immediate && !timeout; + if (!timeout) timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + + return result; + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return _.partial(wrapper, func); + }; + + // Returns a negated version of the passed-in predicate. + _.negate = function(predicate) { + return function() { + return !predicate.apply(this, arguments); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var args = arguments; + var start = args.length - 1; + return function() { + var i = start; + var result = args[start].apply(this, arguments); + while (i--) result = args[i].call(this, result); + return result; + }; + }; + + // Returns a function that will only be executed on and after the Nth call. + _.after = function(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; + + // Returns a function that will only be executed up to (but not including) the Nth call. + _.before = function(times, func) { + var memo; + return function() { + if (--times > 0) { + memo = func.apply(this, arguments); + } + if (times <= 1) func = null; + return memo; + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = _.partial(_.before, 2); + + // Object Functions + // ---------------- + + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + function collectNonEnumProps(obj, keys) { + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { + keys.push(prop); + } + } + } + + // Retrieve the names of an object's own properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve all the property names of an object. + _.allKeys = function(obj) { + if (!_.isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; + }; + + // Returns the results of applying the iteratee to each element of the object + // In contrast to _.map it returns an object + _.mapObject = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = _.keys(obj), + length = keys.length, + results = {}, + currentKey; + for (var index = 0; index < length; index++) { + currentKey = keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Convert an object into a list of `[key, value]` pairs. + _.pairs = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var pairs = Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [keys[i], obj[keys[i]]]; + } + return pairs; + }; + + // Invert the keys and values of an object. The values must be serializable. + _.invert = function(obj) { + var result = {}; + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + result[obj[keys[i]]] = keys[i]; + } + return result; + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = createAssigner(_.allKeys); + + // Assigns a given object with all the own properties in the passed-in object(s) + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + _.extendOwn = _.assign = createAssigner(_.keys); + + // Returns the first key on an object that passes a predicate test + _.findKey = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = _.keys(obj), key; + for (var i = 0, length = keys.length; i < length; i++) { + key = keys[i]; + if (predicate(obj[key], key, obj)) return key; + } + }; + + // Return a copy of the object only containing the whitelisted properties. + _.pick = function(object, oiteratee, context) { + var result = {}, obj = object, iteratee, keys; + if (obj == null) return result; + if (_.isFunction(oiteratee)) { + keys = _.allKeys(obj); + iteratee = optimizeCb(oiteratee, context); + } else { + keys = flatten(arguments, false, false, 1); + iteratee = function(value, key, obj) { return key in obj; }; + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; + } + return result; + }; + + // Return a copy of the object without the blacklisted properties. + _.omit = function(obj, iteratee, context) { + if (_.isFunction(iteratee)) { + iteratee = _.negate(iteratee); + } else { + var keys = _.map(flatten(arguments, false, false, 1), String); + iteratee = function(value, key) { + return !_.contains(keys, key); + }; + } + return _.pick(obj, iteratee, context); + }; + + // Fill in a given object with default properties. + _.defaults = createAssigner(_.allKeys, true); + + // Creates an object that inherits from the given prototype object. + // If additional properties are provided then they will be added to the + // created object. + _.create = function(prototype, props) { + var result = baseCreate(prototype); + if (props) _.extendOwn(result, props); + return result; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Returns whether an object has a given set of `key:value` pairs. + _.isMatch = function(object, attrs) { + var keys = _.keys(attrs), length = keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; + } + return true; + }; + + + // Internal recursive comparison function for `isEqual`. + var eq = function(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + switch (className) { + // Strings, numbers, regular expressions, dates, and booleans are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + } + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && + _.isFunction(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + } + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } + + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var keys = _.keys(a), key; + length = keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (_.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (obj == null) return true; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) === '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. + _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) === '[object ' + name + ']'; + }; + }); + + // Define a fallback version of the method in browsers (ahem, IE < 9), where + // there isn't any inspectable "Arguments" type. + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return _.has(obj, 'callee'); + }; + } + + // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, + // IE 11 (#1621), and in Safari 8 (#1929). + if (typeof /./ != 'function' && typeof Int8Array != 'object') { + _.isFunction = function(obj) { + return typeof obj == 'function' || false; + }; + } + + // Is a given object a finite number? + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; + + // Is the given value `NaN`? (NaN is the only number which does not equal itself). + _.isNaN = function(obj) { + return _.isNumber(obj) && obj !== +obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Shortcut function for checking if an object has a given property directly + // on itself (in other words, not on a prototype). + _.has = function(obj, key) { + return obj != null && hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iteratees. + _.identity = function(value) { + return value; + }; + + // Predicate-generating functions. Often useful outside of Underscore. + _.constant = function(value) { + return function() { + return value; + }; + }; + + _.noop = function(){}; + + _.property = property; + + // Generates a function for a given object that returns a given property. + _.propertyOf = function(obj) { + return obj == null ? function(){} : function(key) { + return obj[key]; + }; + }; + + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + _.matcher = _.matches = function(attrs) { + attrs = _.extendOwn({}, attrs); + return function(obj) { + return _.isMatch(obj, attrs); + }; + }; + + // Run a function **n** times. + _.times = function(n, iteratee, context) { + var accum = Array(Math.max(0, n)); + iteratee = optimizeCb(iteratee, context, 1); + for (var i = 0; i < n; i++) accum[i] = iteratee(i); + return accum; + }; + + // Return a random integer between min and max (inclusive). + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; + + // A (possibly faster) way to get the current timestamp as an integer. + _.now = Date.now || function() { + return new Date().getTime(); + }; + + // List of HTML entities for escaping. + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + var unescapeMap = _.invert(escapeMap); + + // Functions for escaping and unescaping strings to/from HTML interpolation. + var createEscaper = function(map) { + var escaper = function(match) { + return map[match]; + }; + // Regexes for identifying a key that needs to be escaped + var source = '(?:' + _.keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function(string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; + }; + _.escape = createEscaper(escapeMap); + _.unescape = createEscaper(unescapeMap); + + // If the value of the named `property` is a function then invoke it with the + // `object` as context; otherwise, return it. + _.result = function(object, property, fallback) { + var value = object == null ? void 0 : object[property]; + if (value === void 0) { + value = fallback; + } + return _.isFunction(value) ? value.call(object) : value; + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escaper = /\\|'|\r|\n|\u2028|\u2029/g; + + var escapeChar = function(match) { + return '\\' + escapes[match]; + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + // NB: `oldSettings` only exists for backwards compatibility. + _.template = function(text, settings, oldSettings) { + if (!settings && oldSettings) settings = oldSettings; + settings = _.defaults({}, settings, _.templateSettings); + + // Combine delimiters into one regular expression via alternation. + var matcher = RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset).replace(escaper, escapeChar); + index = offset + match.length; + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } else if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } else if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + + // Adobe VMs need the match returned to produce the correct offest. + return match; + }); + source += "';\n"; + + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + 'return __p;\n'; + + try { + var render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + var template = function(data) { + return render.call(this, data, _); + }; + + // Provide the compiled source as a convenience for precompilation. + var argument = settings.variable || 'obj'; + template.source = 'function(' + argument + '){\n' + source + '}'; + + return template; + }; + + // Add a "chain" function. Start chaining a wrapped Underscore object. + _.chain = function(obj) { + var instance = _(obj); + instance._chain = true; + return instance; + }; + + // OOP + // --------------- + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + + // Helper function to continue chaining intermediate results. + var result = function(instance, obj) { + return instance._chain ? _(obj).chain() : obj; + }; + + // Add your own custom functions to the Underscore object. + _.mixin = function(obj) { + _.each(_.functions(obj), function(name) { + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result(this, func.apply(_, args)); + }; + }); + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; + return result(this, obj); + }; + }); + + // Add all accessor Array functions to the wrapper. + _.each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result(this, method.apply(this._wrapped, arguments)); + }; + }); + + // Extracts the result from a wrapped and chained object. + _.prototype.value = function() { + return this._wrapped; + }; + + // Provide unwrapping proxy for some methods used in engine operations + // such as arithmetic and JSON stringification. + _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; + + _.prototype.toString = function() { + return '' + this._wrapped; + }; + + // AMD registration happens at the end for compatibility with AMD loaders + // that may not enforce next-turn semantics on modules. Even though general + // practice for AMD registration is to be anonymous, underscore registers + // as a named module because, like jQuery, it is a base library that is + // popular enough to be bundled in a third party lib, but not be part of + // an AMD load request. Those cases could generate an error when an + // anonymous define() is called outside of a loader request. + if (typeof define === 'function' && define.amd) { + define('underscore', [], function() { + return _; + }); + } +}.call(this)); + +},{}],"/home/raskolnikov/dev/mixco/script/maudio_xponent.mixco":[function(require,module,exports){ +var assert, b, c, mixco, v; + +mixco = require('mixco'); + +assert = mixco.util.assert; + +c = mixco.control; + +b = mixco.behaviour; + +v = mixco.value; + +mixco.script.register(module, { + info: { + name: '[mixco] M-Audio Xponent', + author: 'Juan Pedro Bolivar Puente ', + wiki: 'https://sinusoid.es/mixco/script/maudio_xponent.mixco.html', + forums: 'https://github.com/arximboldi/mixco/issues', + description: "Controller mapping for the M-Audio Xponent DJ controller." + }, + constructor: function() { + var ccId, g; + ccId = function(cc) { + return c.ccIds(cc, 2); + }; + g = "[Master]"; + c.input(ccId(0x0D)).does(g, "headMix"); + c.input(ccId(0x07)).does(g, "crossfader"); + c.input(0x0c, 0x00).does(b.soft("[EffectRack1_EffectUnit1]", "super1")); + c.input(0x0d, 0x00).does(b.soft("[EffectRack1_EffectUnit1]", "mix")); + c.input(0x0c, 0x01).does(b.soft("[EffectRack1_EffectUnit2]", "super1")); + c.input(0x0d, 0x01).does(b.soft("[EffectRack1_EffectUnit2]", "mix")); + c.control(0x09, 0x02).does("[EffectRack1_EffectUnit1_Effect1]", "parameter1"); + c.control(0x08, 0x02).does("[EffectRack1_EffectUnit1_Effect1]", "parameter2"); + c.input(c.noteOnIds(0x00, 0x02)).does("[EffectRack1_EffectUnit1]", "group_[Channel1]_enable"); + c.input(c.noteOnIds(0x01, 0x02)).does("[EffectRack1_EffectUnit1]", "group_[Channel2]_enable"); + this.decks = b.chooser(); + this.addDeck(0); + return this.addDeck(1); + }, + addDeck: function(i) { + var beatloop, ccId, g, idx, j, noteId, noteOnId, scratchMode, selectTrackKnobTransform, shift; + assert(i === 0 || i === 1); + g = "[Channel" + (i + 1) + "]"; + ccId = function(cc) { + return c.ccIds(cc, i); + }; + noteId = function(note) { + return c.noteIds(note, i); + }; + noteOnId = function(note) { + return c.noteOnIds(note, i); + }; + shift = b.modifier(); + c.control(noteId(0x2C)).does(shift); + c.control(noteOnId(0x14)).does(this.decks.add(g, "pfl")); + c.control(noteId(0x08)).does(g, "filterLowKill"); + c.control(noteId(0x09)).does(g, "filterMidKill"); + c.control(noteId(0x0A)).does(g, "filterHighKill"); + c.control(noteId(0x0B)).does(g, "pregain_toggle"); + c.input(ccId(0x08)).does(g, "filterLow"); + c.input(ccId(0x09)).does(g, "filterMid"); + c.input(ccId(0x0A)).does(g, "filterHigh"); + c.input(ccId(0x0B)).does(b.soft(g, "pregain")); + c.output(c.ccIds(0x12 + i, 3)).does(b.mapOut(g, "VuMeter").meter()); + c.control(noteId(0x02)).does(g, "sync_enabled"); + c.input(ccId(0x07)).does(b.soft(g, "volume")); + c.control(noteId(0x07)).does(b.punchIn(0.5 - i)); + c.output(c.ccIds(0x14 + i, 3)).does(b.playhead(g)); + c.control(noteId(0x21)).does(g, "back"); + c.control(noteId(0x22)).does(g, "fwd"); + for (idx = j = 0; j <= 4; idx = ++j) { + c.control(noteId(0x17 + idx)).when(shift, g, "hotcue_" + (idx + 1) + "_clear", g, "hotcue_" + (idx + 1) + "_enabled")["else"](g, "hotcue_" + (idx + 1) + "_activate", g, "hotcue_" + (idx + 1) + "_enabled"); + } + c.control(noteId(0x1C)).when(shift, g, "beatjump_1_backward")["else"](g, "beatjump_4_backward"); + c.control(noteId(0x1D)).when(shift, g, "beatjump_1_forward")["else"](g, "beatjump_4_forward"); + c.control(noteId(0x1E)).when(shift, "[Playlist]", "ToggleSelectedSidebarItem")["else"](g, "keylock"); + c.control(noteId(0x1F)).does(g, "beats_translate_curpos"); + c.control(noteId(0x20)).does(g, "reverse"); + c.control(noteId(0x23)).does(g, "cue_default", g, "cue_indicator"); + c.control(noteOnId(0x24)).does(g, "play"); + c.control(noteId(0x29)).when(shift, g, "loop_halve")["else"](g, "loop_in"); + c.control(noteId(0x2B)).when(shift, g, "loop_double")["else"](g, "loop_out"); + c.control(noteOnId(0x2A)).does(g, "reloop_exit", g, "loop_enabled"); + c.control(noteId(0x25)).when(shift, g, "beatloop_0.125_activate", g, "beatloop_0.125_enabled")["else"](g, "beatloop_4_activate", g, "beatloop_4_enabled"); + c.control(noteId(0x26)).when(shift, g, "beatloop_0.5_activate", g, "beatloop_0.5_enabled")["else"](g, "beatloop_8_activate", g, "beatloop_8_enabled"); + c.control(noteId(0x27)).when(shift, g, "beatloop_1_activate", g, "beatloop_1_enabled")["else"](g, "beatloop_16_activate", g, "beatloop_16_enabled"); + c.control(noteId(0x28)).when(shift, g, "beatloop_2_activate", g, "beatloop_2_enabled")["else"](g, "beatloop_32_activate", g, "beatloop_32_enabled"); + c.control(noteOnId(0x0c)).does("[EffectRack1_EffectUnit1]", "group_" + g + "_enable"); + c.control(noteOnId(0x0d)).does("[EffectRack1_EffectUnit2]", "group_" + g + "_enable"); + beatloop = b.beatEffect(g, 'roll'); + c.input(ccId(0x0e)).does(beatloop.selector()); + c.control(noteId(0x0e)).does(beatloop); + c.input(ccId(0x0f)).does("[QuickEffectRack1_" + g + "]", 'super1'); + c.control(noteId(0x0f)).does("[QuickEffectRack1_" + g + "]", 'enabled'); + scratchMode = b["switch"](); + c.control(noteOnId(0x15)).does(scratchMode); + selectTrackKnobTransform = (function() { + var toggle; + toggle = 1; + return function(ev) { + var val; + val = ev.value - 64; + toggle -= 1; + if (toggle < 0) { + toggle = 3; + } + if (toggle === 0) { + return val.sign(); + } else { + return null; + } + }; + })(); + c.control(noteId(0x16)).when(v.and(v.not(shift), scratchMode), b.scratchEnable(i + 1)); + c.input(ccId(0x16)).when(shift, b.map("[Playlist]", "SelectTrackKnob").transform(selectTrackKnobTransform))["else"].when(scratchMode, b.scratchTick(i + 1).options.spread64)["else"](b.map(g, "jog").transform(function(ev) { + return (ev.value - 64) / 8; + })); + c.control(noteId(0x10)).when(shift, g, "rate_temp_down_small")["else"](g, "rate_temp_down"); + c.control(noteId(0x11)).when(shift, g, "rate_temp_up_small")["else"](g, "rate_temp_up"); + c.input(c.pbIds(i)).does(b.soft(g, "rate")); + c.control(noteId(0x12)).when(shift, g, "eject")["else"](b.brake(i + 1)); + return c.control(noteId(0x13)).when(shift, g, "LoadSelectedTrack")["else"](b.spinback(i + 1)); + }, + preinit: function() { + var msg; + msg = [0xF0, 0x00, 0x20, 0x08, 0x00, 0x00, 0x63, 0x0E, 0x16, 0x40, 0x00, 0x01, 0xF7]; + return this.mixxx.midi.sendSysexMsg(msg, msg.length); + }, + init: function() { + return this.decks.activate(0); + }, + postshutdown: function() { + var msg; + msg = [0xF0, 0x00, 0x20, 0x08, 0x00, 0x00, 0x63, 0x0E, 0x16, 0x40, 0x00, 0x00, 0xF7]; + return this.mixxx.midi.sendSysexMsg(msg, msg.length); + } +}); + + +},{"mixco":2}],17:[function(require,module,exports){ +var _, assert, bind, copy, events, extend, factory, indent, isinstance, makeOptionsChooser, map, multi, option, ref, ref1, ref2, toOption, transform, value, + extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + slice = [].slice; + +events = require('events'); + +transform = require('./transform'); + +value = require('./value'); + +ref = require('./util'), indent = ref.indent, assert = ref.assert, factory = ref.factory, copy = ref.copy; + +ref1 = require('heterarchy'), multi = ref1.multi, isinstance = ref1.isinstance; + +_ = (ref2 = require('underscore'), extend = ref2.extend, bind = ref2.bind, map = ref2.map, ref2); + +exports.Actor = (function(superClass) { + extend1(Actor, superClass); + + function Actor() { + return Actor.__super__.constructor.apply(this, arguments); + } + + Actor.prototype.send = void 0; + + return Actor; + +})(events.EventEmitter); + +toOption = function(option) { + var result; + result = option; + if (isinstance(option, Function)) { + result = { + transform: option + }; + } + if ((result.transform != null) && (result.process == null)) { + result.process = result.transform.length === 1 ? function(ev, b) { + return ev.value = this.transform(ev.value); + } : function(ev, b) { + return ev.value = this.transform(ev.value, b.midiValue); + }; + } + return result; +}; + +option = exports.option = (function() { + var add, result, rot64; + result = {}; + add = function() { + var desc, i, mixxxName, name, names, option; + names = 2 <= arguments.length ? slice.call(arguments, 0, i = arguments.length - 1) : (i = 0, []), option = arguments[i++]; + mixxxName = names[0], name = names[1]; + desc = toOption(option); + desc.name = mixxxName; + result[name != null ? name : mixxxName] = desc; + return result; + }; + rot64 = function(sign) { + return function(v1, v0) { + var diff; + diff = v1 - (64..diff = diff === -1 || diff === 1 ? diff / 16.0 : diff - diff.sign()); + return (v0 + diff * sign).clamp(0, 127); + }; + }; + add('invert', function(v) { + return 127.0 - v; + }); + add('rot64', rot64(1)); + add('rot64inv', rot64(-1)); + add('rot64fast', function(v1, v0) { + return (v0 + (v1 - 64) * 1.5).clamp(0, 127); + }); + add('diff', function(v1, v0) { + return v0 + (v1 > 64 ? v1 - 128 : v1); + }); + add('button', function(v) { + return v !== 0; + }); + add('switch', function(v) { + return 1; + }); + result.switch_ = result["switch"]; + add('hercjog', function(v1, v0) { + return v0 + (v1 > 64 ? v1 - 128 : v1); + }); + add('spread64', function(v) { + return v - 64; + }); + add('selectknob', function(v) { + if (v > 64) { + return v - 128; + } else { + return v; + } + }); + return add('soft-takeover', 'softTakeover', { + enable: function(b) { + if (isinstance(b, exports.MapIn)) { + return b.script.mixxx.engine.softTakeover(b.group, b.key, true); + } + }, + disable: function(b) { + if (isinstance(b, exports.MapIn)) { + return b.script.mixxx.engine.softTakeover(b.group, b.key, false); + } + } + }); +})(); + +exports.makeOptionsChooser = makeOptionsChooser = function(obj) { + var key, opt, result; + result = {}; + for (key in option) { + opt = option[key]; + Object.defineProperty(result, key, { + get: (function(opt) { + return function() { + return obj.option(opt); + }; + })(opt) + }); + } + return result; +}; + +exports.Behaviour = (function(superClass) { + extend1(Behaviour, superClass); + + function Behaviour() { + return Behaviour.__super__.constructor.apply(this, arguments); + } + + Behaviour.prototype.enable = function(script, actor) { + var i, len, opt, ref3, results; + assert(this.actor == null); + assert(this.script == null); + this.script = script; + this.actor = actor; + this._eventListener = (function(_this) { + return function(ev) { + var i, len, opt, ref3; + if (_this._options != null) { + ev = copy(ev); + ref3 = _this._options; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (typeof opt.process === "function") { + opt.process(ev, _this); + } + } + } + return _this.onMidiEvent(ev); + }; + })(this); + actor.on('event', this._eventListener); + if (this._options != null) { + ref3 = this._options; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + results.push(typeof opt.enable === "function" ? opt.enable(this) : void 0); + } + return results; + } + }; + + Behaviour.prototype.disable = function(script, actor) { + var i, len, opt, ref3; + assert(this.script === script); + assert(this.actor === actor); + if (this._options != null) { + ref3 = this._options; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (typeof opt.disable === "function") { + opt.disable(this); + } + } + } + actor.removeListener('event', this._eventListener); + delete this.script; + return delete this.actor; + }; + + Behaviour.prototype.option = function() { + var i, len, opt, options, ref3; + options = 1 <= arguments.length ? slice.call(arguments, 0) : []; + for (i = 0, len = options.length; i < len; i++) { + opt = options[i]; + assert(opt); + } + (ref3 = (this._options != null ? this._options : this._options = [])).push.apply(ref3, map(options, toOption)); + return this; + }; + + Behaviour.property('options', function() { + return makeOptionsChooser(this); + }); + + Behaviour.prototype.directInMapping = function() { + return null; + }; + + Behaviour.prototype.directOutMapping = function() { + return null; + }; + + Behaviour.prototype.onMidiEvent = function(ev) { + return null; + }; + + Behaviour.prototype.getMidiValue = function() { + return this.value; + }; + + Behaviour.property('midiValue', function() { + return this.getMidiValue(); + }); + + return Behaviour; + +})(value.Value); + +exports.Call = (function(superClass) { + extend1(Call, superClass); + + function Call(onMidiEvent) { + this.onMidiEvent = onMidiEvent; + Call.__super__.constructor.call(this); + } + + return Call; + +})(exports.Behaviour); + +exports.call = factory(exports.Call); + +exports.Output = (function(superClass) { + extend1(Output, superClass); + + Output.prototype.minimum = 1; + + Output.prototype.maximum = void 0; + + function Output() { + Output.__super__.constructor.apply(this, arguments); + this.output = value.value(); + } + + Output.prototype.enable = function() { + Output.__super__.enable.apply(this, arguments); + if (this.actor.send != null) { + if (this._updateOutputCallback == null) { + this._updateOutputCallback = (function(_this) { + return function() { + return _this.updateOutput(); + }; + })(this); + } + this.output.on('value', this._updateOutputCallback); + } + if (this.actor.doSend != null) { + return this.updateOutput(this.actor.doSend); + } + }; + + Output.prototype.disable = function() { + if (this._updateOutputCallback != null) { + this.removeListener('value', this._updateOutputCallback); + this._updateOutputCallback = void 0; + } + return Output.__super__.disable.apply(this, arguments); + }; + + Output.prototype.updateOutput = function(sendfn) { + if (sendfn == null) { + sendfn = null; + } + if (sendfn == null) { + sendfn = this.actor.send; + } + return sendfn.call(this.actor, (Math.abs(this.output.value) >= this.minimum ? 'on' : 'off')); + }; + + return Output; + +})(exports.Behaviour); + +exports.Transform = (function(superClass) { + extend1(Transform, superClass); + + function Transform(transformer1, initial) { + this.transformer = transformer1; + if (initial == null) { + initial = void 0; + } + Transform.__super__.constructor.call(this, { + initial: initial + }); + } + + Transform.prototype.onMidiEvent = function(ev) { + var result; + result = this.transformer(ev, this.midiValue); + if (result != null) { + return this.output.value = this.value = result; + } + }; + + Transform.prototype.getMidiValue = function() { + var base, ref3; + return (ref3 = typeof (base = this.transformer).inverse === "function" ? base.inverse(this.value) : void 0) != null ? ref3 : this.value; + }; + + return Transform; + +})(exports.Output); + +exports.transform = factory(exports.Transform); + +exports.modifier = function() { + return exports.transform(transform.momentaryT, false); +}; + +exports["switch"] = function() { + return exports.transform(transform.binaryT, false); +}; + +exports.switch_ = exports["switch"]; + +exports.MapIn = (function(superClass) { + extend1(MapIn, superClass); + + function MapIn(ingroupOrParams, inkey) { + var ref3; + if (inkey == null) { + inkey = void 0; + } + MapIn.__super__.constructor.apply(this, arguments); + ref3 = !isinstance(ingroupOrParams, String) ? ingroupOrParams : { + group: ingroupOrParams, + key: inkey + }, this.group = ref3.group, this.key = ref3.key; + this._transform = transform.mappings[this.key]; + } + + MapIn.prototype.transform = function(trans) { + this._transform = trans; + return this; + }; + + MapIn.prototype.enable = function(script, actor) { + var engine; + MapIn.__super__.enable.apply(this, arguments); + engine = script.mixxx.engine; + this.value = engine.getValue(this.group, this.key); + if (this.listeners('value').length > 0) { + if (this._inHandler == null) { + this._inHandler = script.registerHandler((function(_this) { + return function(v) { + return _this.value = v; + }; + })(this)); + } + engine.connectControl(this.group, this.key, this._inHandler); + return this._inHandlerConnected = true; + } + }; + + MapIn.prototype.disable = function() { + if (this._inHandlerConnected != null) { + this.script.mixxx.engine.connectControl(this.group, this.key, this._inHandler, true); + this._inHandlerConnected = false; + } + return MapIn.__super__.disable.apply(this, arguments); + }; + + MapIn.prototype.directInMapping = function() { + if (this._transform === transform.mappings[this.key]) { + return { + group: this.group, + key: this.key + }; + } + }; + + MapIn.prototype.onMidiEvent = function(ev) { + var val; + val = this._transform(ev, this.midiValue); + if (val != null) { + this.script.mixxx.engine.setValue(this.group, this.key, val); + if (this.listeners('value').length === 0) { + return this.value = val; + } + } + }; + + MapIn.prototype.getMidiValue = function() { + var ref3, ref4; + return (ref3 = (ref4 = this._transform) != null ? typeof ref4.inverse === "function" ? ref4.inverse(this.value) : void 0 : void 0) != null ? ref3 : this.value; + }; + + return MapIn; + +})(exports.Behaviour); + +exports.mapIn = factory(exports.MapIn); + +exports.MapOut = (function(superClass) { + extend1(MapOut, superClass); + + function MapOut(outgroupOrParams, outkey) { + var ref3; + if (outkey == null) { + outkey = void 0; + } + MapOut.__super__.constructor.apply(this, arguments); + ref3 = !isinstance(outgroupOrParams, String) ? outgroupOrParams : { + outgroup: outgroupOrParams, + outkey: outkey + }, this.outgroup = ref3.outgroup, this.outkey = ref3.outkey; + } + + MapOut.prototype.meter = function(transformer) { + if (transformer == null) { + transformer = void 0; + } + this._outTransform = transformer; + if (this._outTransform == null) { + this._outTransform = transform.mappings[this.outkey].inverse; + } + this.updateOutput = function() { + return this.actor.send(Math.floor(this._outTransform(this.output.value))); + }; + return this; + }; + + MapOut.prototype.enable = function(script, actor) { + var engine; + MapOut.__super__.enable.apply(this, arguments); + engine = script.mixxx.engine; + this.output.value = engine.getValue(this.outgroup, this.outkey); + if (this.output.listeners('value').length > 0) { + if (this._outHandler == null) { + this._outHandler = script.registerHandler((function(_this) { + return function(v) { + return _this.output.value = v; + }; + })(this)); + } + engine.connectControl(this.outgroup, this.outkey, this._outHandler); + return this._outHandlerConnected = true; + } + }; + + MapOut.prototype.disable = function() { + if (this._outHandlerConnected != null) { + this.script.mixxx.engine.connectControl(this.outgroup, this.outkey, this._outHandler, true); + this._outHandlerConnected = false; + } + return MapOut.__super__.disable.apply(this, arguments); + }; + + MapOut.prototype.directOutMapping = function() { + if (this._outTransform == null) { + return { + group: this.outgroup, + key: this.outkey, + minimum: this.minimum + }; + } + }; + + return MapOut; + +})(exports.Output); + +exports.mapOut = factory(exports.MapOut); + +exports.Map = (function(superClass) { + extend1(Map, superClass); + + function Map(groupOrParams, key, outgroup, outkey) { + var params; + params = !isinstance(groupOrParams, String) ? groupOrParams : { + group: groupOrParams, + key: key, + outgroup: outgroup, + outkey: outkey + }; + if (params.outgroup == null) { + params.outgroup = params.group; + } + if (params.outkey == null) { + params.outkey = params.key; + } + Map.__super__.constructor.call(this, params); + } + + return Map; + +})(multi(exports.MapIn, exports.MapOut)); + +exports.map = factory(exports.Map); + +exports.toBehaviour = function() { + var args, behaviour; + behaviour = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + if (args.length > 0) { + return exports.map.apply(exports, [behaviour].concat(slice.call(args))); + } else { + return behaviour; + } +}; + +exports.soft = function() { + return exports.map.apply(exports, arguments).option(option.softTakeover); +}; + +exports.toggle = function() { + var args, offValue, onValue; + offValue = arguments[0], onValue = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; + return exports.map.apply(exports, args).transform(function(ev) { + if (ev.pressed) { + return onValue; + } else { + return offValue; + } + }); +}; + +exports.set = function() { + var args, valueToSet; + valueToSet = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.toggle.apply(exports, [valueToSet, null].concat(slice.call(args))); +}; + +exports.Chooser = (function(superClass) { + extend1(Chooser, superClass); + + function Chooser(arg) { + var ref3; + ref3 = arg != null ? arg : {}, this.autoExclusive = ref3.autoExclusive, this.onDisable = ref3.onDisable; + Chooser.__super__.constructor.apply(this, arguments); + this._selectedIndex = null; + this._chooseOptions = []; + this._chooseActivators = []; + this._chooseSelectors = []; + this._chooseHandles = []; + } + + Chooser.prototype.add = function(group, key, listen) { + var activator, idx; + if (listen == null) { + listen = null; + } + idx = this._chooseOptions.length; + activator = exports.map(group, key).transform((function(_this) { + return function(ev) { + if (ev.pressed) { + _this.activate(idx); + } + return null; + }; + })(this)); + this._chooseOptions.push([group, key, listen]); + this._chooseActivators.push(activator); + return activator; + }; + + Chooser.prototype.enable = function(script) { + var engine, group, i, key, len, listen, ref3, ref4; + Chooser.__super__.enable.apply(this, arguments); + if (this._updateValueHandler == null) { + this._updateValueHandler = script.registerHandler((function(_this) { + return function() { + return _this._updateValue(); + }; + })(this)); + } + engine = script.mixxx.engine; + ref3 = this._chooseOptions; + for (i = 0, len = ref3.length; i < len; i++) { + ref4 = ref3[i], group = ref4[0], key = ref4[1], listen = ref4[2]; + if (listen == null) { + listen = key; + } + engine.connectControl(group, listen, this._updateValueHandler); + } + return this._updateValue(); + }; + + Chooser.prototype.disable = function(script) { + var engine, group, i, key, len, listen, ref3, ref4; + assert(this._updateValueHandler); + engine = script.mixxx.engine; + ref3 = this._chooseOptions; + for (i = 0, len = ref3.length; i < len; i++) { + ref4 = ref3[i], group = ref4[0], key = ref4[1], listen = ref4[2]; + if (listen == null) { + listen = key; + } + engine.connectControl(group, listen, this._updateValueHandler, true); + } + return Chooser.__super__.disable.apply(this, arguments); + }; + + Chooser.prototype.activator = function(idx) { + assert((0 <= idx && idx < this._chooseOptions.length)); + return this._chooseActivators[idx]; + }; + + Chooser.prototype.selector = function() { + var select, selector; + select = (function(_this) { + return function(ev) { + var v; + v = (ev.value / 128.0 * _this._chooseOptions.length).clamp(0, _this._chooseOptions.length - 1); + _this._update({ + index: Math.floor(v) + }); + return v; + }; + })(this); + select.inverse = (function(_this) { + return function(v) { + return v / _this._chooseOptions.length * 128.0; + }; + })(this); + selector = extend(exports.transform(select), { + _updateValue: function(newv) { + if (Math.floor(newv) !== Math.floor(this.value)) { + return this.value = this.output.value = newv; + } + } + }); + this._chooseSelectors.push(selector); + return selector; + }; + + Chooser.prototype.momentary = function() { + return exports.action({ + press: (function(_this) { + return function() { + return _this._update({ + enable: true + }); + }; + })(this), + release: (function(_this) { + return function() { + return _this._update({ + enable: false + }); + }; + })(this) + }); + }; + + Chooser.prototype.activate = function(idx) { + this._update({ + index: idx, + enable: true + }); + return this; + }; + + Chooser.prototype.select = function(idx) { + if (this.actor != null) { + this._update({ + index: idx, + enable: true + }); + } else { + this._selectedIndex = idx; + } + return this; + }; + + Chooser.prototype.onMidiEvent = function(event) { + var enable; + if (event.pressed) { + enable = !this.value; + this._update({ + enable: enable + }); + if (!enable) { + return typeof this.onDisable === "function" ? this.onDisable() : void 0; + } + } + }; + + Chooser.prototype._update = function(arg) { + var enable, group, i, idx, index, key, len, listen, ref3, ref4, ref5, ref6, ref7, script; + ref3 = arg != null ? arg : {}, index = ref3.index, enable = ref3.enable; + if (enable == null) { + enable = this.value; + } + if (index == null) { + index = this._selectedIndex; + } + index = index != null ? index.clamp(0, this._chooseOptions.length - 1) : void 0; + if (index !== this._selectedIndex || enable !== this.value) { + script = (ref4 = this.script) != null ? ref4 : this._chooseActivators[index].script; + if (index != null) { + ref5 = this._chooseOptions[index], group = ref5[0], key = ref5[1], listen = ref5[2]; + script.mixxx.engine.setValue(group, key, enable); + } + if (!this.autoExclusive || !enable) { + ref6 = this._chooseOptions; + for (idx = i = 0, len = ref6.length; i < len; idx = ++i) { + ref7 = ref6[idx], group = ref7[0], key = ref7[1]; + if (idx !== index) { + script.mixxx.engine.setValue(group, key, false); + } + } + } + return this._selectedIndex = index; + } + }; + + Chooser.prototype._updateValue = function() { + var engine, i, len, ref3, selector; + if (this.script != null) { + engine = this.script.mixxx.engine; + this.value = this.output.value = _.some(this._chooseOptions, function(arg) { + var group, key, listen; + group = arg[0], key = arg[1], listen = arg[2]; + if (listen == null) { + listen = key; + } + return engine.getValue(group, listen); + }); + ref3 = this._chooseSelectors; + for (i = 0, len = ref3.length; i < len; i++) { + selector = ref3[i]; + selector._updateValue(this._selectedIndex); + } + } + return this; + }; + + return Chooser; + +})(exports.Output); + +exports.chooser = factory(exports.Chooser); + +exports.When = (function(superClass) { + extend1(When, superClass); + + function When() { + var _condition, base, wrapped; + _condition = arguments[0], wrapped = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this._condition = _condition; + this["else"] = (function(_this) { + return function() { + return _this._else.apply(_this, arguments); + }; + })(this); + this["else"].when = (function(_this) { + return function() { + return _this._elseWhen.apply(_this, arguments); + }; + })(this); + this.when = this["else"].when; + this.else_ = this["else"]; + When.__super__.constructor.call(this); + this._wrapped = exports.toBehaviour.apply(exports, wrapped); + this._condition.on('value', (function(_this) { + return function() { + return _this._update(); + }; + })(this)); + if (this._lastCondition !== 'no-more-negations') { + this._lastCondition = this._condition; + if ((base = this._lastCondition).negation == null) { + base.negation = value.not(this._condition); + } + } + } + + When.prototype.option = function() { + var ref3; + When.__super__.option.apply(this, arguments); + (ref3 = this._wrapped).option.apply(ref3, arguments); + return this; + }; + + When.prototype._elseWhen = function() { + var args, condition, nextCondition; + condition = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + assert(this._lastCondition != null, "Can not define more conditions after 'else'"); + nextCondition = value.and(condition, value.not(this._lastCondition)); + nextCondition.negation = value.and(this._lastCondition.negation, value.not(condition)); + this._lastCondition = nextCondition; + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(exports.When, [nextCondition].concat(slice.call(args)), function(){}); + }; + + When.prototype._else = function() { + var args, nextCondition; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastCondition != null, "Can not define more conditions after 'else'"); + nextCondition = this._lastCondition.negation; + nextCondition.negation = 'no-more-negations'; + delete this._lastCondition; + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(exports.When, [nextCondition].concat(slice.call(args)), function(){}); + }; + + When.prototype.enable = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + When.__super__.enable.apply(this, arguments); + this._enableOn = args; + this._enableRequested = true; + return this._update(); + }; + + When.prototype.disable = function() { + this._enableRequested = false; + this._update(); + return When.__super__.disable.apply(this, arguments); + }; + + When.prototype._update = function() { + var ref3, ref4; + this.value = this._enableRequested && this._condition.value; + if (this._wrapped.actor && !this.value) { + (ref3 = this._wrapped).disable.apply(ref3, this._enableOn); + } + if (!this._wrapped.actor && this.value) { + return (ref4 = this._wrapped).enable.apply(ref4, this._enableOn); + } + }; + + When.prototype.directOutMapping = function() { + return null; + }; + + When.prototype.directInMapping = function() { + return null; + }; + + return When; + +})(exports.Behaviour); + +exports.when = factory(exports.When); + +exports.Action = (function(superClass) { + extend1(Action, superClass); + + Action.prototype.minimum = true; + + function Action(action) { + this.action = action != null ? action : void 0; + Action.__super__.constructor.call(this); + if (this.onPress == null) { + this.onPress = this.action.press; + } + if (this.onRelease == null) { + this.onRelease = this.action.release; + } + } + + Action.prototype.onMidiEvent = function(ev) { + var val; + val = this.value = this.output.value = ev.pressed; + if (val) { + return typeof this.onPress === "function" ? this.onPress() : void 0; + } else { + return typeof this.onRelease === "function" ? this.onRelease() : void 0; + } + }; + + return Action; + +})(exports.Output); + +exports.action = factory(exports.Action); + +exports.punchIn = function(threshold, threshold2) { + var inThreshold, oldxfader; + if (threshold2 == null) { + threshold2 = void 0; + } + oldxfader = void 0; + inThreshold = function(newxfader, threshold) { + return (threshold < 0 && newxfader < threshold) || (threshold > 0 && newxfader > threshold); + }; + return exports.action({ + press: function() { + var engine, newxfader; + engine = this.script.mixxx.engine; + newxfader = engine.getValue("[Master]", "crossfader"); + if (inThreshold(newxfader, threshold) || ((threshold2 != null) && inThreshold(newxfader, threshold2))) { + oldxfader = newxfader; + return engine.setValue("[Master]", "crossfader", 0); + } + }, + release: function() { + var engine; + engine = this.script.mixxx.engine; + if (oldxfader != null) { + engine.setValue("[Master]", "crossfader", oldxfader); + return oldxfader = void 0; + } + } + }); +}; + +exports.scratchEnable = function(deck, intervalsPerRev, rpm, alpha, beta, ramp) { + if (intervalsPerRev == null) { + intervalsPerRev = 128 * 4; + } + if (rpm == null) { + rpm = 44.0; + } + if (alpha == null) { + alpha = 1.0 / 8.0; + } + if (beta == null) { + beta = 1.0 / 8.0 / 32.0; + } + if (ramp == null) { + ramp = true; + } + return exports.action({ + press: function() { + var enable; + enable = this.script.mixxx.engine.scratchEnable; + return enable(deck, intervalsPerRev, rpm, alpha, beta, ramp); + }, + release: function() { + return this.script.mixxx.engine.scratchDisable(deck, ramp); + } + }); +}; + +exports.scratchTick = function(deck, transform) { + if (transform == null) { + transform = function(x) { + return x; + }; + } + return exports.call(function(ev) { + var engine; + engine = this.script.mixxx.engine; + return engine.scratchTick(deck, transform(ev.value)); + }); +}; + +exports.spinback = function() { + var args, deck; + deck = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.modifier().on('value', function() { + var ref3; + return (ref3 = this.script.mixxx.engine).spinback.apply(ref3, [deck, this.value].concat(slice.call(args))); + }); +}; + +exports.brake = function() { + var args, deck; + deck = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.modifier().on('value', function() { + var ref3; + return (ref3 = this.script.mixxx.engine).brake.apply(ref3, [deck, this.value].concat(slice.call(args))); + }); +}; + +exports.playhead = function(g) { + return exports.mapOut(g, "playposition").meter((function() { + var step; + step = 0; + return function(pos) { + var duration, engine; + engine = this.script.mixxx.engine; + duration = (function() { + switch (false) { + case !!engine.getValue(g, "play"): + return void 0; + case !(pos > .9): + return 5; + case !(pos > .8): + return 9; + case !(pos > .75): + return 13; + default: + return void 0; + } + })(); + if (duration != null) { + step = (step + 1) % duration; + if (step > duration / 2) { + return 0; + } else { + return pos * 127; + } + } else { + step = 0; + return pos * 127; + } + }; + })()); +}; + +exports.beatEffect = function(channel, type) { + var i, len, result, size, sizes; + if (type == null) { + type = ''; + } + sizes = ["0.0625", "0.125", "0.25", "0.5", "1", "2", "4", "8", "16", "32", "64"]; + result = exports.chooser({ + autoExclusive: true, + onDisable: function() { + var engine; + engine = this.script.mixxx.engine; + if (type !== 'roll' && engine.getValue(channel, "loop_enabled")) { + return engine.setValue(channel, "reloop_exit", true); + } + } + }); + for (i = 0, len = sizes.length; i < len; i++) { + size = sizes[i]; + result.add(channel, "beatloop" + type + "_" + size + "_activate", "beatloop_" + size + "_enabled"); + } + return result.select(4); +}; + +exports.stutter = function(group, beats) { + var tick; + if (beats == null) { + beats = 0.25; + } + tick = function() { + var engine, gain, newgain; + engine = this.script.mixxx.engine; + gain = engine.getValue(group, "pregain"); + newgain = gain > 0 ? (this._oldgain = gain, 0) : this._oldgain; + return engine.setValue(group, "pregain", newgain); + }; + return exports.action({ + press: function() { + var bpm, delta, engine; + engine = this.script.mixxx.engine; + bpm = engine.getValue(group, "bpm"); + delta = beats * 60000 / bpm; + if (this._timerHandle == null) { + this._timerHandle = this.script.registerHandler(bind(tick, this)); + } + return this._timerId != null ? this._timerId : this._timerId = engine.beginTimer(delta, this._timerHandle); + }, + release: function() { + var engine; + engine = this.script.mixxx.engine; + engine.stopTimer(this._timerId); + if (this._oldgain != null) { + engine.setValue(group, "pregain", this._oldgain); + } + delete this._timerId; + return delete this._oldgain; + } + }); +}; + + +},{"./transform":21,"./util":22,"./value":23,"events":10,"heterarchy":13,"underscore":16}],18:[function(require,module,exports){ +var assert, exports, konsole; + +assert = require('./util').assert; + +konsole = this; + +exports = konsole; + +if (konsole.log == null) { + konsole.log = function() { + return print("" + arguments); + }; +} + +if (konsole.info == null) { + konsole.info = konsole.log; +} + +if (konsole.warn == null) { + konsole.warn = konsole.log; +} + +if (konsole.error == null) { + konsole.error = konsole.log; +} + +if (konsole.time == null) { + konsole.time = function() { + return assert(False, "time not implemented in konsole"); + }; +} + +if (konsole.timeEnd == null) { + konsole.timeEnd = function() { + return assert(False, "time not implemented in konsole"); + }; +} + +if (konsole.trace == null) { + konsole.trace = function() { + var err; + err = new Error(); + err.name = "Trace"; + err.message = "" + arguments; + return konsole.error(err.stack); + }; +} + +if (konsole.dir == null) { + konsole.dir = function() { + return konsole.log(object + "\n"); + }; +} + +if (konsole.assert == null) { + konsole.assert = assert; +} + + +},{"./util":22}],19:[function(require,module,exports){ +var MIDI_CC, MIDI_NOTE_OFF, MIDI_NOTE_ON, MIDI_PITCHBEND, assert, behaviour, ccIds, event, extend, factory, hexStr, indent, joinLn, midiId, multi, noteIds, noteOnIds, pbIds, ref, ref1, some, xmlTag, + slice = [].slice, + extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + +multi = require('heterarchy').multi; + +ref = require('./util'), indent = ref.indent, hexStr = ref.hexStr, assert = ref.assert, factory = ref.factory, xmlTag = ref.xmlTag, joinLn = ref.joinLn; + +behaviour = require('./behaviour'); + +ref1 = require('underscore'), some = ref1.some, extend = ref1.extend; + +exports.MIDI_NOTE_ON = MIDI_NOTE_ON = 0x9; + +exports.MIDI_NOTE_OFF = MIDI_NOTE_OFF = 0x8; + +exports.MIDI_CC = MIDI_CC = 0xB; + +exports.MIDI_PITCHBEND = MIDI_PITCHBEND = 0xE; + +midiId = function(message, midino, channel) { + if (message == null) { + message = MIDI_CC; + } + if (midino == null) { + midino = 0; + } + if (channel == null) { + channel = 0; + } + return { + message: message, + midino: midino, + channel: channel, + status: function() { + return (this.message << 4) | this.channel; + }, + configMidi: function(depth) { + return (indent(depth)) + "" + (hexStr(this.status())) + "\n" + (indent(depth)) + "" + (hexStr(this.midino)) + ""; + } + }; +}; + +exports.midiId = midiId; + +pbIds = function() { + return [midiId.apply(null, [MIDI_PITCHBEND, 0].concat(slice.call(arguments)))]; +}; + +noteOnIds = function() { + return [midiId.apply(null, [MIDI_NOTE_ON].concat(slice.call(arguments)))]; +}; + +noteIds = function() { + return [midiId.apply(null, [MIDI_NOTE_ON].concat(slice.call(arguments))), midiId.apply(null, [MIDI_NOTE_OFF].concat(slice.call(arguments)))]; +}; + +ccIds = function() { + return [midiId.apply(null, [MIDI_CC].concat(slice.call(arguments)))]; +}; + +exports.pbIds = pbIds; + +exports.noteOnIds = noteOnIds; + +exports.noteIds = noteIds; + +exports.ccIds = ccIds; + +exports.event = event = function(channel, control, value, status, group) { + return { + channel: channel, + control: control, + value: (function() { + switch (status >> 4) { + case MIDI_PITCHBEND: + return (value * 128.0 + control) / 128.0; + default: + return value; + } + })(), + status: status, + group: group, + message: function() { + return this.status >> 4; + }, + pressed: status >> 4 !== MIDI_NOTE_OFF && value + }; +}; + +exports.Control = (function(superClass) { + extend1(Control, superClass); + + function Control() { + var args, ids; + ids = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this.ids = ids != null ? ids : [midiId()]; + this["else"] = (function(_this) { + return function() { + return _this._else.apply(_this, arguments); + }; + })(this); + this["else"].when = (function(_this) { + return function() { + return _this._elseWhen.apply(_this, arguments); + }; + })(this); + this.else_ = this["else"]; + Control.__super__.constructor.call(this); + if (!(this.ids instanceof Array)) { + this.ids = ccIds.apply(null, [this.ids].concat(slice.call(args))); + } + this._behaviours = []; + if (typeof this._controlRegistry === "function") { + this._controlRegistry(this); + } + } + + Control.prototype.does = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit); + this._behaviours.push(this.registerBehaviour(behaviour.toBehaviour.apply(behaviour, args))); + return this; + }; + + Control.prototype.when = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit); + this._lastWhen = behaviour.when.apply(behaviour, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + return this; + }; + + Control.prototype._elseWhen = function() { + var args, ref2; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastWhen != null, "'elseWhen' must be preceded by 'when' or 'elseWhen'"); + this._lastWhen = (ref2 = this._lastWhen["else"]).when.apply(ref2, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + return this; + }; + + Control.prototype._else = function() { + var args, ref2; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastWhen != null, "'else' must be preceded by 'when' or 'elseWhen'"); + this._lastWhen = (ref2 = this._lastWhen)["else"].apply(ref2, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + this._lastWhen = void 0; + return this; + }; + + Control.prototype.init = function(script) { + var b, i, len, ref2; + this.script = script; + assert(!this._isInit); + ref2 = this._behaviours; + for (i = 0, len = ref2.length; i < len; i++) { + b = ref2[i]; + b.enable(script, this); + } + return this._isInit = true; + }; + + Control.prototype.shutdown = function(script) { + var b, i, len, ref2; + assert(script === this.script); + assert(this._isInit); + ref2 = this._behaviours; + for (i = 0, len = ref2.length; i < len; i++) { + b = ref2[i]; + b.disable(script, this); + } + this._isInit = false; + return delete this.script; + }; + + Control.prototype.registerBehaviour = function(b) { + return b; + }; + + Control.prototype.configInputs = function(depth, script) {}; + + Control.prototype.configOutputs = function(depth, script) {}; + + Control.prototype.setRegistry = function(registry) { + assert((this._controlRegistry == null) || (registry == null)); + return this._controlRegistry = registry; + }; + + return Control; + +})(behaviour.Actor); + +exports.InControl = (function(superClass) { + extend1(InControl, superClass); + + function InControl() { + return InControl.__super__.constructor.apply(this, arguments); + } + + InControl.prototype.init = function(script) { + InControl.__super__.init.apply(this, arguments); + if (this.needsHandler()) { + return script.registerHandler(((function(_this) { + return function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return _this.emit('event', event.apply(null, args)); + }; + })(this)), this.handlerId()); + } + }; + + InControl.prototype.option = function() { + var beh, i, len, options, ref2, ref3; + options = 1 <= arguments.length ? slice.call(arguments, 0) : []; + (ref2 = (this._options != null ? this._options : this._options = [])).push.apply(ref2, options); + ref3 = this._behaviours; + for (i = 0, len = ref3.length; i < len; i++) { + beh = ref3[i]; + beh.option.apply(beh, options); + } + return this; + }; + + InControl.property('options', function() { + return behaviour.makeOptionsChooser(this); + }); + + InControl.prototype.registerBehaviour = function(beh) { + if (this._options != null) { + beh.option.apply(beh, this._options); + } + return beh; + }; + + InControl.prototype.needsHandler = function() { + return this._behaviours.length !== 1 || !this._behaviours[0].directInMapping() || some(this._behaviours[0]._options, function(opt) { + return !opt.name; + }); + }; + + InControl.prototype.handlerId = function() { + return "x" + (this.ids[0].status().toString(16)) + "_x" + (this.ids[0].midino.toString(16)); + }; + + InControl.prototype.configInputs = function(depth, script) { + var id, mapping; + if (this.needsHandler()) { + mapping = { + group: "[Master]", + key: script.handlerKey(this.handlerId()) + }; + } else { + mapping = this._behaviours[0].directInMapping(); + } + return joinLn((function() { + var i, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + results.push(this.configInMapping(depth, mapping, id)); + } + return results; + }).call(this)); + }; + + InControl.prototype.configInMapping = function(depth, mapping, id) { + return (indent(depth)) + "\n" + (indent(depth + 1)) + "" + mapping.group + "\n" + (indent(depth + 1)) + "" + mapping.key + "\n" + (id.configMidi(depth + 1)) + "\n" + (indent(depth + 1)) + "\n" + (this.configOptions(depth + 2)) + "\n" + (indent(depth + 1)) + "\n" + (indent(depth)) + ""; + }; + + InControl.prototype.configOptions = function(depth) { + var opt, ref2; + if (this.needsHandler()) { + return (indent(depth)) + ""; + } else if (((ref2 = this._behaviours[0]._options) != null ? ref2.length : void 0) > 0) { + return joinLn((function() { + var i, len, ref3, results; + ref3 = this._behaviours[0]._options; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (opt.name != null) { + results.push((indent(depth)) + "<" + opt.name + "/>"); + } else { + results.push(void 0); + } + } + return results; + }).call(this)); + } else { + return (indent(depth)) + ""; + } + }; + + return InControl; + +})(exports.Control); + +exports.OutControl = (function(superClass) { + extend1(OutControl, superClass); + + function OutControl() { + OutControl.__super__.constructor.apply(this, arguments); + this._states = { + on: 0x7f, + off: 0x00, + disable: 0x00 + }; + } + + OutControl.prototype.send = function(state) { + return this.doSend(state); + }; + + OutControl.prototype.states = function(states) { + extend(this._states, states); + return this; + }; + + OutControl.prototype.doSend = function(state) { + var i, id, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + if (id.message !== MIDI_NOTE_OFF) { + if (state in this._states) { + results.push(this.script.mixxx.midi.sendShortMsg(id.status(), id.midino, this._states[state])); + } else { + results.push(this.script.mixxx.midi.sendShortMsg(id.status(), id.midino, state)); + } + } else { + results.push(void 0); + } + } + return results; + }; + + OutControl.prototype.init = function() { + if (!this.needsSend()) { + this.send = void 0; + } + return OutControl.__super__.init.apply(this, arguments); + }; + + OutControl.prototype.shutdown = function() { + this.doSend('disable'); + return OutControl.__super__.shutdown.apply(this, arguments); + }; + + OutControl.prototype.needsSend = function() { + return this._behaviours.length !== 1 || !this._behaviours[0].directOutMapping(); + }; + + OutControl.prototype.configOutputs = function(depth, script) { + var id, mapping; + mapping = !this.needsSend() && this._behaviours[0].directOutMapping(); + if (mapping) { + return joinLn((function() { + var i, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + results.push(this.configOutMapping(depth, mapping, id)); + } + return results; + }).call(this)); + } + }; + + OutControl.prototype.configOutMapping = function(depth, mapping, id) { + var options; + if (id.message !== MIDI_NOTE_OFF) { + options = joinLn([xmlTag('minimum', mapping.minimum, depth + 1), xmlTag('maximum', mapping.maximum, depth + 1)]); + return (indent(depth)) + "\n" + (indent(depth + 1)) + "" + mapping.group + "\n" + (indent(depth + 1)) + "" + mapping.key + "\n" + (id.configMidi(depth + 1)) + "\n" + (indent(depth + 1)) + "" + (hexStr(this._states['on'])) + "\n" + (indent(depth + 1)) + "" + (hexStr(this._states['off'])) + "\n" + options + "\n" + (indent(depth)) + ""; + } + }; + + return OutControl; + +})(exports.Control); + +exports.input = factory(exports.InControl); + +exports.output = factory(exports.OutControl); + +exports.InOutControl = (function(superClass) { + extend1(InOutControl, superClass); + + function InOutControl() { + return InOutControl.__super__.constructor.apply(this, arguments); + } + + return InOutControl; + +})(multi(exports.InControl, exports.OutControl)); + +exports.control = factory(exports.InOutControl); + + +},{"./behaviour":17,"./util":22,"heterarchy":13,"underscore":16}],20:[function(require,module,exports){ +(function (process){ +var Control, S, _, assert, basename, bind, catching, flatten, indent, issubclass, mro, ref, ref1, ref2, xmlEscape, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, + slice = [].slice; + +ref = require('underscore'), flatten = ref.flatten, bind = ref.bind; + +ref1 = require('heterarchy'), issubclass = ref1.issubclass, mro = ref1.mro; + +Control = require('./control').Control; + +ref2 = require('./util'), indent = ref2.indent, xmlEscape = ref2.xmlEscape, catching = ref2.catching, assert = ref2.assert; + +require('./console'); + +basename = require('path').basename; + +S = require('string'); + +_ = require('underscore'); + +exports.nameFromFilename = function(fname) { + var extensions, name; + extensions = [".mixco.coffee", ".mixco.litcoffee", ".mixco.js", ".mixco"]; + fname = basename(fname); + assert(_.some(extensions, function(x) { + return S(fname).endsWith(x); + }), "Script file name: " + fname + " must end in one of: " + extensions); + name = extensions.reduce((function(fname, ext) { + return fname.replace(ext, ""); + }), fname); + assert(name.match(/^[a-zA-Z_$][0-9a-zA-Z_$].*$/, "Script name must be a valid JavaScript identifier")); + return name; +}; + +exports.register = function(targetModule, scriptTypeOrDefinition) { + var instance, name, scriptType; + name = targetModule.filename != null ? exports.nameFromFilename(targetModule.filename) : typeof MIXCO_SCRIPT_FILENAME !== "undefined" && MIXCO_SCRIPT_FILENAME !== null ? exports.nameFromFilename(MIXCO_SCRIPT_FILENAME) : assert(false, "Invalid script"); + scriptType = issubclass(scriptTypeOrDefinition, exports.Script) ? scriptTypeOrDefinition : exports.create(scriptTypeOrDefinition); + instance = new scriptType; + instance.__registeredName = name; + targetModule.exports[name] = instance; + if (targetModule === require.main) { + return instance.main(); + } +}; + +exports.create = function(scriptDefinition) { + var NewScript, constructor, init, k, shutdown, special, v; + assert(scriptDefinition.constructor != null, "Script definition must have a constructor"); + constructor = scriptDefinition.constructor, init = scriptDefinition.init, shutdown = scriptDefinition.shutdown; + NewScript = (function(superClass) { + extend(NewScript, superClass); + + function NewScript() { + NewScript.__super__.constructor.apply(this, arguments); + try { + Control.prototype.setRegistry(bind(this.add, this)); + constructor.apply(this, arguments); + } finally { + Control.prototype.setRegistry(null); + } + this; + } + + NewScript.prototype.init = function() { + var ref3; + if ((ref3 = this.preinit) != null) { + ref3.apply(this, arguments); + } + NewScript.__super__.init.apply(this, arguments); + return init != null ? init.apply(this, arguments) : void 0; + }; + + NewScript.prototype.shutdown = function() { + var ref3; + if (shutdown != null) { + shutdown.apply(this, arguments); + } + NewScript.__super__.shutdown.apply(this, arguments); + return (ref3 = this.postshutdown) != null ? ref3.apply(this, arguments) : void 0; + }; + + return NewScript; + + })(exports.Script); + special = ['name', 'constructor', 'init', 'shutdown']; + for (k in scriptDefinition) { + v = scriptDefinition[k]; + if (indexOf.call(special, k) < 0) { + NewScript.prototype[k] = v; + } + } + return NewScript; +}; + +exports.Script = (function() { + Script.prototype.info = { + name: "[mixco] Generic Script", + author: "Juan Pedro Bolivar Puente ", + description: "", + forums: "", + wiki: "" + }; + + Script.property('name', { + get: function() { + assert(this.__registeredName, "Script must be registered"); + return this.__registeredName; + } + }); + + Script.prototype.add = function() { + var controls, ref3; + controls = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit, "Can only add controls in constructor"); + return (ref3 = this.controls).push.apply(ref3, flatten(controls)); + }; + + Script.prototype.init = catching(function() { + var control, i, len, ref3, results; + this._isInit = true; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.init(this)); + } + return results; + }); + + Script.prototype.shutdown = catching(function() { + var control, i, len, ref3; + ref3 = this.controls; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + control.shutdown(this); + } + return delete this._isInit; + }); + + function Script() { + this.controls = []; + } + + Script.prototype.mixxx = { + engine: (typeof engine !== "undefined" && engine !== null ? engine : void 0), + midi: (typeof midi !== "undefined" && midi !== null ? midi : void 0), + script: (typeof script !== "undefined" && script !== null ? script : void 0) + }; + + Script.prototype.main = function() { + var arg, i, len, ref3, results; + ref3 = process.argv; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + arg = ref3[i]; + if (arg === '-h' || arg === '--help') { + console.info(this.help()); + break; + } + if (arg === '-g' || arg === '--generate-config') { + console.info(this.config()); + break; + } else { + results.push(void 0); + } + } + return results; + }; + + Script.prototype.help = function() { + return "Mixxx Controller Script\n=======================\n\nName: " + this.info.name + "\nAuthor: " + this.info.author + "\nDescription: " + this.info.description + "\nForums: " + this.info.description + "\n\nUsage\n-----\n1. Generate Mixxx config:\n coffee " + this.name + ".coffee -g > " + this.name + ".xml\n\n2. Generate Mixxx script:\n coffee -c " + this.name + ".coffee"; + }; + + Script.prototype.config = function() { + return "\n\n" + (indent(1)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.name)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.author)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.description)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.wiki)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.forums)) + "\n" + (indent(1)) + "\n" + (indent(1)) + "\n" + (indent(2)) + "\n" + (indent(3)) + "\n" + (indent(2)) + "\n" + (indent(2)) + "\n" + (this.configInputs(3)) + "\n" + (indent(2)) + "\n" + (indent(2)) + "\n" + (this.configOutputs(3)) + "\n" + (indent(2)) + "\n" + (indent(1)) + "\n"; + }; + + Script.prototype.configInputs = function(depth) { + var control; + return ((function() { + var i, len, ref3, results; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.configInputs(depth, this)); + } + return results; + }).call(this)).filter(function(x) { + return x; + }).join('\n'); + }; + + Script.prototype.configOutputs = function(depth) { + var control; + return ((function() { + var i, len, ref3, results; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.configOutputs(depth, this)); + } + return results; + }).call(this)).filter(function(x) { + return x; + }).join('\n'); + }; + + Script.prototype._nextCallbackId = 1; + + Script.prototype.registerHandler = function(callback, id) { + var handlerName; + if (id == null) { + id = void 0; + } + id || (id = this._nextCallbackId++); + handlerName = "__handle_" + id; + assert(!this[handlerName], "Handlers can be registered only once (" + handlerName + ")"); + this[handlerName] = callback; + return this.handlerKey(id); + }; + + Script.prototype.handlerKey = function(id) { + if (id == null) { + id = void 0; + } + if (id == null) { + id = this._nextCallbackId - 1; + } + return this.name + ".__handle_" + id; + }; + + return Script; + +})(); + + +}).call(this,require('_process')) +},{"./console":18,"./control":19,"./util":22,"_process":12,"heterarchy":13,"path":11,"string":15,"underscore":16}],21:[function(require,module,exports){ +var binaryT, centeredT, defaultT, identityT, linearT, momentaryT, + slice = [].slice; + +exports.identity = function(v) { + return v; +}; + +exports.identity.inverse = exports.identity; + +exports.momentary = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } +}; + +exports.momentary.inverse = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } +}; + +exports.binary = function(v, oldv) { + if (v > 0) { + return !oldv; + } else { + return null; + } +}; + +exports.binary.inverse = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } +}; + +exports.linear = function(v, min, max) { + return min + v * (max - min); +}; + +exports.linear.inverse = function(v, min, max) { + return (v - min) / (max - min); +}; + +exports.centered = function(v, min, center, max) { + if (v < .5) { + return linear(v * 2, min, center); + } else { + return linear((v - .5) * 2, center, max); + } +}; + +exports.centered.inverse = function(v, min, center, max) { + if (v < center) { + return 0.5 * linear.inverse(v, min, center); + } else { + return 0.5 + 0.5 * linear.inverse(v, center, max); + } +}; + +exports.transform = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.value / 127.0].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return 127 * f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; +}; + +exports.transformI = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.value].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; +}; + +exports.transformB = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.pressed / 127.0].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return 127 * f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; +}; + +exports.identityT = identityT = exports.transformI(exports.identity); + +exports.momentaryT = momentaryT = exports.transformB(exports.momentary); + +exports.binaryT = binaryT = exports.transformB(exports.binary); + +exports.linearT = linearT = function() { + return exports.transform.apply(exports, [exports.linear].concat(slice.call(arguments))); +}; + +exports.centeredT = centeredT = function() { + return exports.transform.apply(exports, [exports.centered].concat(slice.call(arguments))); +}; + +exports.defaultT = defaultT = linearT(0.0, 1.0); + +exports.mappings = { + "beatloop_0.0625_activate": momentaryT, + "beatloop_0.0625_toggle": momentaryT, + "beatloop_0.125_activate": momentaryT, + "beatloop_0.125_toggle": momentaryT, + "beatloop_0.5_activate": momentaryT, + "beatloop_0.5_toggle": momentaryT, + "beatlooproll_0.0625_activate": momentaryT, + "beatlooproll_0.125_activate": momentaryT, + "beatlooproll_0.5_activate": momentaryT, + back: momentaryT, + balance: linearT(-1.0, 1.0), + beatloop_16_activate: momentaryT, + beatloop_16_toggle: momentaryT, + beatloop_1_activate: momentaryT, + beatloop_1_toggle: momentaryT, + beatloop_2_activate: momentaryT, + beatloop_2_toggle: momentaryT, + beatloop_32_activate: momentaryT, + beatloop_32_toggle: momentaryT, + beatloop_4_activate: momentaryT, + beatloop_4_toggle: momentaryT, + beatloop_8_activate: momentaryT, + beatloop_8_toggle: momentaryT, + beatlooproll_16_activate: momentaryT, + beatlooproll_1_activate: momentaryT, + beatlooproll_2_activate: momentaryT, + beatlooproll_32_activate: momentaryT, + beatlooproll_4_activate: momentaryT, + beatlooproll_8_activate: momentaryT, + beatloop_double: momentaryT, + beatloop_halve: momentaryT, + beatjump_4_forward: momentaryT, + beatjump_4_backward: momentaryT, + beatjump_1_forward: momentaryT, + beatjump_1_backward: momentaryT, + beats_translate_curpos: momentaryT, + beatsync: momentaryT, + beatsync_tempo: momentaryT, + crossfader: linearT(-1.0, 1.0), + cue_default: momentaryT, + eject: momentaryT, + enabled: binaryT, + filterHigh: centeredT(0.0, 1.0, 4.0), + filterHighKill: binaryT, + filterLow: centeredT(0.0, 1.0, 4.0), + filterLowKill: binaryT, + filterMid: centeredT(0.0, 1.0, 4.0), + filterMidKill: binaryT, + fwd: momentaryT, + headMix: centeredT(-1.0, 1.0), + headVolume: centeredT(0.0, 1.0, 5.0), + hotcue_1_activate: momentaryT, + hotcue_1_clear: momentaryT, + hotcue_2_activate: momentaryT, + hotcue_2_clear: momentaryT, + hotcue_3_activate: momentaryT, + hotcue_3_clear: momentaryT, + hotcue_4_activate: momentaryT, + hotcue_4_clear: momentaryT, + hotcue_5_activate: momentaryT, + hotcue_5_clear: momentaryT, + hotcue_6_activate: momentaryT, + hotcue_6_clear: momentaryT, + hotcue_7_activate: momentaryT, + hotcue_7_clear: momentaryT, + jog: identityT, + keylock: binaryT, + lfoDelay: linearT(50.0, 10000.0), + lfoDepth: defaultT, + lfoPeriod: linearT(50000.0, 2000000.0), + LoadSelectedTrack: momentaryT, + loop_double: momentaryT, + loop_enabled: binaryT, + loop_end_position: linearT, + loop_halve: momentaryT, + loop_in: momentaryT, + loop_out: momentaryT, + loop_start_position: linearT, + play: binaryT, + playposition: linearT(0.0, 1.0), + plf: binaryT, + pregain: centeredT(0.0, 1.0, 4.0), + pregain_toggle: binaryT, + rate: linearT(-1.0, 1.0), + rate_temp_down: momentaryT, + rate_temp_down_small: momentaryT, + rate_temp_up: momentaryT, + rate_temp_up_small: momentaryT, + reverse: binaryT, + scratch2: linearT(-3.0, 3.0), + scratch2_enable: binaryT, + SelectNextPlaylist: momentaryT, + SelectNextTrack: momentaryT, + SelectPrevPlaylist: momentaryT, + SelectPrevTrack: momentaryT, + SelectTrackKnob: identityT, + slip_enabled: binaryT, + super1: linearT(0.0, 10.0), + talkover: binaryT, + ToggleSelectedSidebarItem: momentaryT, + volume: defaultT, + VuMeter: defaultT, + VuMeterL: defaultT, + VuMeterR: defaultT, + wheel: linearT(-3.0, 3.0) +}; + + +},{}],22:[function(require,module,exports){ +Function.prototype.property = function(prop, desc) { + if (desc instanceof Function) { + desc = { + get: desc + }; + } + return Object.defineProperty(this.prototype, prop, desc); +}; + +Number.prototype.clamp = function(min, max) { + return Math.min(Math.max(this, min), max); +}; + +Number.prototype.sign = function() { + if (this < 0) { + return -1; + } else { + return 1; + } +}; + +Array.prototype.equals = function(other) { + return this.length === other.length && this.every(function(elem, i) { + return elem === other[i]; + }); +}; + +exports.copy = function(a, b) { + var k, v; + if (b == null) { + b = {}; + } + for (k in a) { + v = a[k]; + b[k] = v; + } + return b; +}; + +exports.catching = function(f) { + return function() { + var err, error1; + try { + return f.apply(this, arguments); + } catch (error1) { + err = error1; + return console.log("ERROR: " + err); + } + }; +}; + +exports.assert = function(value, error) { + if (error == null) { + error = void 0; + } + if (!value) { + throw new Error(error != null ? error : "Assertion failed"); + } +}; + +exports.xmlEscape = function(str) { + var ref; + return (ref = str != null ? str.replace('&', '&').replace('"', '"').replace('>', '>').replace('<', '<') : void 0) != null ? ref : ''; +}; + +exports.indent = function(depth) { + return Array(depth * 4).join(" "); +}; + +exports.hexStr = function(number) { + return "0x" + (number.toString(16)); +}; + +exports.xmlTag = function(str, value, indent) { + if (indent == null) { + indent = 0; + } + if (value != null) { + return (exports.indent(indent)) + "<" + str + ">" + value + ""; + } else { + return ""; + } +}; + +exports.joinLn = function(lines) { + return lines.filter(function(x) { + return x; + }).join('\n'); +}; + +exports.factory = function(Klass) { + return function() { + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(Klass, arguments, function(){}); + }; +}; + + +},{}],23:[function(require,module,exports){ +var events, factory, util, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + slice = [].slice; + +events = require('events'); + +util = require('./util'); + +factory = util.factory; + +exports.Value = (function(superClass) { + extend(Value, superClass); + + function Value(arg) { + var initial; + initial = (arg != null ? arg : {}).initial; + Value.__super__.constructor.apply(this, arguments); + this.setMaxListeners(0); + if (initial != null) { + this.value = initial; + } + } + + Value.property('value', { + get: function() { + return this._value; + }, + set: function(newValue) { + return this.setValue(newValue); + } + }); + + Value.prototype.setValue = function(newValue) { + if (this._value !== newValue) { + this._value = newValue; + this.emit('value', newValue); + } + return this._value; + }; + + return Value; + +})(events.EventEmitter); + +exports.value = factory(exports.Value); + +exports.Const = (function() { + Const.prototype.value = void 0; + + function Const(initial) { + if (initial == null) { + initial = void 0; + } + this.value = initial; + } + + Const.prototype.on = function() {}; + + Const.prototype.addListener = function() {}; + + Const.prototype.removeListener = function() {}; + + Const.prototype.listeners = function() { + return []; + }; + + return Const; + +})(); + +exports["const"] = factory(exports.Const); + +exports.Reduce = (function(superClass) { + extend(Reduce, superClass); + + function Reduce() { + var i, len, reduced, reducer, ref, v; + reducer = arguments[0], reduced = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this.reducer = reducer; + this.reduced = reduced; + Reduce.__super__.constructor.call(this); + ref = this.reduced; + for (i = 0, len = ref.length; i < len; i++) { + v = ref[i]; + v.on('value', (function(_this) { + return function() { + return _this.update(); + }; + })(this)); + } + this.update(); + } + + Reduce.prototype.update = function() { + return this.value = this.reduced.reduce((function(_this) { + return function(a, b) { + return exports["const"](_this.reducer(a.value, b.value)); + }; + })(this)).value; + }; + + return Reduce; + +})(exports.Value); + +exports.reduce = factory(exports.Reduce); + +exports.and = function() { + return exports.reduce.apply(exports, [(function(a, b) { + return a && b; + })].concat(slice.call(arguments))); +}; + +exports.or = function() { + return exports.reduce.apply(exports, [(function(a, b) { + return a || b; + })].concat(slice.call(arguments))); +}; + +exports.Transform = (function(superClass) { + extend(Transform, superClass); + + function Transform(transformer, transformed) { + this.transformer = transformer; + this.transformed = transformed; + Transform.__super__.constructor.call(this); + this.transformed.on('value', (function(_this) { + return function() { + return _this.update(); + }; + })(this)); + this.update(); + } + + Transform.prototype.update = function() { + return this.value = this.transformer(this.transformed.value); + }; + + return Transform; + +})(exports.Value); + +exports.transform = factory(exports.Transform); + +exports.not = function() { + return exports.transform.apply(exports, [(function(a) { + return !a; + })].concat(slice.call(arguments))); +}; + + +},{"./util":22,"events":10}]},{},[1]); + +maudio_xponent = require('/home/raskolnikov/dev/mixco/script/maudio_xponent.mixco').maudio_xponent; +/* End of Mixco generated script */ \ No newline at end of file diff --git a/res/controllers/maudio_xponent.mixco.output.midi.xml b/res/controllers/maudio_xponent.mixco.output.midi.xml new file mode 100644 index 000000000000..ea69ef9bfe94 --- /dev/null +++ b/res/controllers/maudio_xponent.mixco.output.midi.xml @@ -0,0 +1,1874 @@ + + + + M-Audio Xponent + Juan Pedro Bolivar Puente <raskolnikov@gnu.org> + Controller mapping for the M-Audio Xponent DJ controller. + https://sinusoid.es/mixco/script/maudio_xponent.mixco.html + https://github.com/arximboldi/mixco/issues + + + + + + + + [Master] + headMix + 0xb2 + 0xd + + + + + + [Master] + crossfader + 0xb2 + 0x7 + + + + + + [EffectRack1_EffectUnit1] + super1 + 0xb0 + 0xc + + + + + + [EffectRack1_EffectUnit1] + mix + 0xb0 + 0xd + + + + + + [EffectRack1_EffectUnit2] + super1 + 0xb1 + 0xc + + + + + + [EffectRack1_EffectUnit2] + mix + 0xb1 + 0xd + + + + + + [EffectRack1_EffectUnit1_Effect1] + parameter1 + 0xb2 + 0x9 + + + + + + [EffectRack1_EffectUnit1_Effect1] + parameter2 + 0xb2 + 0x8 + + + + + + [EffectRack1_EffectUnit1] + group_[Channel1]_enable + 0x92 + 0x0 + + + + + + [EffectRack1_EffectUnit1] + group_[Channel2]_enable + 0x92 + 0x1 + + + + + + [Master] + maudio_xponent.__handle_x90_x2c + 0x90 + 0x2c + + + + + + [Master] + maudio_xponent.__handle_x90_x2c + 0x80 + 0x2c + + + + + + [Master] + maudio_xponent.__handle_x90_x14 + 0x90 + 0x14 + + + + + + [Channel1] + filterLowKill + 0x90 + 0x8 + + + + + + [Channel1] + filterLowKill + 0x80 + 0x8 + + + + + + [Channel1] + filterMidKill + 0x90 + 0x9 + + + + + + [Channel1] + filterMidKill + 0x80 + 0x9 + + + + + + [Channel1] + filterHighKill + 0x90 + 0xa + + + + + + [Channel1] + filterHighKill + 0x80 + 0xa + + + + + + [Channel1] + pregain_toggle + 0x90 + 0xb + + + + + + [Channel1] + pregain_toggle + 0x80 + 0xb + + + + + + [Channel1] + filterLow + 0xb0 + 0x8 + + + + + + [Channel1] + filterMid + 0xb0 + 0x9 + + + + + + [Channel1] + filterHigh + 0xb0 + 0xa + + + + + + [Channel1] + pregain + 0xb0 + 0xb + + + + + + [Channel1] + sync_enabled + 0x90 + 0x2 + + + + + + [Channel1] + sync_enabled + 0x80 + 0x2 + + + + + + [Channel1] + volume + 0xb0 + 0x7 + + + + + + [Master] + maudio_xponent.__handle_x90_x7 + 0x90 + 0x7 + + + + + + [Master] + maudio_xponent.__handle_x90_x7 + 0x80 + 0x7 + + + + + + [Channel1] + back + 0x90 + 0x21 + + + + + + [Channel1] + back + 0x80 + 0x21 + + + + + + [Channel1] + fwd + 0x90 + 0x22 + + + + + + [Channel1] + fwd + 0x80 + 0x22 + + + + + + [Master] + maudio_xponent.__handle_x90_x17 + 0x90 + 0x17 + + + + + + [Master] + maudio_xponent.__handle_x90_x17 + 0x80 + 0x17 + + + + + + [Master] + maudio_xponent.__handle_x90_x18 + 0x90 + 0x18 + + + + + + [Master] + maudio_xponent.__handle_x90_x18 + 0x80 + 0x18 + + + + + + [Master] + maudio_xponent.__handle_x90_x19 + 0x90 + 0x19 + + + + + + [Master] + maudio_xponent.__handle_x90_x19 + 0x80 + 0x19 + + + + + + [Master] + maudio_xponent.__handle_x90_x1a + 0x90 + 0x1a + + + + + + [Master] + maudio_xponent.__handle_x90_x1a + 0x80 + 0x1a + + + + + + [Master] + maudio_xponent.__handle_x90_x1b + 0x90 + 0x1b + + + + + + [Master] + maudio_xponent.__handle_x90_x1b + 0x80 + 0x1b + + + + + + [Master] + maudio_xponent.__handle_x90_x1c + 0x90 + 0x1c + + + + + + [Master] + maudio_xponent.__handle_x90_x1c + 0x80 + 0x1c + + + + + + [Master] + maudio_xponent.__handle_x90_x1d + 0x90 + 0x1d + + + + + + [Master] + maudio_xponent.__handle_x90_x1d + 0x80 + 0x1d + + + + + + [Master] + maudio_xponent.__handle_x90_x1e + 0x90 + 0x1e + + + + + + [Master] + maudio_xponent.__handle_x90_x1e + 0x80 + 0x1e + + + + + + [Channel1] + beats_translate_curpos + 0x90 + 0x1f + + + + + + [Channel1] + beats_translate_curpos + 0x80 + 0x1f + + + + + + [Channel1] + reverse + 0x90 + 0x20 + + + + + + [Channel1] + reverse + 0x80 + 0x20 + + + + + + [Channel1] + cue_default + 0x90 + 0x23 + + + + + + [Channel1] + cue_default + 0x80 + 0x23 + + + + + + [Channel1] + play + 0x90 + 0x24 + + + + + + [Master] + maudio_xponent.__handle_x90_x29 + 0x90 + 0x29 + + + + + + [Master] + maudio_xponent.__handle_x90_x29 + 0x80 + 0x29 + + + + + + [Master] + maudio_xponent.__handle_x90_x2b + 0x90 + 0x2b + + + + + + [Master] + maudio_xponent.__handle_x90_x2b + 0x80 + 0x2b + + + + + + [Channel1] + reloop_exit + 0x90 + 0x2a + + + + + + [Master] + maudio_xponent.__handle_x90_x25 + 0x90 + 0x25 + + + + + + [Master] + maudio_xponent.__handle_x90_x25 + 0x80 + 0x25 + + + + + + [Master] + maudio_xponent.__handle_x90_x26 + 0x90 + 0x26 + + + + + + [Master] + maudio_xponent.__handle_x90_x26 + 0x80 + 0x26 + + + + + + [Master] + maudio_xponent.__handle_x90_x27 + 0x90 + 0x27 + + + + + + [Master] + maudio_xponent.__handle_x90_x27 + 0x80 + 0x27 + + + + + + [Master] + maudio_xponent.__handle_x90_x28 + 0x90 + 0x28 + + + + + + [Master] + maudio_xponent.__handle_x90_x28 + 0x80 + 0x28 + + + + + + [EffectRack1_EffectUnit1] + group_[Channel1]_enable + 0x90 + 0xc + + + + + + [EffectRack1_EffectUnit2] + group_[Channel1]_enable + 0x90 + 0xd + + + + + + [Master] + maudio_xponent.__handle_xb0_xe + 0xb0 + 0xe + + + + + + [Master] + maudio_xponent.__handle_x90_xe + 0x90 + 0xe + + + + + + [Master] + maudio_xponent.__handle_x90_xe + 0x80 + 0xe + + + + + + [QuickEffectRack1_[Channel1]] + super1 + 0xb0 + 0xf + + + + + + [QuickEffectRack1_[Channel1]] + enabled + 0x90 + 0xf + + + + + + [QuickEffectRack1_[Channel1]] + enabled + 0x80 + 0xf + + + + + + [Master] + maudio_xponent.__handle_x90_x15 + 0x90 + 0x15 + + + + + + [Master] + maudio_xponent.__handle_x90_x16 + 0x90 + 0x16 + + + + + + [Master] + maudio_xponent.__handle_x90_x16 + 0x80 + 0x16 + + + + + + [Master] + maudio_xponent.__handle_xb0_x16 + 0xb0 + 0x16 + + + + + + [Master] + maudio_xponent.__handle_x90_x10 + 0x90 + 0x10 + + + + + + [Master] + maudio_xponent.__handle_x90_x10 + 0x80 + 0x10 + + + + + + [Master] + maudio_xponent.__handle_x90_x11 + 0x90 + 0x11 + + + + + + [Master] + maudio_xponent.__handle_x90_x11 + 0x80 + 0x11 + + + + + + [Channel1] + rate + 0xe0 + 0x0 + + + + + + [Master] + maudio_xponent.__handle_x90_x12 + 0x90 + 0x12 + + + + + + [Master] + maudio_xponent.__handle_x90_x12 + 0x80 + 0x12 + + + + + + [Master] + maudio_xponent.__handle_x90_x13 + 0x90 + 0x13 + + + + + + [Master] + maudio_xponent.__handle_x90_x13 + 0x80 + 0x13 + + + + + + [Master] + maudio_xponent.__handle_x91_x2c + 0x91 + 0x2c + + + + + + [Master] + maudio_xponent.__handle_x91_x2c + 0x81 + 0x2c + + + + + + [Master] + maudio_xponent.__handle_x91_x14 + 0x91 + 0x14 + + + + + + [Channel2] + filterLowKill + 0x91 + 0x8 + + + + + + [Channel2] + filterLowKill + 0x81 + 0x8 + + + + + + [Channel2] + filterMidKill + 0x91 + 0x9 + + + + + + [Channel2] + filterMidKill + 0x81 + 0x9 + + + + + + [Channel2] + filterHighKill + 0x91 + 0xa + + + + + + [Channel2] + filterHighKill + 0x81 + 0xa + + + + + + [Channel2] + pregain_toggle + 0x91 + 0xb + + + + + + [Channel2] + pregain_toggle + 0x81 + 0xb + + + + + + [Channel2] + filterLow + 0xb1 + 0x8 + + + + + + [Channel2] + filterMid + 0xb1 + 0x9 + + + + + + [Channel2] + filterHigh + 0xb1 + 0xa + + + + + + [Channel2] + pregain + 0xb1 + 0xb + + + + + + [Channel2] + sync_enabled + 0x91 + 0x2 + + + + + + [Channel2] + sync_enabled + 0x81 + 0x2 + + + + + + [Channel2] + volume + 0xb1 + 0x7 + + + + + + [Master] + maudio_xponent.__handle_x91_x7 + 0x91 + 0x7 + + + + + + [Master] + maudio_xponent.__handle_x91_x7 + 0x81 + 0x7 + + + + + + [Channel2] + back + 0x91 + 0x21 + + + + + + [Channel2] + back + 0x81 + 0x21 + + + + + + [Channel2] + fwd + 0x91 + 0x22 + + + + + + [Channel2] + fwd + 0x81 + 0x22 + + + + + + [Master] + maudio_xponent.__handle_x91_x17 + 0x91 + 0x17 + + + + + + [Master] + maudio_xponent.__handle_x91_x17 + 0x81 + 0x17 + + + + + + [Master] + maudio_xponent.__handle_x91_x18 + 0x91 + 0x18 + + + + + + [Master] + maudio_xponent.__handle_x91_x18 + 0x81 + 0x18 + + + + + + [Master] + maudio_xponent.__handle_x91_x19 + 0x91 + 0x19 + + + + + + [Master] + maudio_xponent.__handle_x91_x19 + 0x81 + 0x19 + + + + + + [Master] + maudio_xponent.__handle_x91_x1a + 0x91 + 0x1a + + + + + + [Master] + maudio_xponent.__handle_x91_x1a + 0x81 + 0x1a + + + + + + [Master] + maudio_xponent.__handle_x91_x1b + 0x91 + 0x1b + + + + + + [Master] + maudio_xponent.__handle_x91_x1b + 0x81 + 0x1b + + + + + + [Master] + maudio_xponent.__handle_x91_x1c + 0x91 + 0x1c + + + + + + [Master] + maudio_xponent.__handle_x91_x1c + 0x81 + 0x1c + + + + + + [Master] + maudio_xponent.__handle_x91_x1d + 0x91 + 0x1d + + + + + + [Master] + maudio_xponent.__handle_x91_x1d + 0x81 + 0x1d + + + + + + [Master] + maudio_xponent.__handle_x91_x1e + 0x91 + 0x1e + + + + + + [Master] + maudio_xponent.__handle_x91_x1e + 0x81 + 0x1e + + + + + + [Channel2] + beats_translate_curpos + 0x91 + 0x1f + + + + + + [Channel2] + beats_translate_curpos + 0x81 + 0x1f + + + + + + [Channel2] + reverse + 0x91 + 0x20 + + + + + + [Channel2] + reverse + 0x81 + 0x20 + + + + + + [Channel2] + cue_default + 0x91 + 0x23 + + + + + + [Channel2] + cue_default + 0x81 + 0x23 + + + + + + [Channel2] + play + 0x91 + 0x24 + + + + + + [Master] + maudio_xponent.__handle_x91_x29 + 0x91 + 0x29 + + + + + + [Master] + maudio_xponent.__handle_x91_x29 + 0x81 + 0x29 + + + + + + [Master] + maudio_xponent.__handle_x91_x2b + 0x91 + 0x2b + + + + + + [Master] + maudio_xponent.__handle_x91_x2b + 0x81 + 0x2b + + + + + + [Channel2] + reloop_exit + 0x91 + 0x2a + + + + + + [Master] + maudio_xponent.__handle_x91_x25 + 0x91 + 0x25 + + + + + + [Master] + maudio_xponent.__handle_x91_x25 + 0x81 + 0x25 + + + + + + [Master] + maudio_xponent.__handle_x91_x26 + 0x91 + 0x26 + + + + + + [Master] + maudio_xponent.__handle_x91_x26 + 0x81 + 0x26 + + + + + + [Master] + maudio_xponent.__handle_x91_x27 + 0x91 + 0x27 + + + + + + [Master] + maudio_xponent.__handle_x91_x27 + 0x81 + 0x27 + + + + + + [Master] + maudio_xponent.__handle_x91_x28 + 0x91 + 0x28 + + + + + + [Master] + maudio_xponent.__handle_x91_x28 + 0x81 + 0x28 + + + + + + [EffectRack1_EffectUnit1] + group_[Channel2]_enable + 0x91 + 0xc + + + + + + [EffectRack1_EffectUnit2] + group_[Channel2]_enable + 0x91 + 0xd + + + + + + [Master] + maudio_xponent.__handle_xb1_xe + 0xb1 + 0xe + + + + + + [Master] + maudio_xponent.__handle_x91_xe + 0x91 + 0xe + + + + + + [Master] + maudio_xponent.__handle_x91_xe + 0x81 + 0xe + + + + + + [QuickEffectRack1_[Channel2]] + super1 + 0xb1 + 0xf + + + + + + [QuickEffectRack1_[Channel2]] + enabled + 0x91 + 0xf + + + + + + [QuickEffectRack1_[Channel2]] + enabled + 0x81 + 0xf + + + + + + [Master] + maudio_xponent.__handle_x91_x15 + 0x91 + 0x15 + + + + + + [Master] + maudio_xponent.__handle_x91_x16 + 0x91 + 0x16 + + + + + + [Master] + maudio_xponent.__handle_x91_x16 + 0x81 + 0x16 + + + + + + [Master] + maudio_xponent.__handle_xb1_x16 + 0xb1 + 0x16 + + + + + + [Master] + maudio_xponent.__handle_x91_x10 + 0x91 + 0x10 + + + + + + [Master] + maudio_xponent.__handle_x91_x10 + 0x81 + 0x10 + + + + + + [Master] + maudio_xponent.__handle_x91_x11 + 0x91 + 0x11 + + + + + + [Master] + maudio_xponent.__handle_x91_x11 + 0x81 + 0x11 + + + + + + [Channel2] + rate + 0xe1 + 0x0 + + + + + + [Master] + maudio_xponent.__handle_x91_x12 + 0x91 + 0x12 + + + + + + [Master] + maudio_xponent.__handle_x91_x12 + 0x81 + 0x12 + + + + + + [Master] + maudio_xponent.__handle_x91_x13 + 0x91 + 0x13 + + + + + + [Master] + maudio_xponent.__handle_x91_x13 + 0x81 + 0x13 + + + + + + + + [EffectRack1_EffectUnit1_Effect1] + parameter1 + 0xb2 + 0x9 + 0x7f + 0x0 + 1 + + + [EffectRack1_EffectUnit1_Effect1] + parameter2 + 0xb2 + 0x8 + 0x7f + 0x0 + 1 + + + [Channel1] + pfl + 0x90 + 0x14 + 0x7f + 0x0 + 1 + + + [Channel1] + filterLowKill + 0x90 + 0x8 + 0x7f + 0x0 + 1 + + + [Channel1] + filterMidKill + 0x90 + 0x9 + 0x7f + 0x0 + 1 + + + [Channel1] + filterHighKill + 0x90 + 0xa + 0x7f + 0x0 + 1 + + + [Channel1] + pregain_toggle + 0x90 + 0xb + 0x7f + 0x0 + 1 + + + [Channel1] + sync_enabled + 0x90 + 0x2 + 0x7f + 0x0 + 1 + + + [Channel1] + back + 0x90 + 0x21 + 0x7f + 0x0 + 1 + + + [Channel1] + fwd + 0x90 + 0x22 + 0x7f + 0x0 + 1 + + + [Channel1] + beats_translate_curpos + 0x90 + 0x1f + 0x7f + 0x0 + 1 + + + [Channel1] + reverse + 0x90 + 0x20 + 0x7f + 0x0 + 1 + + + [Channel1] + cue_indicator + 0x90 + 0x23 + 0x7f + 0x0 + 1 + + + [Channel1] + play + 0x90 + 0x24 + 0x7f + 0x0 + 1 + + + [Channel1] + loop_enabled + 0x90 + 0x2a + 0x7f + 0x0 + 1 + + + [EffectRack1_EffectUnit1] + group_[Channel1]_enable + 0x90 + 0xc + 0x7f + 0x0 + 1 + + + [EffectRack1_EffectUnit2] + group_[Channel1]_enable + 0x90 + 0xd + 0x7f + 0x0 + 1 + + + [QuickEffectRack1_[Channel1]] + enabled + 0x90 + 0xf + 0x7f + 0x0 + 1 + + + [Channel2] + pfl + 0x91 + 0x14 + 0x7f + 0x0 + 1 + + + [Channel2] + filterLowKill + 0x91 + 0x8 + 0x7f + 0x0 + 1 + + + [Channel2] + filterMidKill + 0x91 + 0x9 + 0x7f + 0x0 + 1 + + + [Channel2] + filterHighKill + 0x91 + 0xa + 0x7f + 0x0 + 1 + + + [Channel2] + pregain_toggle + 0x91 + 0xb + 0x7f + 0x0 + 1 + + + [Channel2] + sync_enabled + 0x91 + 0x2 + 0x7f + 0x0 + 1 + + + [Channel2] + back + 0x91 + 0x21 + 0x7f + 0x0 + 1 + + + [Channel2] + fwd + 0x91 + 0x22 + 0x7f + 0x0 + 1 + + + [Channel2] + beats_translate_curpos + 0x91 + 0x1f + 0x7f + 0x0 + 1 + + + [Channel2] + reverse + 0x91 + 0x20 + 0x7f + 0x0 + 1 + + + [Channel2] + cue_indicator + 0x91 + 0x23 + 0x7f + 0x0 + 1 + + + [Channel2] + play + 0x91 + 0x24 + 0x7f + 0x0 + 1 + + + [Channel2] + loop_enabled + 0x91 + 0x2a + 0x7f + 0x0 + 1 + + + [EffectRack1_EffectUnit1] + group_[Channel2]_enable + 0x91 + 0xc + 0x7f + 0x0 + 1 + + + [EffectRack1_EffectUnit2] + group_[Channel2]_enable + 0x91 + 0xd + 0x7f + 0x0 + 1 + + + [QuickEffectRack1_[Channel2]] + enabled + 0x91 + 0xf + 0x7f + 0x0 + 1 + + + + diff --git a/res/controllers/mixco/README.md b/res/controllers/mixco/README.md new file mode 100644 index 000000000000..9fc615249542 --- /dev/null +++ b/res/controllers/mixco/README.md @@ -0,0 +1,18 @@ + +Mixco Scripts +============= + +Some of the scripts in the parent folder are the compile output of +**Mixco**, a tool that can generate the `.xml` and `.js` files from a +single source file, among other things. This folder contains the +original sources for such scripts. + +If you modify these scripts, you need to use the `mixco` command to +compile the `.xml` and `.js` files that Mixxx can read. To install +it, you need [NPM](https://www.npmjs.org/) and then: +```sh + $ npm install -g mixco +``` + +You can find more information on how to install and use this +tool [in the offical Mixco website](https://sinusoid.es/mixco/). diff --git a/res/controllers/mixco/korg_nanokontrol2.mixco.litcoffee b/res/controllers/mixco/korg_nanokontrol2.mixco.litcoffee new file mode 100644 index 000000000000..835c39e3ee70 --- /dev/null +++ b/res/controllers/mixco/korg_nanokontrol2.mixco.litcoffee @@ -0,0 +1,298 @@ +script.nanokontrol2 +=================== + +> This file is part of the [Mixco framework](http://sinusoid.es/mixco). +> - **View me [on a static web](http://sinusoid.es/mixco/script/korg_nanokontrol2.mixco.html)** +> - **View me [on GitHub](https://github.com/arximboldi/mixco/blob/master/script/korg_nanokontrol2.mixco.litcoffee)** + +Mixxx script file for the **Korg NanoKontrol2** controller. + +This script description is a bit more verbose than others, at it tries +to serve as **tutorial** on how to write your own controller scripts. +People just interested in the functionallity of the mapping can find +this in indented bullet points. + + ![NanoKontrol2 Layout](http://sinusoid.es/mixco/pic/korg_nanokontrol2.jpg) + +Dependencies +------------ + +First, we have to import he *Mixco* modules that we are going to use, +using the [NodeJS, +**require**](http://nodejs.org/api/modules.html#modules_module_require_id) +function. Also, lets define these couple of shortcuts to save typing. + + mixco = require 'mixco' + {assert} = mixco.util + c = mixco.control + b = mixco.behaviour + v = mixco.value + +The script +---------- + +### Declaration + +We define the script with the **script.register** function, which will +create the script instance. As first parameter we pass the current +module, that is contained in the special *NodeJS* variable +`module`. The second parameter is an object with the actual script. + + mixco.script.register module, + +### Metadata + +Then we fill out the metadata. This will be shown to the user in the +preferences window in Mixxx when he selects the script. + + info: + name: '[mixco] Korg Nanokontrol 2' + author: 'Juan Pedro Bolivar Puente ' + wiki: 'https://sinusoid.es/mixco/script/korg_nanokontrol2.mixco.html' + forums: 'https://github.com/arximboldi/mixco/issues' + description: + """ + Controller mapping for Korg Nanokontrol 2. Unlike + other scripts that are oriented as a secondary + controller, this provides basic deck controls, being + usable as primary interface. + """ + +### Constructor + +All the actual interesting stuff happens in the *constructor* of the +script. Here we will create the controls and add them to the script +and define their behaviour. + + constructor: -> + +#### Master section + +In this section we describe controls that have effect on the master +channel and main outputs. + +##### Transport section + +All the buttons on the left side of the controllers is what we call +the *transport section*. These are global buttons + +* The *cycle* button will be used as modifier. + + @cycle = b.modifier() + c.control(0x2e).does @cycle + +Most of the transport controls will have their behaviour defined +per-deck. We define them here and add the behaviours later. + + @backButton = c.control 0x3a + @fwdButton = c.control 0x3b + @nudgeDownButton = c.control 0x2b + @nudgeUpButton = c.control 0x2c + +* The *marker* section can be used to browse the library. The left + and right arrows browse the playlist up and down. When *set* is + pressed, they move the sidebar. + + @marker = b.modifier() + c.control(0x3C).does @marker + + g = "[Playlist]" + c.control(0x3D) + .when(@marker, g, "SelectPrevPlaylist") + .else g, "SelectPrevTrack" + c.control(0x3E) + .when(@marker, g, "SelectNextPlaylist") + .else g, "SelectNextTrack" + + @loadTrack = c.control(0x2a) + +Here are some more controls that get their actual functionallity +defined later. + + @sync = c.control(0x29) + @syncTempo = c.control(0x2d) + +##### Channel sections + +And finally, some of the master functionality are mapped to the +channel sliders. + +* The *headphone gain* is mapped to the 7th slider. + + g = "[Master]" + c.input(0x06).does g, "headVolume" + +* The *headphone mix* is mapped to the 6th slider. + + c.input(0x05).does g, "headMix" + +* The *crossfader* is mapped to the 2nd slider. + + c.input(0x02).does b.soft g, "crossfader" + +* The main *balance* is mapped to the 1st slider. + + c.input(0x01).does b.soft g, "balance" + + +#### Deck controls + +Then, we create a chooser object over the *pfl* (headphone) parameter, +so we will have only one deck with PFL activated at a time. +Also, this will let us change the behaviour of some *transport* +controls depending on which deck is *selected* -- i.e, has PFL +enabled. + + @decks = b.chooser() + +Finally we add the per-deck controls, that are defined in `addDeck`. + + @addDeck 0 + @addDeck 1 + + addDeck: (i) -> + assert i in [0, 1] + + g = "[Channel#{i+1}]" + offset = if i == 0 then [3, 2, 1, 0] else [4, 5, 6, 7] + +##### Channel sections + +* The top 8 knobs are mapped to the two decks mixer filter section + (low, mid, high, gain). They spread out from the center, i.e. the + 4th and 5th knob control the low EQ filter, the 3rd and 6th knob + control the mid EQ filter, and so on. + + c.input(0x10 + offset[0]).does g, "filterLow" + c.input(0x10 + offset[1]).does g, "filterMid" + c.input(0x10 + offset[2]).does g, "filterHigh" + c.input(0x10 + offset[3]).does b.soft g, "pregain" + +* Then two central channel sections (4th and 5th) control the + following parameters of the left and right deck: + + * S: Selects the deck *PFL*. + * M: *Cue* button for the deck. + * R: *Play* button for the deck. + * The fader controls the *volume* of the deck. + + c.control(0x20 + offset[0]).does @decks.add g, "pfl" + c.control(0x30 + offset[0]).does g, "cue_default", g, "cue_indicator" + c.control(0x40 + offset[0]).does g, "play" + c.input(0x00 + offset[0]).does g, "volume" + +* The two furthest channel sections (1st and 8th) control the pitch +related stuff of the two decks. + + * S: *Bpm tap*, also shows the speed. + * M: Toggles *key lock*. + * R: Sets the *beat grid* to match the current playhead position. + * The fader controls the *pitch* of the deck. + + c.control(0x20 + offset[3]).does g, "bpm_tap", g, "beat_active" + c.control(0x30 + offset[3]).does g, "keylock" + c.control(0x40 + offset[3]).does g, "beats_translate_curpos" + c.input(0x00 + offset[3]).does b.soft g, "rate" + +Then, we have some looping related buttons in the middle. Also, these +are the hotcue trigger and clear with the *cycle* and *marker* +modifiers. + +* The *S, M, R* buttons of the central channels (2nd, 3rd, 6th, 7th) + have different functionality, depending on the modifiers. + * Normally, they *toggle loops* of size 1, 2, 4 and 8 beats. The *R* +buttons of these sections control *loop double* and *halve.* + * When the *cycle* button is held, they *launch hot-cues*. + * When the *set* button is held, they *clear hot-cues*. + + c.control(0x20 + offset[1]) + .when(@cycle, g, "hotcue_1_activate", g, "hotcue_1_enabled") + .else.when(@marker, g, "hotcue_1_clear", g, "hotcue_1_enabled") + .else g, "beatloop_2_toggle", g, "beatloop_2_enabled" + c.control(0x20 + offset[2]) + .when(@cycle, g, "hotcue_2_activate", g, "hotcue_2_enabled") + .else.when(@marker, g, "hotcue_2_clear", g, "hotcue_2_enabled") + .else g, "beatloop_4_toggle", g, "beatloop_4_enabled" + c.control(0x30 + offset[1]) + .when(@cycle, g, "hotcue_3_activate", g, "hotcue_3_enabled") + .else.when(@marker, g, "hotcue_3_clear", g, "hotcue_3_enabled") + .else g, "beatloop_8_toggle", g, "beatloop_8_enabled" + c.control(0x30 + offset[2]) + .when(@cycle, g, "hotcue_4_activate", g, "hotcue_4_enabled") + .else.when(@marker, g, "hotcue_4_clear", g, "hotcue_4_enabled") + .else g, "beatloop_16_toggle", g, "beatloop_16_enabled" + c.control(0x40 + offset[1]) + .when(@cycle, g, "hotcue_5_activate", g, "hotcue_5_enabled") + .else.when(@marker, g, "hotcue_5_clear", g, "hotcue_5_enabled") + .else g, "loop_halve" + c.control(0x40 + offset[2]) + .when(@cycle, g, "hotcue_6_activate", g, "hotcue_6_enabled") + .else.when(@marker, g, "hotcue_6_clear", g, "hotcue_6_enabled") + .else g, "loop_double" + +##### Transport section + +These per-deck controls of the transport section have effect on the +*selected track*. We consider the current PFL track to be the +selected track. + +The *<<* and *>>* buttons are a bit more complicated. We want them +to behave as *nudge* buttons for the selected track, but we want the +*cycle* modifier to change the nudge speed. + +See how we use the `behaviour.and` condition combinator to mix the +conditions. We also use `control.else.when` to simplify the negative +condition. + +* The *<<* and *>>* buttons nudge and scroll over the selected track. + + chooseCycle = v.and @cycle, @decks.activator i + @nudgeUpButton + .when(chooseCycle, b.toggle 0, 0.5, g, "wheel") + .else.when @decks.activator(i), b.toggle 0, 0.1, g, "wheel" + @nudgeDownButton + .when(chooseCycle, b.toggle 0, -0.5, g, "wheel") + .else.when @decks.activator(i), b.toggle 0, -0.1, g, "wheel" + +* The *track<* and *track>* buttons control the selected track *fast + forward* and *fast rewind*. + + @fwdButton.when @decks.activator(i), g, "fwd" + @backButton.when @decks.activator(i), g, "back" + +* Load *stop* button loads the selected track in the selected deck. + + @loadTrack.when @decks.activator(i), g, "LoadSelectedTrack" + +* The *play* and *record* buttons synchronize to the other track. The + *play* button can be held to enable master synchronization for the deck. + + @sync.when @decks.activator(i), g, "sync_enabled" + @syncTempo.when @decks.activator(i), g, "beatsync" + +### Initialization + +The **init** method is called by Mixxx when the script is loaded. Here +we can initialize the state of Mixxx. In our case, we select the first +deck, such that all transport buttons are directly functional. + + init: -> + @decks.activate 0 + +License +------- + +> Copyright (C) 2013 Juan Pedro Bolívar Puente +> +> 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 . diff --git a/res/controllers/mixco/maudio_xponent.mixco.litcoffee b/res/controllers/mixco/maudio_xponent.mixco.litcoffee new file mode 100644 index 000000000000..88f0ce116171 --- /dev/null +++ b/res/controllers/mixco/maudio_xponent.mixco.litcoffee @@ -0,0 +1,393 @@ +script.xponent +============== + +> This file is part of the [Mixco framework](http://sinusoid.es/mixco). +> - **View me [on a static web](http://sinusoid.es/mixco/script/maudio_xponent.mixco.html)** +> - **View me [on GitHub](https://github.com/arximboldi/mixco/blob/master/script/maudio_xponent.mixco.litcoffee)** + +Mixxx script file for the **M-Audio Xponent** controller. The numbers +in the following picture will be used in the script to describe the +functionallity of the controls. + + ![Xponent Layout](http://sinusoid.es/mixco/pic/maudio_xponent.png) + + mixco = require 'mixco' + {assert} = mixco.util + c = mixco.control + b = mixco.behaviour + v = mixco.value + + mixco.script.register module, + + info: + name: '[mixco] M-Audio Xponent' + author: 'Juan Pedro Bolivar Puente ' + wiki: 'https://sinusoid.es/mixco/script/maudio_xponent.mixco.html' + forums: 'https://github.com/arximboldi/mixco/issues' + description: + """ + Controller mapping for the M-Audio Xponent DJ controller. + """ + +Global section +-------------- + +Controls that do not have a per-deck functionality. + + constructor: -> + ccId = (cc) -> c.ccIds cc, 2 + g = "[Master]" + +* **27.** Headphone mix. + + c.input(ccId 0x0D).does g, "headMix" + +* **39.** Crossfader. + + c.input(ccId 0x07).does g, "crossfader" + +### Effects + +Most of knobs and buttons in **24** and **25** are dedicated to +effects. Some of them are mapped per-deck --see later-- but some are +mapped globally: + +* The *first and second knobs* of the *left deck* control the *super* + and *mix* of the first effect unit. In the *right deck*, they do + likewise for the second effect unit. + + c.input(0x0c, 0x00).does \ + b.soft "[EffectRack1_EffectUnit1]", "super1" + c.input(0x0d, 0x00).does \ + b.soft "[EffectRack1_EffectUnit1]", "mix" + + c.input(0x0c, 0x01).does \ + b.soft "[EffectRack1_EffectUnit2]", "super1" + c.input(0x0d, 0x01).does \ + b.soft "[EffectRack1_EffectUnit2]", "mix" + +* **16.** When in *MIDI mode*, the touch pad can be used to control + the first two parameters of the first effect. *MIDI mode* can be + enabled with the button labeled `MIDI` below the touch pad. + Otherwise, the touch pad is used to control the computer mouse. + + c.control(0x09, 0x02) + .does "[EffectRack1_EffectUnit1_Effect1]", "parameter1" + c.control(0x08, 0x02) + .does "[EffectRack1_EffectUnit1_Effect1]", "parameter2" + +* **17.** and **18.** When in *MIDI mode*, the touch pad buttons *toggle + the first effect unit* for the first and second deck respectively. + + c.input(c.noteOnIds 0x00, 0x02) + .does "[EffectRack1_EffectUnit1]", "group_[Channel1]_enable" + c.input(c.noteOnIds 0x01, 0x02) + .does "[EffectRack1_EffectUnit1]", "group_[Channel2]_enable" + +Per deck controls +----------------- + +We add the two decks with the `addDeck(idx)` function. In the +*Xponent*, each MIDI message is repeated per-deck on a different +channel. + + @decks = b.chooser() + @addDeck 0 + @addDeck 1 + + addDeck: (i) -> + assert i in [0, 1] + g = "[Channel#{i+1}]" + ccId = (cc) -> c.ccIds cc, i + noteId = (note) -> c.noteIds note, i + noteOnId = (note) -> c.noteOnIds note, i + +* **15.** Shift. It changes the behaviour of some controls. Note + that there is a shift button per-deck, which only affects the + controls of that deck. + + shift = b.modifier() + c.control(noteId 0x2C).does shift + +* **12.** Pre-Fade Listen. Select which deck goes to the headphones. + + c.control(noteOnId 0x14).does @decks.add g, "pfl" + +### The mixer + + +* **20.** Filter and gain kills. + + c.control(noteId 0x08).does g, "filterLowKill" + c.control(noteId 0x09).does g, "filterMidKill" + c.control(noteId 0x0A).does g, "filterHighKill" + c.control(noteId 0x0B).does g, "pregain_toggle" + +* **22.** Mixer EQ and gain. + + c.input(ccId 0x08).does g, "filterLow" + c.input(ccId 0x09).does g, "filterMid" + c.input(ccId 0x0A).does g, "filterHigh" + c.input(ccId 0x0B).does b.soft g, "pregain" + +* **23.** Per deck volume meters. + + c.output(c.ccIds 0x12+i, 3) + .does b.mapOut(g, "VuMeter").meter() + +* **34.** Sync button. Like the button in the UI, it can be held + pressed to enable the deck in the *master sync* group. + + c.control(noteId 0x02).does g, "sync_enabled" + +* **33.** Deck volume. + + c.input(ccId 0x07).does b.soft g, "volume" + +* **38.** Punch-in/transform. While pressed, lets this track be heard + overriding the crossfader. + + c.control(noteId 0x07).does b.punchIn (0.5-i) + +### The transport section + +* **29.** Song progress indication. When it approches the end of the + playing song it starts blinking. + + c.output(c.ccIds 0x14+i, 3).does b.playhead g + +* **30.** Back and forward. + + c.control(noteId 0x21).does g, "back" + c.control(noteId 0x22).does g, "fwd" + +* **31.** Includes several buttons... + +- The top buttons with numbers are the *hotcues*. On first press, + sets the hotcue. On second press, jumps to hotcue. When *shift* is + held, deletes the hotcue point. + + for idx in [0..4] + c.control(noteId(0x17 + idx)) + .when(shift, + g, "hotcue_#{idx+1}_clear", + g, "hotcue_#{idx+1}_enabled") + .else g, "hotcue_#{idx+1}_activate", + g, "hotcue_#{idx+1}_enabled" + +- The little arrow buttons do *beatjump* -- jump forward or back by + 4 beats. When *shift* is pressed they jump by one beat. + + c.control(noteId 0x1C) + .when shift, g, "beatjump_1_backward" + .else g, "beatjump_4_backward" + c.control(noteId 0x1D) + .when shift, g, "beatjump_1_forward" + .else g, "beatjump_4_forward" + +- The *lock* button does *key lock* -- i.e. makes tempo changes + independent of pitch. When *shift* is pressed, it expands/collapses + the selected browser item. + + c.control(noteId 0x1E) + .when(shift, "[Playlist]", "ToggleSelectedSidebarItem") + .else g, "keylock" + +- The *plus* (+) button moves the beat grid to align with the current + play position. + + c.control(noteId 0x1F).does g, "beats_translate_curpos" + +- The *minus* (-) button plays the track in reverese. + + c.control(noteId 0x20).does g, "reverse" + +* **35.** Cue button. + + c.control(noteId 0x23).does g, "cue_default", g, "cue_indicator" + +* **37.** Play/pause button. + + c.control(noteOnId 0x24).does g, "play" + + +### The looping section + +* **36.** This includes several controls to manage loops... + +- The *in* and *out* buttons set the loop start and end to the + current playing position. When *shift* is pressed, they halve and + double the current loop size respectively. + + c.control(noteId 0x29) + .when(shift, g, "loop_halve") + .else g, "loop_in" + c.control(noteId 0x2B) + .when(shift, g, "loop_double") + .else g, "loop_out" + +- The *loop* toggles the current loop on/off whenever there is a loop + selected. + + c.control(noteOnId 0x2A) + .does g, "reloop_exit", g, "loop_enabled" + +- The numbers set and trigger a loop of 4, 8, 16 and 32 beats + respectively. When *shift*, they set loops of 1/8, 1/2, 1 or 2 + beats long. + + c.control(noteId 0x25) + .when(shift, g, "beatloop_0.125_activate", + g, "beatloop_0.125_enabled") + .else g, "beatloop_4_activate", + g, "beatloop_4_enabled" + c.control(noteId 0x26) + .when(shift, g, "beatloop_0.5_activate", + g, "beatloop_0.5_enabled") + .else g, "beatloop_8_activate", + g, "beatloop_8_enabled" + c.control(noteId 0x27) + .when(shift, g, "beatloop_1_activate", + g, "beatloop_1_enabled") + .else g, "beatloop_16_activate", + g, "beatloop_16_enabled" + c.control(noteId 0x28) + .when(shift, g, "beatloop_2_activate", + g, "beatloop_2_enabled") + .else g, "beatloop_32_activate", + g, "beatloop_32_enabled" + +### Effects + +* In the **24** group, the *first* and *second* buttons enable the + first or second effect units for this deck. + + c.control(noteOnId 0x0c) + .does "[EffectRack1_EffectUnit1]", "group_#{g}_enable" + c.control(noteOnId 0x0d) + .does "[EffectRack1_EffectUnit2]", "group_#{g}_enable" + +* The *third knob and button* in **24** and **25** enable a *beat + roll* effect, similar to those of the looping section but with + resolution controllable with a knob for more drastic effects, and + the play position is restored when turned off. + + beatloop = b.beatEffect g, 'roll' + c.input(ccId 0x0e).does beatloop.selector() + c.control(noteId 0x0e).does beatloop + +* The *fourth knob and button* in **24** and **25** enable the quick + effect knob -- by default mapped to a filter sweep. + + c.input(ccId 0x0f) + .does "[QuickEffectRack1_#{g}]", 'super1' + c.control(noteId 0x0f) + .does "[QuickEffectRack1_#{g}]", 'enabled' + +### The wheel and pitch section + +* **10.** Toggles *scratch* mode. + + scratchMode = b.switch() + c.control(noteOnId 0x15).does scratchMode + +* **11.** The wheel does different functions... + + - When the deck is stopped, it moves the play position. + + - When *scratch* mode is on, it will stop the song when touched on + top and control the track play like a vinyl when moved. + + - Otherwise, it can be used to *nudge* the playing speed up or down + to sync the phase of tracks when the track is playing. + + - When *shift* is pressed, it will scroll through the current list + of tracks in the browser. + + selectTrackKnobTransform = do -> + toggle = 1 + (ev) -> + val = ev.value - 64 + toggle -= 1 + if toggle < 0 then toggle = 3 + if toggle == 0 then val.sign() else null + + c.control(noteId 0x16) + .when v.and(v.not(shift), scratchMode), b.scratchEnable i+1 + + c.input(ccId 0x16) + .when(shift, b.map("[Playlist]", "SelectTrackKnob") + .transform selectTrackKnobTransform) + .else.when(scratchMode, + b.scratchTick(i+1).options.spread64) + .else b.map(g, "jog").transform (ev) -> (ev.value - 64) / 8 + +* **26.** Temporarily nudges the pitch down or up. When **shift**, +they do it in a smaller amount. + + c.control(noteId 0x10) + .when(shift, g, "rate_temp_down_small") + .else g, "rate_temp_down" + c.control(noteId 0x11) + .when(shift, g, "rate_temp_up_small") + .else g, "rate_temp_up" + +* **32.** Pitch slider, adjusts playing speed. + + c.input(c.pbIds i).does b.soft g, "rate" + +* **21.** Custom effects that include... + +- The *big cross* (X) button simulates a *brake* effect as if the + turntable was turned off suddenly. On *shift*, it ejects the track + from the deck. + + c.control(noteId 0x12) + .when(shift, g, "eject") + .else b.brake i+1 + +- The *big minus* (--) button simulates a *backspin* effect as if the + vinyl was launched backwards. On *shift*, it loads the selected + track in the browser into the deck. + + c.control(noteId 0x13) + .when(shift, g, "LoadSelectedTrack") + .else b.spinback i+1 + +Initialization +-------------- + +Unlike old Mixxx versions, this script initializes the device properly +for light feedback. The trick of holding the two and key button on +initalization are no longer required. + + preinit: -> + msg = [0xF0, 0x00, 0x20, 0x08, 0x00, 0x00, 0x63, 0x0E, + 0x16, 0x40, 0x00, 0x01, 0xF7] + @mixxx.midi.sendSysexMsg msg, msg.length + + init: -> + @decks.activate 0 + + postshutdown: -> + msg = [0xF0, 0x00, 0x20, 0x08, 0x00, 0x00, 0x63, 0x0E, + 0x16, 0x40, 0x00, 0x00, 0xF7] + @mixxx.midi.sendSysexMsg msg, msg.length + +License +------- + +> Copyright (C) 2013 Juan Pedro Bolívar Puente +> +> 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 . diff --git a/res/controllers/mixco/novation_twitch.mixco.js b/res/controllers/mixco/novation_twitch.mixco.js new file mode 100644 index 000000000000..b7a9298f8023 --- /dev/null +++ b/res/controllers/mixco/novation_twitch.mixco.js @@ -0,0 +1,450 @@ +// script.twitch +// ============= +// +// > This file is part of the [Mixco framework](http://sinusoid.es/mixco). +// > - **View me [on a static web](http://sinusoid.es/mixco/script/novation_twitch.mixco.html)** +// > - **View me [on GitHub](https://github.com/arximboldi/mixco/blob/master/script/novation_twitch.mixco.litcoffee)** +// +// Mixx script file for the **Novation Twitch** controller. +// +// This script serves as **tutorial** for creating scripts using the +// *Mixco* framework, but programming directly in JavaScript. Still, +// we recommend you to try CoffeeScript, since it is a bit of a nicer +// language. +// +// If you want to modify this script, you may want to read the +// [Novation Twitch Programmer Guide](https://us.novationmusic.com/support/downloads/twitch-programmers-reference-guide) +// +// ### Note for Linux Users +// +// The Linux Kernel version 3.10 is required to get Novation Twitch +// detected as soundcard or MIDI device. +// +// ![Novation Twitch Layout](http://sinusoid.es/mixco/pic/novation_twitch.png) +// +// Dependencies +// ------------ +// +// First, we have to import the modules from the framework. We use +// that the *NodeJS* `require` function. Note that all other NodeJS +// modules are usable too when writing your script with the *Mixco* +// framework. + +var _ = require('underscore') +var mixco = require('mixco') +var c = mixco.control +var b = mixco.behaviour +var v = mixco.value + +// The script +// ---------- +// +// When writing a controller script we use the `script.register` +// function to generate and install a script instance in the current +// module. The first parameter is the current module as defined by +// *NodeJS*, the second parameter is the JavaScript object with all +// the functions and information about our script. + +mixco.script.register(module, { + + // ### Metadata + // + // Then the `info` object contains the meta-data that is displayed + // to the user in the MIDI mapping chooser of Mixxx. + + info: { + name: "[mixco] Novation Twitch", + author: "Juan Pedro Bolivar Puente ", + forums: 'https://github.com/arximboldi/mixco/issues', + wiki: 'https://sinusoid.es/mixco/script/korg_nanokontrol2.mixco.html', + description: "Controller mapping for Novation Twitch (in basic mode).", + }, + + // ### Constructor + // + // The constructor contains the definition of the MIDI mapping. + // Here we create all the different control objects and add them + // to the script instance. + + constructor: function () { + + // #### Master section + // + // Many of the master controls of the that the *headphone + // volume*, *headphone mix*, *booth volume* and *master volume* + // knobs are handled directly by the integrated soundcard of + // the controller. We map the rest here. + // + // * *Crossfader* slider. + + c.input(0x08, 0x07).does("[Master]", "crossfader") + + // #### Mic/aux and effects + // + // Sadly, the buttons *Aux*, *Deck A*, *Deck B* and *PFL* + // of the effects and microphone sections are controlled by + // the hardware in a bit of a useless way, so they do nothing + // -- other than light up when they are pressed. + + var ccIdFxBanks = function (index) { + banks = 5 + params = 4 + ids = [] + for (var j = 0; j < banks; ++j) + ids.push.apply(ids, c.ccIds(index + params * j, 0xB)) + return ids + } + + // * Microphone *volume* control and *on/off* button. + + c.input(ccIdFxBanks(0x3)).does(b.soft("[Microphone]", "pregain")) + c.control(c.noteIds(0x23, 0xB)).does("[Microphone]", "talkover") + + // * The the *Depth* and *Mix* knobs in the *Master FX* + // section are mapped to *mix* and *super* of the first + // effect unit. + + c.input(ccIdFxBanks(0x0)) + .does("[EffectRack1_EffectUnit1]", "mix") + c.input(ccIdFxBanks(0x1)) + .option(scaledDiff(1/2)) + .does("[EffectRack1_EffectUnit1]", "super1") + + // * The *beats* knob can be used to change the selected effect. + + c.input(ccIdFxBanks(0x2)) + .does("[EffectRack1_EffectUnit1]", "chain_selector") + + // * The *on/off* button of the FX section completley toggles + // the first effect unit. + + c.control(c.noteIds(0x22, 0xB)) + .does("[EffectRack1_EffectUnit1]", "enabled") + + // #### Browse + // + // * The *back* and *fwd* can be used to scroll the sidebar. + + c.input(c.noteIds(0x54, 0x7)).does( + "[Playlist]", "SelectPrevPlaylist") + c.input(c.noteIds(0x56, 0x7)).does( + "[Playlist]", "SelectNextPlaylist") + + // * The *scroll* encoder scrolls the current view. When + // pressed it moves faster. + + scrollFaster = b.modifier() + + c.input(c.noteIds(0x55, 0x7)).does(scrollFaster) + c.input(0x55, 0x7) + .when (scrollFaster, + b.map("[Playlist]", "SelectTrackKnob") + .option(scaledSelectKnob(8))) + .else_(b.map("[Playlist]", "SelectTrackKnob") + .options.selectknob) + + // * The *area* toggles the maximized library. + + c.control(c.noteIds(0x50, 0x7)).does( + "[Master]", "maximize_library") + + // * The *view* button in the *browser* section lets you tap + // the tempo for the track that is currently on PFL. + + this.viewButton = c.control(c.noteIds(0x51, 0x7)) + + // ### Per deck controls + // + // We use a `behaviou.chooser` for the PFL selection. This + // will make sure that only one deck's PFL is selected at + // a time for greater convenience. Then, we define a `addDeck` + // function that will add the actual controls for each of the + // decks. + + this.decks = b.chooser() + this.addDeck(0) + this.addDeck(1) + + }, + + addDeck: function (i) { + var g = "[Channel" + (i+1) + "]" + var ccId = function (cc) { return c.ccIds(cc, 0x07+i) } + var ccIdShift = function (cc) { return c.ccIds(cc, 0x09+i) } + var ccIdAll = function (cc) { return _.union(ccId(cc), + ccIdShift(cc)) } + var noteId = function (note) { return c.noteIds(note, 0x07+i) } + var noteIdShift = function (note) { return c.noteIds(note, 0x09+i) } + var noteIdAll = function (cc) { return _.union(noteId(cc), + noteIdShift(cc)) } + + // #### Mixer section + // + // * PFL deck selection. + + c.control(noteIdAll(0x0A)).does(this.decks.add(g, "pfl")) + + this.viewButton.when(this.decks.activator(i), + g, "bpm_tap", g, "beat_active") + + // * *Volume* fader and *low*, *mid*, *high* and *trim* knobs. + // *Trim* is the deck *gain* knob in Mixxx. + + c.input(ccIdAll(0x07)).does(g, "volume") + c.input(ccIdAll(0x46)).does(g, "filterLow") + c.input(ccIdAll(0x47)).does(g, "filterMid") + c.input(ccIdAll(0x48)).does(g, "filterHigh") + c.input(ccIdAll(0x09)).does(g, "pregain") + + // * *Volume* meters for each channel. + + c.output(noteIdAll(0x5f)).does(b.mapOut(g, "VuMeter").meter()) + + // * The **fader FX** we use to control the quick filter. The + // **on/off** button below can be used to toggle it. + // Likewise, pressing the knob momentarily toggles it. + + c.input(ccIdAll(0x06)) + .option(scaledDiff(1/2)) + .does("[QuickEffectRack1_"+g+"]", 'super1') + c.control(noteIdAll(0x06)) + .does("[QuickEffectRack1_"+g+"]", 'enabled') + c.control(noteIdAll(0x0D)) + .does("[QuickEffectRack1_"+g+"]", 'enabled') + + // #### Effects + // + // * In the *Master FX* section, the *FX Select* left and + // right enable the first effect unit on the deck in the + // direction of the arrow. + + c.control(c.noteIds(0x20+i, 0xB)) + .does("[EffectRack1_EffectUnit1]", "group_"+g+"_enable") + + // #### Browse + // + // * The *load A* or *load B* buttons load the selected track + // to the given deck. + + c.control(c.noteIds(0x52+i, 0x7)).does(g, "LoadSelectedTrack") + + // #### Deck transport + // + // * The *play* and *cue* buttons work as expected. On + // *shift*, the cue button does a reverse effect. + + var redLed = 0x00 + var amberLed = 0x40 + var greenLed = 0x70 + var pad = function (ids, color) { + return c.control(ids).states({ + on: color + 0xf, + off: color + 0x1 + }) + } + + pad(noteIdAll(0x17), greenLed).does(g, "play") + pad(noteId(0x16), redLed).does(g, "cue_default", g, "cue_indicator") + pad(noteIdShift(0x16), amberLed).does(g, "reverse") + + // * The *keylock* button toggles the pitch-independent time + // stretching. On *shift*, it toggles *slip mode*, in which + // loops and scratching continue playback on the background + // thus returning the playhead to where the track would have + // been. + + slipMode = b.switch_() + c.control(noteId(0x12)).does(g, "keylock") + c.control(noteIdShift(0x12)).does(slipMode) + + // * The *sync* button. Like the button in the UI, it can be + // held pressed to enable the deck in the *master sync* + // group. + + c.control(noteIdAll(0x13)).does(g, "sync_enabled") + + // #### Beat grid + // + // * The *adjust* button *aligns the beatgrid* to the current + // play position. + + c.control(noteIdAll(0x11)).does(g, "beats_translate_curpos") + + // * The *set* button toggles loop and hot-cue *quantization* + // on or off. + + c.control(noteIdAll(0x10)).does(g, "quantize") + + // #### Pitch and transport bar + // + // * The *pitch* encoder moves the pitch slider up and + // down. When it is pressed, it moves it pitch faster. + + var coarseRateFactor = 1/10 + var coarseRateOn = b.modifier() + + c.input(noteIdAll(0x03)).does(coarseRateOn) + c.input(ccIdAll(0x03)) + .when (coarseRateOn, + b.map(g, "rate").option(scaledDiff(2))) + .else_(b.map(g, "rate").option(scaledDiff(1/12))) + + // * In *drop* mode, the touch strip scrolls through the song. + + c.input(ccId(0x34)).does(g, "playposition") + + // * In *swipe* mode, the touch strip nudges the pitch up and + // down. When *shift* is held it simulates scratching. + + c.input(ccId(0x35)).does(g, "jog") + .option(scaledSelectKnob(-1/3)) + c.input(ccIdShift(0x35)).does(b.scratchTick(i+1)) + .options.selectknob, + c.input(noteIdShift(0x47)) + .does(b.scratchEnable(i+1, 128)) + .when(slipMode, b.map(g, "slip_enabled").options.switch_) + + // #### Performance modes + // + // ##### Hot cues + // + // * In *hot-cues* mode, the performance buttons control the + // hot cues. One may *clear* hot-cues with *shift*. + + for (var j = 0; j < 8; ++j) { + pad(noteId(0x60+j), amberLed).does( + g, "hotcue_" + (j+1) + "_activate", + g, "hotcue_" + (j+1) + "_enabled") + pad(noteIdShift(0x60+j), amberLed).does( + g, "hotcue_" + (j+1) + "_clear", + g, "hotcue_" + (j+1) + "_enabled") + } + + // ##### Slicer + // + // There is no functionality like a *slicer* in Mixxx, but we + // reuse these pads for various purposes in this mode. + // + // * The buttons *1 to 4* trigger the first four samplers. + // The sample plays as long as the button is held. + + for (var j = 0; j < 4; ++j) + pad(noteIdAll(0x68+j), redLed).does( + "[Sampler" + (j+1) + "]", "cue_preview") + + // * The buttons *5 and 6* trigger a *spinback* and *brake* + // effect respectively. + + pad(noteIdAll(0x6C), greenLed).does(b.spinback(i+1)) + pad(noteIdAll(0x6D), greenLed).does(b.brake(i+1)) + + // * The buttons *7 and 8* perform a stutter effect at + // different speeds. + + pad(noteIdAll(0x6E), amberLed).does(b.stutter(g, 1/8)) + pad(noteIdAll(0x6F), amberLed).does(b.stutter(g, 1/4)) + + // ##### Auto loop + // + // * In *auto-loop* mode, the pads select *loops* of sizes + // 0.5, 1, 2, 4, 8, 16, 32 or 64, beats (starting at the + // top-left pad). On *shift*, it creates loops of sizes + // 1/32, 1/16, 1/8, 1/4, 1/2, 1, 2, or 4 beats. + + loopSize = [ "0.03125", "0.0625", "0.125", "0.25", + "0.5", "1", "2", "4", + "8", "16", "32", "64" ] + for (var j = 0; j < 8; ++j) + pad(noteId(0x70+j), greenLed).does( + g, "beatloop_" + loopSize[4+j] + "_toggle", + g, "beatloop_" + loopSize[4+j] + "_enabled") + for (var j = 0; j < 8; ++j) + pad(noteIdShift(0x70+j), greenLed).does( + g, "beatloop_" + loopSize[j] + "_toggle", + g, "beatloop_" + loopSize[j] + "_enabled") + + // ##### Loop roll + // + // * In *loop-roll* mode, momentarily creates a loop and, on + // release returns the playhead to where it would have been + // without looping. Loop sizes are 1/32, 1/16, 1/8, 1/4, + // 1/2, 1, 2, or 4 beats (starting at the top-left pad). On + // *shift*, it is 0.5, 1, 2, 4, 8, 16, 32 or 64 beats. + + loopSize = [ "0.03125", "0.0625", "0.125", "0.25", + "0.5", "1", "2", "4", + "8", "16", "32", "64" ] + for (var j = 0; j < 8; ++j) + pad(noteId(0x78+j), greenLed).does( + g, "beatlooproll_" + loopSize[j] + "_activate", + g, "beatloop_" + loopSize[j] + "_enabled") + for (var j = 0; j < 8; ++j) + pad(noteIdShift(0x78+j), greenLed).does( + g, "beatlooproll_" + loopSize[4+j] + "_activate", + g, "beatloop_" + loopSize[4+j] + "_enabled") + + }, + + // ### Initialization + // + // The `preinit` function is called before the MIDI controls are + // initialized. We are going to set the device in *basic mode*, + // as mentioned in the manual. This means that mode management is + // done by the device -- this will simplify the script and let + // have direct lower latency mappings more often. + + preinit: function () { + this.mixxx.midi.sendShortMsg(0xb7, 0x00, 0x6f) + this.mixxx.midi.sendShortMsg(0xb7, 0x00, 0x00) + }, + + init: function () { + this.decks.activate(0) + }, + + // ### Shutdown + // + // The documentation suggests to reset the device when the program + // shuts down. This means that all the lights are turned off and + // the device is in basic mode, ready to be used by some other + // program. + + postshutdown: function () { + this.mixxx.midi.sendShortMsg(0xb7, 0x00, 0x00) + } + +}); + +// Utilities +// --------- +// +// The *scaledDiff* function returns a behaviour option that is useful +// to define encoders with a specific sensitivity, which is useful to +// correct the issues of the stepped encoders. + +function scaledDiff (factor) { + return function (v, v0) { + return (v0 + factor * (v > 64 ? v - 128 : v)).clamp(0, 128) + } +} + +function scaledSelectKnob (factor) { + return function (v) { + return factor * (v > 64 ? v - 128 : v) + } +} + +// > Copyright (C) 2013 Juan Pedro Bolívar Puente +// > +// > 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 . diff --git a/res/controllers/novation_twitch.mixco.output.js b/res/controllers/novation_twitch.mixco.output.js new file mode 100644 index 000000000000..ad56ba5fa438 --- /dev/null +++ b/res/controllers/novation_twitch.mixco.output.js @@ -0,0 +1,8582 @@ +/* + * File generated with Mixco framework version: 2.0.2 + * More info at: + */ + +MIXCO_SCRIPT_FILENAME = '/home/raskolnikov/dev/mixco/script/novation_twitch.mixco.js'; + +require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 64 ? v1 - 128 : v1); + }); + add('button', function(v) { + return v !== 0; + }); + add('switch', function(v) { + return 1; + }); + result.switch_ = result["switch"]; + add('hercjog', function(v1, v0) { + return v0 + (v1 > 64 ? v1 - 128 : v1); + }); + add('spread64', function(v) { + return v - 64; + }); + add('selectknob', function(v) { + if (v > 64) { + return v - 128; + } else { + return v; + } + }); + return add('soft-takeover', 'softTakeover', { + enable: function(b) { + if (isinstance(b, exports.MapIn)) { + return b.script.mixxx.engine.softTakeover(b.group, b.key, true); + } + }, + disable: function(b) { + if (isinstance(b, exports.MapIn)) { + return b.script.mixxx.engine.softTakeover(b.group, b.key, false); + } + } + }); + })(); + + exports.makeOptionsChooser = makeOptionsChooser = function(obj) { + var key, opt, result; + result = {}; + for (key in option) { + opt = option[key]; + Object.defineProperty(result, key, { + get: (function(opt) { + return function() { + return obj.option(opt); + }; + })(opt) + }); + } + return result; + }; + + exports.Behaviour = (function(superClass) { + extend1(Behaviour, superClass); + + function Behaviour() { + return Behaviour.__super__.constructor.apply(this, arguments); + } + + Behaviour.prototype.enable = function(script, actor) { + var i, len, opt, ref3, results; + assert(this.actor == null); + assert(this.script == null); + this.script = script; + this.actor = actor; + this._eventListener = (function(_this) { + return function(ev) { + var i, len, opt, ref3; + if (_this._options != null) { + ev = copy(ev); + ref3 = _this._options; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (typeof opt.process === "function") { + opt.process(ev, _this); + } + } + } + return _this.onMidiEvent(ev); + }; + })(this); + actor.on('event', this._eventListener); + if (this._options != null) { + ref3 = this._options; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + results.push(typeof opt.enable === "function" ? opt.enable(this) : void 0); + } + return results; + } + }; + + Behaviour.prototype.disable = function(script, actor) { + var i, len, opt, ref3; + assert(this.script === script); + assert(this.actor === actor); + if (this._options != null) { + ref3 = this._options; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (typeof opt.disable === "function") { + opt.disable(this); + } + } + } + actor.removeListener('event', this._eventListener); + delete this.script; + return delete this.actor; + }; + + Behaviour.prototype.option = function() { + var i, len, opt, options, ref3; + options = 1 <= arguments.length ? slice.call(arguments, 0) : []; + for (i = 0, len = options.length; i < len; i++) { + opt = options[i]; + assert(opt); + } + (ref3 = (this._options != null ? this._options : this._options = [])).push.apply(ref3, map(options, toOption)); + return this; + }; + + Behaviour.property('options', function() { + return makeOptionsChooser(this); + }); + + Behaviour.prototype.directInMapping = function() { + return null; + }; + + Behaviour.prototype.directOutMapping = function() { + return null; + }; + + Behaviour.prototype.onMidiEvent = function(ev) { + return null; + }; + + Behaviour.prototype.getMidiValue = function() { + return this.value; + }; + + Behaviour.property('midiValue', function() { + return this.getMidiValue(); + }); + + return Behaviour; + + })(value.Value); + + exports.Call = (function(superClass) { + extend1(Call, superClass); + + function Call(onMidiEvent) { + this.onMidiEvent = onMidiEvent; + Call.__super__.constructor.call(this); + } + + return Call; + + })(exports.Behaviour); + + exports.call = factory(exports.Call); + + exports.Output = (function(superClass) { + extend1(Output, superClass); + + Output.prototype.minimum = 1; + + Output.prototype.maximum = void 0; + + function Output() { + Output.__super__.constructor.apply(this, arguments); + this.output = value.value(); + } + + Output.prototype.enable = function() { + Output.__super__.enable.apply(this, arguments); + if (this.actor.send != null) { + if (this._updateOutputCallback == null) { + this._updateOutputCallback = (function(_this) { + return function() { + return _this.updateOutput(); + }; + })(this); + } + this.output.on('value', this._updateOutputCallback); + } + if (this.actor.doSend != null) { + return this.updateOutput(this.actor.doSend); + } + }; + + Output.prototype.disable = function() { + if (this._updateOutputCallback != null) { + this.removeListener('value', this._updateOutputCallback); + this._updateOutputCallback = void 0; + } + return Output.__super__.disable.apply(this, arguments); + }; + + Output.prototype.updateOutput = function(sendfn) { + if (sendfn == null) { + sendfn = null; + } + if (sendfn == null) { + sendfn = this.actor.send; + } + return sendfn.call(this.actor, (Math.abs(this.output.value) >= this.minimum ? 'on' : 'off')); + }; + + return Output; + + })(exports.Behaviour); + + exports.Transform = (function(superClass) { + extend1(Transform, superClass); + + function Transform(transformer1, initial) { + this.transformer = transformer1; + if (initial == null) { + initial = void 0; + } + Transform.__super__.constructor.call(this, { + initial: initial + }); + } + + Transform.prototype.onMidiEvent = function(ev) { + var result; + result = this.transformer(ev, this.midiValue); + if (result != null) { + return this.output.value = this.value = result; + } + }; + + Transform.prototype.getMidiValue = function() { + var base, ref3; + return (ref3 = typeof (base = this.transformer).inverse === "function" ? base.inverse(this.value) : void 0) != null ? ref3 : this.value; + }; + + return Transform; + + })(exports.Output); + + exports.transform = factory(exports.Transform); + + exports.modifier = function() { + return exports.transform(transform.momentaryT, false); + }; + + exports["switch"] = function() { + return exports.transform(transform.binaryT, false); + }; + + exports.switch_ = exports["switch"]; + + exports.MapIn = (function(superClass) { + extend1(MapIn, superClass); + + function MapIn(ingroupOrParams, inkey) { + var ref3; + if (inkey == null) { + inkey = void 0; + } + MapIn.__super__.constructor.apply(this, arguments); + ref3 = !isinstance(ingroupOrParams, String) ? ingroupOrParams : { + group: ingroupOrParams, + key: inkey + }, this.group = ref3.group, this.key = ref3.key; + this._transform = transform.mappings[this.key]; + } + + MapIn.prototype.transform = function(trans) { + this._transform = trans; + return this; + }; + + MapIn.prototype.enable = function(script, actor) { + var engine; + MapIn.__super__.enable.apply(this, arguments); + engine = script.mixxx.engine; + this.value = engine.getValue(this.group, this.key); + if (this.listeners('value').length > 0) { + if (this._inHandler == null) { + this._inHandler = script.registerHandler((function(_this) { + return function(v) { + return _this.value = v; + }; + })(this)); + } + engine.connectControl(this.group, this.key, this._inHandler); + return this._inHandlerConnected = true; + } + }; + + MapIn.prototype.disable = function() { + if (this._inHandlerConnected != null) { + this.script.mixxx.engine.connectControl(this.group, this.key, this._inHandler, true); + this._inHandlerConnected = false; + } + return MapIn.__super__.disable.apply(this, arguments); + }; + + MapIn.prototype.directInMapping = function() { + if (this._transform === transform.mappings[this.key]) { + return { + group: this.group, + key: this.key + }; + } + }; + + MapIn.prototype.onMidiEvent = function(ev) { + var val; + val = this._transform(ev, this.midiValue); + if (val != null) { + this.script.mixxx.engine.setValue(this.group, this.key, val); + if (this.listeners('value').length === 0) { + return this.value = val; + } + } + }; + + MapIn.prototype.getMidiValue = function() { + var ref3, ref4; + return (ref3 = (ref4 = this._transform) != null ? typeof ref4.inverse === "function" ? ref4.inverse(this.value) : void 0 : void 0) != null ? ref3 : this.value; + }; + + return MapIn; + + })(exports.Behaviour); + + exports.mapIn = factory(exports.MapIn); + + exports.MapOut = (function(superClass) { + extend1(MapOut, superClass); + + function MapOut(outgroupOrParams, outkey) { + var ref3; + if (outkey == null) { + outkey = void 0; + } + MapOut.__super__.constructor.apply(this, arguments); + ref3 = !isinstance(outgroupOrParams, String) ? outgroupOrParams : { + outgroup: outgroupOrParams, + outkey: outkey + }, this.outgroup = ref3.outgroup, this.outkey = ref3.outkey; + } + + MapOut.prototype.meter = function(transformer) { + if (transformer == null) { + transformer = void 0; + } + this._outTransform = transformer; + if (this._outTransform == null) { + this._outTransform = transform.mappings[this.outkey].inverse; + } + this.updateOutput = function() { + return this.actor.send(Math.floor(this._outTransform(this.output.value))); + }; + return this; + }; + + MapOut.prototype.enable = function(script, actor) { + var engine; + MapOut.__super__.enable.apply(this, arguments); + engine = script.mixxx.engine; + this.output.value = engine.getValue(this.outgroup, this.outkey); + if (this.output.listeners('value').length > 0) { + if (this._outHandler == null) { + this._outHandler = script.registerHandler((function(_this) { + return function(v) { + return _this.output.value = v; + }; + })(this)); + } + engine.connectControl(this.outgroup, this.outkey, this._outHandler); + return this._outHandlerConnected = true; + } + }; + + MapOut.prototype.disable = function() { + if (this._outHandlerConnected != null) { + this.script.mixxx.engine.connectControl(this.outgroup, this.outkey, this._outHandler, true); + this._outHandlerConnected = false; + } + return MapOut.__super__.disable.apply(this, arguments); + }; + + MapOut.prototype.directOutMapping = function() { + if (this._outTransform == null) { + return { + group: this.outgroup, + key: this.outkey, + minimum: this.minimum + }; + } + }; + + return MapOut; + + })(exports.Output); + + exports.mapOut = factory(exports.MapOut); + + exports.Map = (function(superClass) { + extend1(Map, superClass); + + function Map(groupOrParams, key, outgroup, outkey) { + var params; + params = !isinstance(groupOrParams, String) ? groupOrParams : { + group: groupOrParams, + key: key, + outgroup: outgroup, + outkey: outkey + }; + if (params.outgroup == null) { + params.outgroup = params.group; + } + if (params.outkey == null) { + params.outkey = params.key; + } + Map.__super__.constructor.call(this, params); + } + + return Map; + + })(multi(exports.MapIn, exports.MapOut)); + + exports.map = factory(exports.Map); + + exports.toBehaviour = function() { + var args, behaviour; + behaviour = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + if (args.length > 0) { + return exports.map.apply(exports, [behaviour].concat(slice.call(args))); + } else { + return behaviour; + } + }; + + exports.soft = function() { + return exports.map.apply(exports, arguments).option(option.softTakeover); + }; + + exports.toggle = function() { + var args, offValue, onValue; + offValue = arguments[0], onValue = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; + return exports.map.apply(exports, args).transform(function(ev) { + if (ev.pressed) { + return onValue; + } else { + return offValue; + } + }); + }; + + exports.set = function() { + var args, valueToSet; + valueToSet = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.toggle.apply(exports, [valueToSet, null].concat(slice.call(args))); + }; + + exports.Chooser = (function(superClass) { + extend1(Chooser, superClass); + + function Chooser(arg) { + var ref3; + ref3 = arg != null ? arg : {}, this.autoExclusive = ref3.autoExclusive, this.onDisable = ref3.onDisable; + Chooser.__super__.constructor.apply(this, arguments); + this._selectedIndex = null; + this._chooseOptions = []; + this._chooseActivators = []; + this._chooseSelectors = []; + this._chooseHandles = []; + } + + Chooser.prototype.add = function(group, key, listen) { + var activator, idx; + if (listen == null) { + listen = null; + } + idx = this._chooseOptions.length; + activator = exports.map(group, key).transform((function(_this) { + return function(ev) { + if (ev.pressed) { + _this.activate(idx); + } + return null; + }; + })(this)); + this._chooseOptions.push([group, key, listen]); + this._chooseActivators.push(activator); + return activator; + }; + + Chooser.prototype.enable = function(script) { + var engine, group, i, key, len, listen, ref3, ref4; + Chooser.__super__.enable.apply(this, arguments); + if (this._updateValueHandler == null) { + this._updateValueHandler = script.registerHandler((function(_this) { + return function() { + return _this._updateValue(); + }; + })(this)); + } + engine = script.mixxx.engine; + ref3 = this._chooseOptions; + for (i = 0, len = ref3.length; i < len; i++) { + ref4 = ref3[i], group = ref4[0], key = ref4[1], listen = ref4[2]; + if (listen == null) { + listen = key; + } + engine.connectControl(group, listen, this._updateValueHandler); + } + return this._updateValue(); + }; + + Chooser.prototype.disable = function(script) { + var engine, group, i, key, len, listen, ref3, ref4; + assert(this._updateValueHandler); + engine = script.mixxx.engine; + ref3 = this._chooseOptions; + for (i = 0, len = ref3.length; i < len; i++) { + ref4 = ref3[i], group = ref4[0], key = ref4[1], listen = ref4[2]; + if (listen == null) { + listen = key; + } + engine.connectControl(group, listen, this._updateValueHandler, true); + } + return Chooser.__super__.disable.apply(this, arguments); + }; + + Chooser.prototype.activator = function(idx) { + assert((0 <= idx && idx < this._chooseOptions.length)); + return this._chooseActivators[idx]; + }; + + Chooser.prototype.selector = function() { + var select, selector; + select = (function(_this) { + return function(ev) { + var v; + v = (ev.value / 128.0 * _this._chooseOptions.length).clamp(0, _this._chooseOptions.length - 1); + _this._update({ + index: Math.floor(v) + }); + return v; + }; + })(this); + select.inverse = (function(_this) { + return function(v) { + return v / _this._chooseOptions.length * 128.0; + }; + })(this); + selector = extend(exports.transform(select), { + _updateValue: function(newv) { + if (Math.floor(newv) !== Math.floor(this.value)) { + return this.value = this.output.value = newv; + } + } + }); + this._chooseSelectors.push(selector); + return selector; + }; + + Chooser.prototype.momentary = function() { + return exports.action({ + press: (function(_this) { + return function() { + return _this._update({ + enable: true + }); + }; + })(this), + release: (function(_this) { + return function() { + return _this._update({ + enable: false + }); + }; + })(this) + }); + }; + + Chooser.prototype.activate = function(idx) { + this._update({ + index: idx, + enable: true + }); + return this; + }; + + Chooser.prototype.select = function(idx) { + if (this.actor != null) { + this._update({ + index: idx, + enable: true + }); + } else { + this._selectedIndex = idx; + } + return this; + }; + + Chooser.prototype.onMidiEvent = function(event) { + var enable; + if (event.pressed) { + enable = !this.value; + this._update({ + enable: enable + }); + if (!enable) { + return typeof this.onDisable === "function" ? this.onDisable() : void 0; + } + } + }; + + Chooser.prototype._update = function(arg) { + var enable, group, i, idx, index, key, len, listen, ref3, ref4, ref5, ref6, ref7, script; + ref3 = arg != null ? arg : {}, index = ref3.index, enable = ref3.enable; + if (enable == null) { + enable = this.value; + } + if (index == null) { + index = this._selectedIndex; + } + index = index != null ? index.clamp(0, this._chooseOptions.length - 1) : void 0; + if (index !== this._selectedIndex || enable !== this.value) { + script = (ref4 = this.script) != null ? ref4 : this._chooseActivators[index].script; + if (index != null) { + ref5 = this._chooseOptions[index], group = ref5[0], key = ref5[1], listen = ref5[2]; + script.mixxx.engine.setValue(group, key, enable); + } + if (!this.autoExclusive || !enable) { + ref6 = this._chooseOptions; + for (idx = i = 0, len = ref6.length; i < len; idx = ++i) { + ref7 = ref6[idx], group = ref7[0], key = ref7[1]; + if (idx !== index) { + script.mixxx.engine.setValue(group, key, false); + } + } + } + return this._selectedIndex = index; + } + }; + + Chooser.prototype._updateValue = function() { + var engine, i, len, ref3, selector; + if (this.script != null) { + engine = this.script.mixxx.engine; + this.value = this.output.value = _.some(this._chooseOptions, function(arg) { + var group, key, listen; + group = arg[0], key = arg[1], listen = arg[2]; + if (listen == null) { + listen = key; + } + return engine.getValue(group, listen); + }); + ref3 = this._chooseSelectors; + for (i = 0, len = ref3.length; i < len; i++) { + selector = ref3[i]; + selector._updateValue(this._selectedIndex); + } + } + return this; + }; + + return Chooser; + + })(exports.Output); + + exports.chooser = factory(exports.Chooser); + + exports.When = (function(superClass) { + extend1(When, superClass); + + function When() { + var _condition, base, wrapped; + _condition = arguments[0], wrapped = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this._condition = _condition; + this["else"] = (function(_this) { + return function() { + return _this._else.apply(_this, arguments); + }; + })(this); + this["else"].when = (function(_this) { + return function() { + return _this._elseWhen.apply(_this, arguments); + }; + })(this); + this.when = this["else"].when; + this.else_ = this["else"]; + When.__super__.constructor.call(this); + this._wrapped = exports.toBehaviour.apply(exports, wrapped); + this._condition.on('value', (function(_this) { + return function() { + return _this._update(); + }; + })(this)); + if (this._lastCondition !== 'no-more-negations') { + this._lastCondition = this._condition; + if ((base = this._lastCondition).negation == null) { + base.negation = value.not(this._condition); + } + } + } + + When.prototype.option = function() { + var ref3; + When.__super__.option.apply(this, arguments); + (ref3 = this._wrapped).option.apply(ref3, arguments); + return this; + }; + + When.prototype._elseWhen = function() { + var args, condition, nextCondition; + condition = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + assert(this._lastCondition != null, "Can not define more conditions after 'else'"); + nextCondition = value.and(condition, value.not(this._lastCondition)); + nextCondition.negation = value.and(this._lastCondition.negation, value.not(condition)); + this._lastCondition = nextCondition; + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(exports.When, [nextCondition].concat(slice.call(args)), function(){}); + }; + + When.prototype._else = function() { + var args, nextCondition; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastCondition != null, "Can not define more conditions after 'else'"); + nextCondition = this._lastCondition.negation; + nextCondition.negation = 'no-more-negations'; + delete this._lastCondition; + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(exports.When, [nextCondition].concat(slice.call(args)), function(){}); + }; + + When.prototype.enable = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + When.__super__.enable.apply(this, arguments); + this._enableOn = args; + this._enableRequested = true; + return this._update(); + }; + + When.prototype.disable = function() { + this._enableRequested = false; + this._update(); + return When.__super__.disable.apply(this, arguments); + }; + + When.prototype._update = function() { + var ref3, ref4; + this.value = this._enableRequested && this._condition.value; + if (this._wrapped.actor && !this.value) { + (ref3 = this._wrapped).disable.apply(ref3, this._enableOn); + } + if (!this._wrapped.actor && this.value) { + return (ref4 = this._wrapped).enable.apply(ref4, this._enableOn); + } + }; + + When.prototype.directOutMapping = function() { + return null; + }; + + When.prototype.directInMapping = function() { + return null; + }; + + return When; + + })(exports.Behaviour); + + exports.when = factory(exports.When); + + exports.Action = (function(superClass) { + extend1(Action, superClass); + + Action.prototype.minimum = true; + + function Action(action) { + this.action = action != null ? action : void 0; + Action.__super__.constructor.call(this); + if (this.onPress == null) { + this.onPress = this.action.press; + } + if (this.onRelease == null) { + this.onRelease = this.action.release; + } + } + + Action.prototype.onMidiEvent = function(ev) { + var val; + val = this.value = this.output.value = ev.pressed; + if (val) { + return typeof this.onPress === "function" ? this.onPress() : void 0; + } else { + return typeof this.onRelease === "function" ? this.onRelease() : void 0; + } + }; + + return Action; + + })(exports.Output); + + exports.action = factory(exports.Action); + + exports.punchIn = function(threshold, threshold2) { + var inThreshold, oldxfader; + if (threshold2 == null) { + threshold2 = void 0; + } + oldxfader = void 0; + inThreshold = function(newxfader, threshold) { + return (threshold < 0 && newxfader < threshold) || (threshold > 0 && newxfader > threshold); + }; + return exports.action({ + press: function() { + var engine, newxfader; + engine = this.script.mixxx.engine; + newxfader = engine.getValue("[Master]", "crossfader"); + if (inThreshold(newxfader, threshold) || ((threshold2 != null) && inThreshold(newxfader, threshold2))) { + oldxfader = newxfader; + return engine.setValue("[Master]", "crossfader", 0); + } + }, + release: function() { + var engine; + engine = this.script.mixxx.engine; + if (oldxfader != null) { + engine.setValue("[Master]", "crossfader", oldxfader); + return oldxfader = void 0; + } + } + }); + }; + + exports.scratchEnable = function(deck, intervalsPerRev, rpm, alpha, beta, ramp) { + if (intervalsPerRev == null) { + intervalsPerRev = 128 * 4; + } + if (rpm == null) { + rpm = 44.0; + } + if (alpha == null) { + alpha = 1.0 / 8.0; + } + if (beta == null) { + beta = 1.0 / 8.0 / 32.0; + } + if (ramp == null) { + ramp = true; + } + return exports.action({ + press: function() { + var enable; + enable = this.script.mixxx.engine.scratchEnable; + return enable(deck, intervalsPerRev, rpm, alpha, beta, ramp); + }, + release: function() { + return this.script.mixxx.engine.scratchDisable(deck, ramp); + } + }); + }; + + exports.scratchTick = function(deck, transform) { + if (transform == null) { + transform = function(x) { + return x; + }; + } + return exports.call(function(ev) { + var engine; + engine = this.script.mixxx.engine; + return engine.scratchTick(deck, transform(ev.value)); + }); + }; + + exports.spinback = function() { + var args, deck; + deck = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.modifier().on('value', function() { + var ref3; + return (ref3 = this.script.mixxx.engine).spinback.apply(ref3, [deck, this.value].concat(slice.call(args))); + }); + }; + + exports.brake = function() { + var args, deck; + deck = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.modifier().on('value', function() { + var ref3; + return (ref3 = this.script.mixxx.engine).brake.apply(ref3, [deck, this.value].concat(slice.call(args))); + }); + }; + + exports.playhead = function(g) { + return exports.mapOut(g, "playposition").meter((function() { + var step; + step = 0; + return function(pos) { + var duration, engine; + engine = this.script.mixxx.engine; + duration = (function() { + switch (false) { + case !!engine.getValue(g, "play"): + return void 0; + case !(pos > .9): + return 5; + case !(pos > .8): + return 9; + case !(pos > .75): + return 13; + default: + return void 0; + } + })(); + if (duration != null) { + step = (step + 1) % duration; + if (step > duration / 2) { + return 0; + } else { + return pos * 127; + } + } else { + step = 0; + return pos * 127; + } + }; + })()); + }; + + exports.beatEffect = function(channel, type) { + var i, len, result, size, sizes; + if (type == null) { + type = ''; + } + sizes = ["0.0625", "0.125", "0.25", "0.5", "1", "2", "4", "8", "16", "32", "64"]; + result = exports.chooser({ + autoExclusive: true, + onDisable: function() { + var engine; + engine = this.script.mixxx.engine; + if (type !== 'roll' && engine.getValue(channel, "loop_enabled")) { + return engine.setValue(channel, "reloop_exit", true); + } + } + }); + for (i = 0, len = sizes.length; i < len; i++) { + size = sizes[i]; + result.add(channel, "beatloop" + type + "_" + size + "_activate", "beatloop_" + size + "_enabled"); + } + return result.select(4); + }; + + exports.stutter = function(group, beats) { + var tick; + if (beats == null) { + beats = 0.25; + } + tick = function() { + var engine, gain, newgain; + engine = this.script.mixxx.engine; + gain = engine.getValue(group, "pregain"); + newgain = gain > 0 ? (this._oldgain = gain, 0) : this._oldgain; + return engine.setValue(group, "pregain", newgain); + }; + return exports.action({ + press: function() { + var bpm, delta, engine; + engine = this.script.mixxx.engine; + bpm = engine.getValue(group, "bpm"); + delta = beats * 60000 / bpm; + if (this._timerHandle == null) { + this._timerHandle = this.script.registerHandler(bind(tick, this)); + } + return this._timerId != null ? this._timerId : this._timerId = engine.beginTimer(delta, this._timerHandle); + }, + release: function() { + var engine; + engine = this.script.mixxx.engine; + engine.stopTimer(this._timerId); + if (this._oldgain != null) { + engine.setValue(group, "pregain", this._oldgain); + } + delete this._timerId; + return delete this._oldgain; + } + }); + }; + +}).call(this); + +},{"./transform":7,"./util":8,"./value":9,"events":10,"heterarchy":13,"underscore":16}],4:[function(require,module,exports){ +// Generated by CoffeeScript 1.10.0 +(function() { + var assert, exports, konsole; + + assert = require('./util').assert; + + konsole = this; + + exports = konsole; + + if (konsole.log == null) { + konsole.log = function() { + return print("" + arguments); + }; + } + + if (konsole.info == null) { + konsole.info = konsole.log; + } + + if (konsole.warn == null) { + konsole.warn = konsole.log; + } + + if (konsole.error == null) { + konsole.error = konsole.log; + } + + if (konsole.time == null) { + konsole.time = function() { + return assert(False, "time not implemented in konsole"); + }; + } + + if (konsole.timeEnd == null) { + konsole.timeEnd = function() { + return assert(False, "time not implemented in konsole"); + }; + } + + if (konsole.trace == null) { + konsole.trace = function() { + var err; + err = new Error(); + err.name = "Trace"; + err.message = "" + arguments; + return konsole.error(err.stack); + }; + } + + if (konsole.dir == null) { + konsole.dir = function() { + return konsole.log(object + "\n"); + }; + } + + if (konsole.assert == null) { + konsole.assert = assert; + } + +}).call(this); + +},{"./util":8}],5:[function(require,module,exports){ +// Generated by CoffeeScript 1.10.0 +(function() { + var MIDI_CC, MIDI_NOTE_OFF, MIDI_NOTE_ON, MIDI_PITCHBEND, assert, behaviour, ccIds, event, extend, factory, hexStr, indent, joinLn, midiId, multi, noteIds, noteOnIds, pbIds, ref, ref1, some, xmlTag, + slice = [].slice, + extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + multi = require('heterarchy').multi; + + ref = require('./util'), indent = ref.indent, hexStr = ref.hexStr, assert = ref.assert, factory = ref.factory, xmlTag = ref.xmlTag, joinLn = ref.joinLn; + + behaviour = require('./behaviour'); + + ref1 = require('underscore'), some = ref1.some, extend = ref1.extend; + + exports.MIDI_NOTE_ON = MIDI_NOTE_ON = 0x9; + + exports.MIDI_NOTE_OFF = MIDI_NOTE_OFF = 0x8; + + exports.MIDI_CC = MIDI_CC = 0xB; + + exports.MIDI_PITCHBEND = MIDI_PITCHBEND = 0xE; + + midiId = function(message, midino, channel) { + if (message == null) { + message = MIDI_CC; + } + if (midino == null) { + midino = 0; + } + if (channel == null) { + channel = 0; + } + return { + message: message, + midino: midino, + channel: channel, + status: function() { + return (this.message << 4) | this.channel; + }, + configMidi: function(depth) { + return (indent(depth)) + "" + (hexStr(this.status())) + "\n" + (indent(depth)) + "" + (hexStr(this.midino)) + ""; + } + }; + }; + + exports.midiId = midiId; + + pbIds = function() { + return [midiId.apply(null, [MIDI_PITCHBEND, 0].concat(slice.call(arguments)))]; + }; + + noteOnIds = function() { + return [midiId.apply(null, [MIDI_NOTE_ON].concat(slice.call(arguments)))]; + }; + + noteIds = function() { + return [midiId.apply(null, [MIDI_NOTE_ON].concat(slice.call(arguments))), midiId.apply(null, [MIDI_NOTE_OFF].concat(slice.call(arguments)))]; + }; + + ccIds = function() { + return [midiId.apply(null, [MIDI_CC].concat(slice.call(arguments)))]; + }; + + exports.pbIds = pbIds; + + exports.noteOnIds = noteOnIds; + + exports.noteIds = noteIds; + + exports.ccIds = ccIds; + + exports.event = event = function(channel, control, value, status, group) { + return { + channel: channel, + control: control, + value: (function() { + switch (status >> 4) { + case MIDI_PITCHBEND: + return (value * 128.0 + control) / 128.0; + default: + return value; + } + })(), + status: status, + group: group, + message: function() { + return this.status >> 4; + }, + pressed: status >> 4 !== MIDI_NOTE_OFF && value + }; + }; + + exports.Control = (function(superClass) { + extend1(Control, superClass); + + function Control() { + var args, ids; + ids = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this.ids = ids != null ? ids : [midiId()]; + this["else"] = (function(_this) { + return function() { + return _this._else.apply(_this, arguments); + }; + })(this); + this["else"].when = (function(_this) { + return function() { + return _this._elseWhen.apply(_this, arguments); + }; + })(this); + this.else_ = this["else"]; + Control.__super__.constructor.call(this); + if (!(this.ids instanceof Array)) { + this.ids = ccIds.apply(null, [this.ids].concat(slice.call(args))); + } + this._behaviours = []; + if (typeof this._controlRegistry === "function") { + this._controlRegistry(this); + } + } + + Control.prototype.does = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit); + this._behaviours.push(this.registerBehaviour(behaviour.toBehaviour.apply(behaviour, args))); + return this; + }; + + Control.prototype.when = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit); + this._lastWhen = behaviour.when.apply(behaviour, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + return this; + }; + + Control.prototype._elseWhen = function() { + var args, ref2; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastWhen != null, "'elseWhen' must be preceded by 'when' or 'elseWhen'"); + this._lastWhen = (ref2 = this._lastWhen["else"]).when.apply(ref2, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + return this; + }; + + Control.prototype._else = function() { + var args, ref2; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastWhen != null, "'else' must be preceded by 'when' or 'elseWhen'"); + this._lastWhen = (ref2 = this._lastWhen)["else"].apply(ref2, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + this._lastWhen = void 0; + return this; + }; + + Control.prototype.init = function(script) { + var b, i, len, ref2; + this.script = script; + assert(!this._isInit); + ref2 = this._behaviours; + for (i = 0, len = ref2.length; i < len; i++) { + b = ref2[i]; + b.enable(script, this); + } + return this._isInit = true; + }; + + Control.prototype.shutdown = function(script) { + var b, i, len, ref2; + assert(script === this.script); + assert(this._isInit); + ref2 = this._behaviours; + for (i = 0, len = ref2.length; i < len; i++) { + b = ref2[i]; + b.disable(script, this); + } + this._isInit = false; + return delete this.script; + }; + + Control.prototype.registerBehaviour = function(b) { + return b; + }; + + Control.prototype.configInputs = function(depth, script) {}; + + Control.prototype.configOutputs = function(depth, script) {}; + + Control.prototype.setRegistry = function(registry) { + assert((this._controlRegistry == null) || (registry == null)); + return this._controlRegistry = registry; + }; + + return Control; + + })(behaviour.Actor); + + exports.InControl = (function(superClass) { + extend1(InControl, superClass); + + function InControl() { + return InControl.__super__.constructor.apply(this, arguments); + } + + InControl.prototype.init = function(script) { + InControl.__super__.init.apply(this, arguments); + if (this.needsHandler()) { + return script.registerHandler(((function(_this) { + return function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return _this.emit('event', event.apply(null, args)); + }; + })(this)), this.handlerId()); + } + }; + + InControl.prototype.option = function() { + var beh, i, len, options, ref2, ref3; + options = 1 <= arguments.length ? slice.call(arguments, 0) : []; + (ref2 = (this._options != null ? this._options : this._options = [])).push.apply(ref2, options); + ref3 = this._behaviours; + for (i = 0, len = ref3.length; i < len; i++) { + beh = ref3[i]; + beh.option.apply(beh, options); + } + return this; + }; + + InControl.property('options', function() { + return behaviour.makeOptionsChooser(this); + }); + + InControl.prototype.registerBehaviour = function(beh) { + if (this._options != null) { + beh.option.apply(beh, this._options); + } + return beh; + }; + + InControl.prototype.needsHandler = function() { + return this._behaviours.length !== 1 || !this._behaviours[0].directInMapping() || some(this._behaviours[0]._options, function(opt) { + return !opt.name; + }); + }; + + InControl.prototype.handlerId = function() { + return "x" + (this.ids[0].status().toString(16)) + "_x" + (this.ids[0].midino.toString(16)); + }; + + InControl.prototype.configInputs = function(depth, script) { + var id, mapping; + if (this.needsHandler()) { + mapping = { + group: "[Master]", + key: script.handlerKey(this.handlerId()) + }; + } else { + mapping = this._behaviours[0].directInMapping(); + } + return joinLn((function() { + var i, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + results.push(this.configInMapping(depth, mapping, id)); + } + return results; + }).call(this)); + }; + + InControl.prototype.configInMapping = function(depth, mapping, id) { + return (indent(depth)) + "\n" + (indent(depth + 1)) + "" + mapping.group + "\n" + (indent(depth + 1)) + "" + mapping.key + "\n" + (id.configMidi(depth + 1)) + "\n" + (indent(depth + 1)) + "\n" + (this.configOptions(depth + 2)) + "\n" + (indent(depth + 1)) + "\n" + (indent(depth)) + ""; + }; + + InControl.prototype.configOptions = function(depth) { + var opt, ref2; + if (this.needsHandler()) { + return (indent(depth)) + ""; + } else if (((ref2 = this._behaviours[0]._options) != null ? ref2.length : void 0) > 0) { + return joinLn((function() { + var i, len, ref3, results; + ref3 = this._behaviours[0]._options; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (opt.name != null) { + results.push((indent(depth)) + "<" + opt.name + "/>"); + } else { + results.push(void 0); + } + } + return results; + }).call(this)); + } else { + return (indent(depth)) + ""; + } + }; + + return InControl; + + })(exports.Control); + + exports.OutControl = (function(superClass) { + extend1(OutControl, superClass); + + function OutControl() { + OutControl.__super__.constructor.apply(this, arguments); + this._states = { + on: 0x7f, + off: 0x00, + disable: 0x00 + }; + } + + OutControl.prototype.send = function(state) { + return this.doSend(state); + }; + + OutControl.prototype.states = function(states) { + extend(this._states, states); + return this; + }; + + OutControl.prototype.doSend = function(state) { + var i, id, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + if (id.message !== MIDI_NOTE_OFF) { + if (state in this._states) { + results.push(this.script.mixxx.midi.sendShortMsg(id.status(), id.midino, this._states[state])); + } else { + results.push(this.script.mixxx.midi.sendShortMsg(id.status(), id.midino, state)); + } + } else { + results.push(void 0); + } + } + return results; + }; + + OutControl.prototype.init = function() { + if (!this.needsSend()) { + this.send = void 0; + } + return OutControl.__super__.init.apply(this, arguments); + }; + + OutControl.prototype.shutdown = function() { + this.doSend('disable'); + return OutControl.__super__.shutdown.apply(this, arguments); + }; + + OutControl.prototype.needsSend = function() { + return this._behaviours.length !== 1 || !this._behaviours[0].directOutMapping(); + }; + + OutControl.prototype.configOutputs = function(depth, script) { + var id, mapping; + mapping = !this.needsSend() && this._behaviours[0].directOutMapping(); + if (mapping) { + return joinLn((function() { + var i, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + results.push(this.configOutMapping(depth, mapping, id)); + } + return results; + }).call(this)); + } + }; + + OutControl.prototype.configOutMapping = function(depth, mapping, id) { + var options; + if (id.message !== MIDI_NOTE_OFF) { + options = joinLn([xmlTag('minimum', mapping.minimum, depth + 1), xmlTag('maximum', mapping.maximum, depth + 1)]); + return (indent(depth)) + "\n" + (indent(depth + 1)) + "" + mapping.group + "\n" + (indent(depth + 1)) + "" + mapping.key + "\n" + (id.configMidi(depth + 1)) + "\n" + (indent(depth + 1)) + "" + (hexStr(this._states['on'])) + "\n" + (indent(depth + 1)) + "" + (hexStr(this._states['off'])) + "\n" + options + "\n" + (indent(depth)) + ""; + } + }; + + return OutControl; + + })(exports.Control); + + exports.input = factory(exports.InControl); + + exports.output = factory(exports.OutControl); + + exports.InOutControl = (function(superClass) { + extend1(InOutControl, superClass); + + function InOutControl() { + return InOutControl.__super__.constructor.apply(this, arguments); + } + + return InOutControl; + + })(multi(exports.InControl, exports.OutControl)); + + exports.control = factory(exports.InOutControl); + +}).call(this); + +},{"./behaviour":3,"./util":8,"heterarchy":13,"underscore":16}],6:[function(require,module,exports){ +(function (process){ +// Generated by CoffeeScript 1.10.0 +(function() { + var Control, S, _, assert, basename, bind, catching, flatten, indent, issubclass, mro, ref, ref1, ref2, xmlEscape, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, + slice = [].slice; + + ref = require('underscore'), flatten = ref.flatten, bind = ref.bind; + + ref1 = require('heterarchy'), issubclass = ref1.issubclass, mro = ref1.mro; + + Control = require('./control').Control; + + ref2 = require('./util'), indent = ref2.indent, xmlEscape = ref2.xmlEscape, catching = ref2.catching, assert = ref2.assert; + + require('./console'); + + basename = require('path').basename; + + S = require('string'); + + _ = require('underscore'); + + exports.nameFromFilename = function(fname) { + var extensions, name; + extensions = [".mixco.coffee", ".mixco.litcoffee", ".mixco.js", ".mixco"]; + fname = basename(fname); + assert(_.some(extensions, function(x) { + return S(fname).endsWith(x); + }), "Script file name: " + fname + " must end in one of: " + extensions); + name = extensions.reduce((function(fname, ext) { + return fname.replace(ext, ""); + }), fname); + assert(name.match(/^[a-zA-Z_$][0-9a-zA-Z_$].*$/, "Script name must be a valid JavaScript identifier")); + return name; + }; + + exports.register = function(targetModule, scriptTypeOrDefinition) { + var instance, name, scriptType; + name = targetModule.filename != null ? exports.nameFromFilename(targetModule.filename) : typeof MIXCO_SCRIPT_FILENAME !== "undefined" && MIXCO_SCRIPT_FILENAME !== null ? exports.nameFromFilename(MIXCO_SCRIPT_FILENAME) : assert(false, "Invalid script"); + scriptType = issubclass(scriptTypeOrDefinition, exports.Script) ? scriptTypeOrDefinition : exports.create(scriptTypeOrDefinition); + instance = new scriptType; + instance.__registeredName = name; + targetModule.exports[name] = instance; + if (targetModule === require.main) { + return instance.main(); + } + }; + + exports.create = function(scriptDefinition) { + var NewScript, constructor, init, k, shutdown, special, v; + assert(scriptDefinition.constructor != null, "Script definition must have a constructor"); + constructor = scriptDefinition.constructor, init = scriptDefinition.init, shutdown = scriptDefinition.shutdown; + NewScript = (function(superClass) { + extend(NewScript, superClass); + + function NewScript() { + NewScript.__super__.constructor.apply(this, arguments); + try { + Control.prototype.setRegistry(bind(this.add, this)); + constructor.apply(this, arguments); + } finally { + Control.prototype.setRegistry(null); + } + this; + } + + NewScript.prototype.init = function() { + var ref3; + if ((ref3 = this.preinit) != null) { + ref3.apply(this, arguments); + } + NewScript.__super__.init.apply(this, arguments); + return init != null ? init.apply(this, arguments) : void 0; + }; + + NewScript.prototype.shutdown = function() { + var ref3; + if (shutdown != null) { + shutdown.apply(this, arguments); + } + NewScript.__super__.shutdown.apply(this, arguments); + return (ref3 = this.postshutdown) != null ? ref3.apply(this, arguments) : void 0; + }; + + return NewScript; + + })(exports.Script); + special = ['name', 'constructor', 'init', 'shutdown']; + for (k in scriptDefinition) { + v = scriptDefinition[k]; + if (indexOf.call(special, k) < 0) { + NewScript.prototype[k] = v; + } + } + return NewScript; + }; + + exports.Script = (function() { + Script.prototype.info = { + name: "[mixco] Generic Script", + author: "Juan Pedro Bolivar Puente ", + description: "", + forums: "", + wiki: "" + }; + + Script.property('name', { + get: function() { + assert(this.__registeredName, "Script must be registered"); + return this.__registeredName; + } + }); + + Script.prototype.add = function() { + var controls, ref3; + controls = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit, "Can only add controls in constructor"); + return (ref3 = this.controls).push.apply(ref3, flatten(controls)); + }; + + Script.prototype.init = catching(function() { + var control, i, len, ref3, results; + this._isInit = true; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.init(this)); + } + return results; + }); + + Script.prototype.shutdown = catching(function() { + var control, i, len, ref3; + ref3 = this.controls; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + control.shutdown(this); + } + return delete this._isInit; + }); + + function Script() { + this.controls = []; + } + + Script.prototype.mixxx = { + engine: (typeof engine !== "undefined" && engine !== null ? engine : void 0), + midi: (typeof midi !== "undefined" && midi !== null ? midi : void 0), + script: (typeof script !== "undefined" && script !== null ? script : void 0) + }; + + Script.prototype.main = function() { + var arg, i, len, ref3, results; + ref3 = process.argv; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + arg = ref3[i]; + if (arg === '-h' || arg === '--help') { + console.info(this.help()); + break; + } + if (arg === '-g' || arg === '--generate-config') { + console.info(this.config()); + break; + } else { + results.push(void 0); + } + } + return results; + }; + + Script.prototype.help = function() { + return "Mixxx Controller Script\n=======================\n\nName: " + this.info.name + "\nAuthor: " + this.info.author + "\nDescription: " + this.info.description + "\nForums: " + this.info.description + "\n\nUsage\n-----\n1. Generate Mixxx config:\n coffee " + this.name + ".coffee -g > " + this.name + ".xml\n\n2. Generate Mixxx script:\n coffee -c " + this.name + ".coffee"; + }; + + Script.prototype.config = function() { + return "\n\n" + (indent(1)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.name)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.author)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.description)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.wiki)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.forums)) + "\n" + (indent(1)) + "\n" + (indent(1)) + "\n" + (indent(2)) + "\n" + (indent(3)) + "\n" + (indent(2)) + "\n" + (indent(2)) + "\n" + (this.configInputs(3)) + "\n" + (indent(2)) + "\n" + (indent(2)) + "\n" + (this.configOutputs(3)) + "\n" + (indent(2)) + "\n" + (indent(1)) + "\n"; + }; + + Script.prototype.configInputs = function(depth) { + var control; + return ((function() { + var i, len, ref3, results; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.configInputs(depth, this)); + } + return results; + }).call(this)).filter(function(x) { + return x; + }).join('\n'); + }; + + Script.prototype.configOutputs = function(depth) { + var control; + return ((function() { + var i, len, ref3, results; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.configOutputs(depth, this)); + } + return results; + }).call(this)).filter(function(x) { + return x; + }).join('\n'); + }; + + Script.prototype._nextCallbackId = 1; + + Script.prototype.registerHandler = function(callback, id) { + var handlerName; + if (id == null) { + id = void 0; + } + id || (id = this._nextCallbackId++); + handlerName = "__handle_" + id; + assert(!this[handlerName], "Handlers can be registered only once (" + handlerName + ")"); + this[handlerName] = callback; + return this.handlerKey(id); + }; + + Script.prototype.handlerKey = function(id) { + if (id == null) { + id = void 0; + } + if (id == null) { + id = this._nextCallbackId - 1; + } + return this.name + ".__handle_" + id; + }; + + return Script; + + })(); + +}).call(this); + +}).call(this,require('_process')) +},{"./console":4,"./control":5,"./util":8,"_process":12,"heterarchy":13,"path":11,"string":15,"underscore":16}],7:[function(require,module,exports){ +// Generated by CoffeeScript 1.10.0 +(function() { + var binaryT, centeredT, defaultT, identityT, linearT, momentaryT, + slice = [].slice; + + exports.identity = function(v) { + return v; + }; + + exports.identity.inverse = exports.identity; + + exports.momentary = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } + }; + + exports.momentary.inverse = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } + }; + + exports.binary = function(v, oldv) { + if (v > 0) { + return !oldv; + } else { + return null; + } + }; + + exports.binary.inverse = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } + }; + + exports.linear = function(v, min, max) { + return min + v * (max - min); + }; + + exports.linear.inverse = function(v, min, max) { + return (v - min) / (max - min); + }; + + exports.centered = function(v, min, center, max) { + if (v < .5) { + return linear(v * 2, min, center); + } else { + return linear((v - .5) * 2, center, max); + } + }; + + exports.centered.inverse = function(v, min, center, max) { + if (v < center) { + return 0.5 * linear.inverse(v, min, center); + } else { + return 0.5 + 0.5 * linear.inverse(v, center, max); + } + }; + + exports.transform = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.value / 127.0].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return 127 * f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; + }; + + exports.transformI = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.value].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; + }; + + exports.transformB = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.pressed / 127.0].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return 127 * f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; + }; + + exports.identityT = identityT = exports.transformI(exports.identity); + + exports.momentaryT = momentaryT = exports.transformB(exports.momentary); + + exports.binaryT = binaryT = exports.transformB(exports.binary); + + exports.linearT = linearT = function() { + return exports.transform.apply(exports, [exports.linear].concat(slice.call(arguments))); + }; + + exports.centeredT = centeredT = function() { + return exports.transform.apply(exports, [exports.centered].concat(slice.call(arguments))); + }; + + exports.defaultT = defaultT = linearT(0.0, 1.0); + + exports.mappings = { + "beatloop_0.0625_activate": momentaryT, + "beatloop_0.0625_toggle": momentaryT, + "beatloop_0.125_activate": momentaryT, + "beatloop_0.125_toggle": momentaryT, + "beatloop_0.5_activate": momentaryT, + "beatloop_0.5_toggle": momentaryT, + "beatlooproll_0.0625_activate": momentaryT, + "beatlooproll_0.125_activate": momentaryT, + "beatlooproll_0.5_activate": momentaryT, + back: momentaryT, + balance: linearT(-1.0, 1.0), + beatloop_16_activate: momentaryT, + beatloop_16_toggle: momentaryT, + beatloop_1_activate: momentaryT, + beatloop_1_toggle: momentaryT, + beatloop_2_activate: momentaryT, + beatloop_2_toggle: momentaryT, + beatloop_32_activate: momentaryT, + beatloop_32_toggle: momentaryT, + beatloop_4_activate: momentaryT, + beatloop_4_toggle: momentaryT, + beatloop_8_activate: momentaryT, + beatloop_8_toggle: momentaryT, + beatlooproll_16_activate: momentaryT, + beatlooproll_1_activate: momentaryT, + beatlooproll_2_activate: momentaryT, + beatlooproll_32_activate: momentaryT, + beatlooproll_4_activate: momentaryT, + beatlooproll_8_activate: momentaryT, + beatloop_double: momentaryT, + beatloop_halve: momentaryT, + beatjump_4_forward: momentaryT, + beatjump_4_backward: momentaryT, + beatjump_1_forward: momentaryT, + beatjump_1_backward: momentaryT, + beats_translate_curpos: momentaryT, + beatsync: momentaryT, + beatsync_tempo: momentaryT, + crossfader: linearT(-1.0, 1.0), + cue_default: momentaryT, + eject: momentaryT, + enabled: binaryT, + filterHigh: centeredT(0.0, 1.0, 4.0), + filterHighKill: binaryT, + filterLow: centeredT(0.0, 1.0, 4.0), + filterLowKill: binaryT, + filterMid: centeredT(0.0, 1.0, 4.0), + filterMidKill: binaryT, + fwd: momentaryT, + headMix: centeredT(-1.0, 1.0), + headVolume: centeredT(0.0, 1.0, 5.0), + hotcue_1_activate: momentaryT, + hotcue_1_clear: momentaryT, + hotcue_2_activate: momentaryT, + hotcue_2_clear: momentaryT, + hotcue_3_activate: momentaryT, + hotcue_3_clear: momentaryT, + hotcue_4_activate: momentaryT, + hotcue_4_clear: momentaryT, + hotcue_5_activate: momentaryT, + hotcue_5_clear: momentaryT, + hotcue_6_activate: momentaryT, + hotcue_6_clear: momentaryT, + hotcue_7_activate: momentaryT, + hotcue_7_clear: momentaryT, + jog: identityT, + keylock: binaryT, + lfoDelay: linearT(50.0, 10000.0), + lfoDepth: defaultT, + lfoPeriod: linearT(50000.0, 2000000.0), + LoadSelectedTrack: momentaryT, + loop_double: momentaryT, + loop_enabled: binaryT, + loop_end_position: linearT, + loop_halve: momentaryT, + loop_in: momentaryT, + loop_out: momentaryT, + loop_start_position: linearT, + play: binaryT, + playposition: linearT(0.0, 1.0), + plf: binaryT, + pregain: centeredT(0.0, 1.0, 4.0), + pregain_toggle: binaryT, + rate: linearT(-1.0, 1.0), + rate_temp_down: momentaryT, + rate_temp_down_small: momentaryT, + rate_temp_up: momentaryT, + rate_temp_up_small: momentaryT, + reverse: binaryT, + scratch2: linearT(-3.0, 3.0), + scratch2_enable: binaryT, + SelectNextPlaylist: momentaryT, + SelectNextTrack: momentaryT, + SelectPrevPlaylist: momentaryT, + SelectPrevTrack: momentaryT, + SelectTrackKnob: identityT, + slip_enabled: binaryT, + super1: linearT(0.0, 10.0), + talkover: binaryT, + ToggleSelectedSidebarItem: momentaryT, + volume: defaultT, + VuMeter: defaultT, + VuMeterL: defaultT, + VuMeterR: defaultT, + wheel: linearT(-3.0, 3.0) + }; + +}).call(this); + +},{}],8:[function(require,module,exports){ +// Generated by CoffeeScript 1.10.0 +(function() { + Function.prototype.property = function(prop, desc) { + if (desc instanceof Function) { + desc = { + get: desc + }; + } + return Object.defineProperty(this.prototype, prop, desc); + }; + + Number.prototype.clamp = function(min, max) { + return Math.min(Math.max(this, min), max); + }; + + Number.prototype.sign = function() { + if (this < 0) { + return -1; + } else { + return 1; + } + }; + + Array.prototype.equals = function(other) { + return this.length === other.length && this.every(function(elem, i) { + return elem === other[i]; + }); + }; + + exports.copy = function(a, b) { + var k, v; + if (b == null) { + b = {}; + } + for (k in a) { + v = a[k]; + b[k] = v; + } + return b; + }; + + exports.catching = function(f) { + return function() { + var err, error1; + try { + return f.apply(this, arguments); + } catch (error1) { + err = error1; + return console.log("ERROR: " + err); + } + }; + }; + + exports.assert = function(value, error) { + if (error == null) { + error = void 0; + } + if (!value) { + throw new Error(error != null ? error : "Assertion failed"); + } + }; + + exports.xmlEscape = function(str) { + var ref; + return (ref = str != null ? str.replace('&', '&').replace('"', '"').replace('>', '>').replace('<', '<') : void 0) != null ? ref : ''; + }; + + exports.indent = function(depth) { + return Array(depth * 4).join(" "); + }; + + exports.hexStr = function(number) { + return "0x" + (number.toString(16)); + }; + + exports.xmlTag = function(str, value, indent) { + if (indent == null) { + indent = 0; + } + if (value != null) { + return (exports.indent(indent)) + "<" + str + ">" + value + ""; + } else { + return ""; + } + }; + + exports.joinLn = function(lines) { + return lines.filter(function(x) { + return x; + }).join('\n'); + }; + + exports.factory = function(Klass) { + return function() { + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(Klass, arguments, function(){}); + }; + }; + +}).call(this); + +},{}],9:[function(require,module,exports){ +// Generated by CoffeeScript 1.10.0 +(function() { + var events, factory, util, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + slice = [].slice; + + events = require('events'); + + util = require('./util'); + + factory = util.factory; + + exports.Value = (function(superClass) { + extend(Value, superClass); + + function Value(arg) { + var initial; + initial = (arg != null ? arg : {}).initial; + Value.__super__.constructor.apply(this, arguments); + this.setMaxListeners(0); + if (initial != null) { + this.value = initial; + } + } + + Value.property('value', { + get: function() { + return this._value; + }, + set: function(newValue) { + return this.setValue(newValue); + } + }); + + Value.prototype.setValue = function(newValue) { + if (this._value !== newValue) { + this._value = newValue; + this.emit('value', newValue); + } + return this._value; + }; + + return Value; + + })(events.EventEmitter); + + exports.value = factory(exports.Value); + + exports.Const = (function() { + Const.prototype.value = void 0; + + function Const(initial) { + if (initial == null) { + initial = void 0; + } + this.value = initial; + } + + Const.prototype.on = function() {}; + + Const.prototype.addListener = function() {}; + + Const.prototype.removeListener = function() {}; + + Const.prototype.listeners = function() { + return []; + }; + + return Const; + + })(); + + exports["const"] = factory(exports.Const); + + exports.Reduce = (function(superClass) { + extend(Reduce, superClass); + + function Reduce() { + var i, len, reduced, reducer, ref, v; + reducer = arguments[0], reduced = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this.reducer = reducer; + this.reduced = reduced; + Reduce.__super__.constructor.call(this); + ref = this.reduced; + for (i = 0, len = ref.length; i < len; i++) { + v = ref[i]; + v.on('value', (function(_this) { + return function() { + return _this.update(); + }; + })(this)); + } + this.update(); + } + + Reduce.prototype.update = function() { + return this.value = this.reduced.reduce((function(_this) { + return function(a, b) { + return exports["const"](_this.reducer(a.value, b.value)); + }; + })(this)).value; + }; + + return Reduce; + + })(exports.Value); + + exports.reduce = factory(exports.Reduce); + + exports.and = function() { + return exports.reduce.apply(exports, [(function(a, b) { + return a && b; + })].concat(slice.call(arguments))); + }; + + exports.or = function() { + return exports.reduce.apply(exports, [(function(a, b) { + return a || b; + })].concat(slice.call(arguments))); + }; + + exports.Transform = (function(superClass) { + extend(Transform, superClass); + + function Transform(transformer, transformed) { + this.transformer = transformer; + this.transformed = transformed; + Transform.__super__.constructor.call(this); + this.transformed.on('value', (function(_this) { + return function() { + return _this.update(); + }; + })(this)); + this.update(); + } + + Transform.prototype.update = function() { + return this.value = this.transformer(this.transformed.value); + }; + + return Transform; + + })(exports.Value); + + exports.transform = factory(exports.Transform); + + exports.not = function() { + return exports.transform.apply(exports, [(function(a) { + return !a; + })].concat(slice.call(arguments))); + }; + +}).call(this); + +},{"./util":8,"events":10}],10:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +},{}],11:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// resolves . and .. elements in a path array with directory names there +// must be no slashes, empty elements, or device names (c:\) in the array +// (so also no leading and trailing slashes - it does not distinguish +// relative and absolute paths) +function normalizeArray(parts, allowAboveRoot) { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + + return parts; +} + +// Split a filename into [root, dir, basename, ext], unix version +// 'root' is just a slash, or nothing. +var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; +var splitPath = function(filename) { + return splitPathRe.exec(filename).slice(1); +}; + +// path.resolve([from ...], to) +// posix version +exports.resolve = function() { + var resolvedPath = '', + resolvedAbsolute = false; + + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? arguments[i] : process.cwd(); + + // Skip empty and invalid entries + if (typeof path !== 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + continue; + } + + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path.charAt(0) === '/'; + } + + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + + // Normalize the path + resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { + return !!p; + }), !resolvedAbsolute).join('/'); + + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; +}; + +// path.normalize(path) +// posix version +exports.normalize = function(path) { + var isAbsolute = exports.isAbsolute(path), + trailingSlash = substr(path, -1) === '/'; + + // Normalize the path + path = normalizeArray(filter(path.split('/'), function(p) { + return !!p; + }), !isAbsolute).join('/'); + + if (!path && !isAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + + return (isAbsolute ? '/' : '') + path; +}; + +// posix version +exports.isAbsolute = function(path) { + return path.charAt(0) === '/'; +}; + +// posix version +exports.join = function() { + var paths = Array.prototype.slice.call(arguments, 0); + return exports.normalize(filter(paths, function(p, index) { + if (typeof p !== 'string') { + throw new TypeError('Arguments to path.join must be strings'); + } + return p; + }).join('/')); +}; + + +// path.relative(from, to) +// posix version +exports.relative = function(from, to) { + from = exports.resolve(from).substr(1); + to = exports.resolve(to).substr(1); + + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + + var end = arr.length - 1; + for (; end >= 0; end--) { + if (arr[end] !== '') break; + } + + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + + var fromParts = trim(from.split('/')); + var toParts = trim(to.split('/')); + + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + + return outputParts.join('/'); +}; + +exports.sep = '/'; +exports.delimiter = ':'; + +exports.dirname = function(path) { + var result = splitPath(path), + root = result[0], + dir = result[1]; + + if (!root && !dir) { + // No dirname whatsoever + return '.'; + } + + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.substr(0, dir.length - 1); + } + + return root + dir; +}; + + +exports.basename = function(path, ext) { + var f = splitPath(path)[2]; + // TODO: make this comparison case-insensitive on windows? + if (ext && f.substr(-1 * ext.length) === ext) { + f = f.substr(0, f.length - ext.length); + } + return f; +}; + + +exports.extname = function(path) { + return splitPath(path)[3]; +}; + +function filter (xs, f) { + if (xs.filter) return xs.filter(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (f(xs[i], i, xs)) res.push(xs[i]); + } + return res; +} + +// String.prototype.substr - negative index don't work in IE8 +var substr = 'ab'.substr(-1) === 'b' + ? function (str, start, len) { return str.substr(start, len) } + : function (str, start, len) { + if (start < 0) start = str.length + start; + return str.substr(start, len); + } +; + +}).call(this,require('_process')) +},{"_process":12}],12:[function(require,module,exports){ +// shim for using process in browser +var process = module.exports = {}; + +// cached from whatever global is present so that test runners that stub it +// don't break things. But we need to wrap it in a try catch in case it is +// wrapped in strict mode code which doesn't define any globals. It's inside a +// function because try/catches deoptimize in certain engines. + +var cachedSetTimeout; +var cachedClearTimeout; + +function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); +} +function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); +} +(function () { + try { + if (typeof setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } else { + cachedSetTimeout = defaultSetTimout; + } + } catch (e) { + cachedSetTimeout = defaultSetTimout; + } + try { + if (typeof clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } else { + cachedClearTimeout = defaultClearTimeout; + } + } catch (e) { + cachedClearTimeout = defaultClearTimeout; + } +} ()) +function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + +} +function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + +} +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; + +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); +} + +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],13:[function(require,module,exports){ +// Generated by CoffeeScript 1.9.3 +(function() { + var assert, copyOwn, every, find, generate, head, hierarchy, inherited, isEmpty, isEqual, isJavaScriptClass, map, memoize, merge, mro, partial, ref, reject, reparent, some, tail, without, + slice = [].slice, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; + + ref = require('underscore'), head = ref.head, tail = ref.tail, map = ref.map, find = ref.find, some = ref.some, without = ref.without, isEmpty = ref.isEmpty, every = ref.every, memoize = ref.memoize, reject = ref.reject, partial = ref.partial, isEqual = ref.isEqual; + + assert = function(value, error) { + if (error == null) { + error = void 0; + } + if (!value) { + throw new Error(error != null ? error : "Assertion failed"); + } + }; + + exports.multi = function() { + var bases; + bases = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return generate(merge(map(bases, mro).concat([bases]))); + }; + + generate = memoize(function(linearization) { + var next, result; + next = head(linearization); + if (isEqual(linearization, hierarchy(next))) { + return next; + } else { + return result = (function(superClass) { + var class1; + + extend(result, superClass); + + function result() { + return class1.apply(this, arguments); + } + + result.prototype.__mro__ = linearization; + + class1 = reparent(next, result, next.prototype.constructor); + + copyOwn(next, result); + + copyOwn(next.prototype, result.prototype, partial(reparent, next, result)); + + return result; + + })(generate(tail(linearization))); + } + }); + + copyOwn = function(from, to, project) { + var key, value; + if (project == null) { + project = function(x) { + return x; + }; + } + for (key in from) { + if (!hasProp.call(from, key)) continue; + value = from[key]; + if (!to.hasOwnProperty(key)) { + to[key] = project(value); + } + } + return to; + }; + + reparent = function(oldklass, newklass, value) { + var newsuper, oldsuper, superctor; + if (!(value instanceof Function)) { + return value; + } else if (value === oldklass.prototype.constructor && inherited(oldklass) === Object) { + superctor = inherited(newklass).prototype.constructor; + return function() { + superctor.apply(this, arguments); + return value.apply(this, arguments); + }; + } else { + newsuper = inherited(newklass).prototype; + oldsuper = oldklass.__super__; + return function() { + oldklass.__super__ = newsuper; + try { + return value.apply(this, arguments); + } finally { + oldklass.__super__ = oldsuper; + } + }; + } + }; + + merge = function(inputs) { + var next, results; + results = []; + while (!isEmpty(inputs)) { + next = find(map(inputs, head), function(candidate) { + return every(inputs, function(input) { + return indexOf.call(tail(input), candidate) < 0; + }); + }); + assert(next != null, "Inconsistent multiple inheritance"); + inputs = reject(map(inputs, function(lst) { + return without(lst, next); + }), isEmpty); + results.push(next); + } + return results; + }; + + isJavaScriptClass = function(cls) { + return cls === Array || cls === Boolean || cls === Date || cls === Error || cls === Function || cls === Number || cls === RegExp || cls === String || cls === Object; + }; + + exports.mro = mro = function(cls) { + var result; + if ((cls == null) || (cls.prototype == null)) { + return []; + } else if (!cls.prototype.hasOwnProperty('__mro__')) { + result = [cls].concat(mro(inherited(cls))); + if (!isJavaScriptClass(cls)) { + cls.prototype.__mro__ = result; + } + return result; + } else { + return cls.prototype.__mro__; + } + }; + + exports.inherited = inherited = function(cls) { + var ref1; + return (ref1 = Object.getPrototypeOf(cls.prototype)) != null ? ref1.constructor : void 0; + }; + + exports.hierarchy = hierarchy = function(cls) { + if (cls == null) { + return []; + } else { + return [cls].concat(hierarchy(inherited(cls))); + } + }; + + exports.isinstance = function() { + var classes, obj; + obj = arguments[0], classes = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.issubclass.apply(exports, [obj != null ? obj.constructor : void 0].concat(slice.call(classes))); + }; + + exports.issubclass = function() { + var classes, klass, linearization; + klass = arguments[0], classes = 2 <= arguments.length ? slice.call(arguments, 1) : []; + linearization = mro(klass); + return some(classes, function(cls) { + return indexOf.call(linearization, cls) >= 0; + }); + }; + +}).call(this); + +},{"underscore":16}],14:[function(require,module,exports){ +function count(self, substr) { + var count = 0 + var pos = self.indexOf(substr) + + while (pos >= 0) { + count += 1 + pos = self.indexOf(substr, pos + 1) + } + + return count +} + +module.exports = count +},{}],15:[function(require,module,exports){ +/* +string.js - Copyright (C) 2012-2014, JP Richardson +*/ + +!(function() { + "use strict"; + + var VERSION = '3.1.3'; + + var ENTITIES = {}; + + // from http://semplicewebsites.com/removing-accents-javascript + var latin_map={"Á":"A","Ă":"A","Ắ":"A","Ặ":"A","Ằ":"A","Ẳ":"A","Ẵ":"A","Ǎ":"A","Â":"A","Ấ":"A","Ậ":"A","Ầ":"A","Ẩ":"A","Ẫ":"A","Ä":"A","Ǟ":"A","Ȧ":"A","Ǡ":"A","Ạ":"A","Ȁ":"A","À":"A","Ả":"A","Ȃ":"A","Ā":"A","Ą":"A","Å":"A","Ǻ":"A","Ḁ":"A","Ⱥ":"A","Ã":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ḃ":"B","Ḅ":"B","Ɓ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ć":"C","Č":"C","Ç":"C","Ḉ":"C","Ĉ":"C","Ċ":"C","Ƈ":"C","Ȼ":"C","Ď":"D","Ḑ":"D","Ḓ":"D","Ḋ":"D","Ḍ":"D","Ɗ":"D","Ḏ":"D","Dz":"D","Dž":"D","Đ":"D","Ƌ":"D","DZ":"DZ","DŽ":"DZ","É":"E","Ĕ":"E","Ě":"E","Ȩ":"E","Ḝ":"E","Ê":"E","Ế":"E","Ệ":"E","Ề":"E","Ể":"E","Ễ":"E","Ḙ":"E","Ë":"E","Ė":"E","Ẹ":"E","Ȅ":"E","È":"E","Ẻ":"E","Ȇ":"E","Ē":"E","Ḗ":"E","Ḕ":"E","Ę":"E","Ɇ":"E","Ẽ":"E","Ḛ":"E","Ꝫ":"ET","Ḟ":"F","Ƒ":"F","Ǵ":"G","Ğ":"G","Ǧ":"G","Ģ":"G","Ĝ":"G","Ġ":"G","Ɠ":"G","Ḡ":"G","Ǥ":"G","Ḫ":"H","Ȟ":"H","Ḩ":"H","Ĥ":"H","Ⱨ":"H","Ḧ":"H","Ḣ":"H","Ḥ":"H","Ħ":"H","Í":"I","Ĭ":"I","Ǐ":"I","Î":"I","Ï":"I","Ḯ":"I","İ":"I","Ị":"I","Ȉ":"I","Ì":"I","Ỉ":"I","Ȋ":"I","Ī":"I","Į":"I","Ɨ":"I","Ĩ":"I","Ḭ":"I","Ꝺ":"D","Ꝼ":"F","Ᵹ":"G","Ꞃ":"R","Ꞅ":"S","Ꞇ":"T","Ꝭ":"IS","Ĵ":"J","Ɉ":"J","Ḱ":"K","Ǩ":"K","Ķ":"K","Ⱪ":"K","Ꝃ":"K","Ḳ":"K","Ƙ":"K","Ḵ":"K","Ꝁ":"K","Ꝅ":"K","Ĺ":"L","Ƚ":"L","Ľ":"L","Ļ":"L","Ḽ":"L","Ḷ":"L","Ḹ":"L","Ⱡ":"L","Ꝉ":"L","Ḻ":"L","Ŀ":"L","Ɫ":"L","Lj":"L","Ł":"L","LJ":"LJ","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ń":"N","Ň":"N","Ņ":"N","Ṋ":"N","Ṅ":"N","Ṇ":"N","Ǹ":"N","Ɲ":"N","Ṉ":"N","Ƞ":"N","Nj":"N","Ñ":"N","NJ":"NJ","Ó":"O","Ŏ":"O","Ǒ":"O","Ô":"O","Ố":"O","Ộ":"O","Ồ":"O","Ổ":"O","Ỗ":"O","Ö":"O","Ȫ":"O","Ȯ":"O","Ȱ":"O","Ọ":"O","Ő":"O","Ȍ":"O","Ò":"O","Ỏ":"O","Ơ":"O","Ớ":"O","Ợ":"O","Ờ":"O","Ở":"O","Ỡ":"O","Ȏ":"O","Ꝋ":"O","Ꝍ":"O","Ō":"O","Ṓ":"O","Ṑ":"O","Ɵ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Õ":"O","Ṍ":"O","Ṏ":"O","Ȭ":"O","Ƣ":"OI","Ꝏ":"OO","Ɛ":"E","Ɔ":"O","Ȣ":"OU","Ṕ":"P","Ṗ":"P","Ꝓ":"P","Ƥ":"P","Ꝕ":"P","Ᵽ":"P","Ꝑ":"P","Ꝙ":"Q","Ꝗ":"Q","Ŕ":"R","Ř":"R","Ŗ":"R","Ṙ":"R","Ṛ":"R","Ṝ":"R","Ȑ":"R","Ȓ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꜿ":"C","Ǝ":"E","Ś":"S","Ṥ":"S","Š":"S","Ṧ":"S","Ş":"S","Ŝ":"S","Ș":"S","Ṡ":"S","Ṣ":"S","Ṩ":"S","ẞ":"SS","Ť":"T","Ţ":"T","Ṱ":"T","Ț":"T","Ⱦ":"T","Ṫ":"T","Ṭ":"T","Ƭ":"T","Ṯ":"T","Ʈ":"T","Ŧ":"T","Ɐ":"A","Ꞁ":"L","Ɯ":"M","Ʌ":"V","Ꜩ":"TZ","Ú":"U","Ŭ":"U","Ǔ":"U","Û":"U","Ṷ":"U","Ü":"U","Ǘ":"U","Ǚ":"U","Ǜ":"U","Ǖ":"U","Ṳ":"U","Ụ":"U","Ű":"U","Ȕ":"U","Ù":"U","Ủ":"U","Ư":"U","Ứ":"U","Ự":"U","Ừ":"U","Ử":"U","Ữ":"U","Ȗ":"U","Ū":"U","Ṻ":"U","Ų":"U","Ů":"U","Ũ":"U","Ṹ":"U","Ṵ":"U","Ꝟ":"V","Ṿ":"V","Ʋ":"V","Ṽ":"V","Ꝡ":"VY","Ẃ":"W","Ŵ":"W","Ẅ":"W","Ẇ":"W","Ẉ":"W","Ẁ":"W","Ⱳ":"W","Ẍ":"X","Ẋ":"X","Ý":"Y","Ŷ":"Y","Ÿ":"Y","Ẏ":"Y","Ỵ":"Y","Ỳ":"Y","Ƴ":"Y","Ỷ":"Y","Ỿ":"Y","Ȳ":"Y","Ɏ":"Y","Ỹ":"Y","Ź":"Z","Ž":"Z","Ẑ":"Z","Ⱬ":"Z","Ż":"Z","Ẓ":"Z","Ȥ":"Z","Ẕ":"Z","Ƶ":"Z","IJ":"IJ","Œ":"OE","ᴀ":"A","ᴁ":"AE","ʙ":"B","ᴃ":"B","ᴄ":"C","ᴅ":"D","ᴇ":"E","ꜰ":"F","ɢ":"G","ʛ":"G","ʜ":"H","ɪ":"I","ʁ":"R","ᴊ":"J","ᴋ":"K","ʟ":"L","ᴌ":"L","ᴍ":"M","ɴ":"N","ᴏ":"O","ɶ":"OE","ᴐ":"O","ᴕ":"OU","ᴘ":"P","ʀ":"R","ᴎ":"N","ᴙ":"R","ꜱ":"S","ᴛ":"T","ⱻ":"E","ᴚ":"R","ᴜ":"U","ᴠ":"V","ᴡ":"W","ʏ":"Y","ᴢ":"Z","á":"a","ă":"a","ắ":"a","ặ":"a","ằ":"a","ẳ":"a","ẵ":"a","ǎ":"a","â":"a","ấ":"a","ậ":"a","ầ":"a","ẩ":"a","ẫ":"a","ä":"a","ǟ":"a","ȧ":"a","ǡ":"a","ạ":"a","ȁ":"a","à":"a","ả":"a","ȃ":"a","ā":"a","ą":"a","ᶏ":"a","ẚ":"a","å":"a","ǻ":"a","ḁ":"a","ⱥ":"a","ã":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ḃ":"b","ḅ":"b","ɓ":"b","ḇ":"b","ᵬ":"b","ᶀ":"b","ƀ":"b","ƃ":"b","ɵ":"o","ć":"c","č":"c","ç":"c","ḉ":"c","ĉ":"c","ɕ":"c","ċ":"c","ƈ":"c","ȼ":"c","ď":"d","ḑ":"d","ḓ":"d","ȡ":"d","ḋ":"d","ḍ":"d","ɗ":"d","ᶑ":"d","ḏ":"d","ᵭ":"d","ᶁ":"d","đ":"d","ɖ":"d","ƌ":"d","ı":"i","ȷ":"j","ɟ":"j","ʄ":"j","dz":"dz","dž":"dz","é":"e","ĕ":"e","ě":"e","ȩ":"e","ḝ":"e","ê":"e","ế":"e","ệ":"e","ề":"e","ể":"e","ễ":"e","ḙ":"e","ë":"e","ė":"e","ẹ":"e","ȅ":"e","è":"e","ẻ":"e","ȇ":"e","ē":"e","ḗ":"e","ḕ":"e","ⱸ":"e","ę":"e","ᶒ":"e","ɇ":"e","ẽ":"e","ḛ":"e","ꝫ":"et","ḟ":"f","ƒ":"f","ᵮ":"f","ᶂ":"f","ǵ":"g","ğ":"g","ǧ":"g","ģ":"g","ĝ":"g","ġ":"g","ɠ":"g","ḡ":"g","ᶃ":"g","ǥ":"g","ḫ":"h","ȟ":"h","ḩ":"h","ĥ":"h","ⱨ":"h","ḧ":"h","ḣ":"h","ḥ":"h","ɦ":"h","ẖ":"h","ħ":"h","ƕ":"hv","í":"i","ĭ":"i","ǐ":"i","î":"i","ï":"i","ḯ":"i","ị":"i","ȉ":"i","ì":"i","ỉ":"i","ȋ":"i","ī":"i","į":"i","ᶖ":"i","ɨ":"i","ĩ":"i","ḭ":"i","ꝺ":"d","ꝼ":"f","ᵹ":"g","ꞃ":"r","ꞅ":"s","ꞇ":"t","ꝭ":"is","ǰ":"j","ĵ":"j","ʝ":"j","ɉ":"j","ḱ":"k","ǩ":"k","ķ":"k","ⱪ":"k","ꝃ":"k","ḳ":"k","ƙ":"k","ḵ":"k","ᶄ":"k","ꝁ":"k","ꝅ":"k","ĺ":"l","ƚ":"l","ɬ":"l","ľ":"l","ļ":"l","ḽ":"l","ȴ":"l","ḷ":"l","ḹ":"l","ⱡ":"l","ꝉ":"l","ḻ":"l","ŀ":"l","ɫ":"l","ᶅ":"l","ɭ":"l","ł":"l","lj":"lj","ſ":"s","ẜ":"s","ẛ":"s","ẝ":"s","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ᵯ":"m","ᶆ":"m","ń":"n","ň":"n","ņ":"n","ṋ":"n","ȵ":"n","ṅ":"n","ṇ":"n","ǹ":"n","ɲ":"n","ṉ":"n","ƞ":"n","ᵰ":"n","ᶇ":"n","ɳ":"n","ñ":"n","nj":"nj","ó":"o","ŏ":"o","ǒ":"o","ô":"o","ố":"o","ộ":"o","ồ":"o","ổ":"o","ỗ":"o","ö":"o","ȫ":"o","ȯ":"o","ȱ":"o","ọ":"o","ő":"o","ȍ":"o","ò":"o","ỏ":"o","ơ":"o","ớ":"o","ợ":"o","ờ":"o","ở":"o","ỡ":"o","ȏ":"o","ꝋ":"o","ꝍ":"o","ⱺ":"o","ō":"o","ṓ":"o","ṑ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","õ":"o","ṍ":"o","ṏ":"o","ȭ":"o","ƣ":"oi","ꝏ":"oo","ɛ":"e","ᶓ":"e","ɔ":"o","ᶗ":"o","ȣ":"ou","ṕ":"p","ṗ":"p","ꝓ":"p","ƥ":"p","ᵱ":"p","ᶈ":"p","ꝕ":"p","ᵽ":"p","ꝑ":"p","ꝙ":"q","ʠ":"q","ɋ":"q","ꝗ":"q","ŕ":"r","ř":"r","ŗ":"r","ṙ":"r","ṛ":"r","ṝ":"r","ȑ":"r","ɾ":"r","ᵳ":"r","ȓ":"r","ṟ":"r","ɼ":"r","ᵲ":"r","ᶉ":"r","ɍ":"r","ɽ":"r","ↄ":"c","ꜿ":"c","ɘ":"e","ɿ":"r","ś":"s","ṥ":"s","š":"s","ṧ":"s","ş":"s","ŝ":"s","ș":"s","ṡ":"s","ṣ":"s","ṩ":"s","ʂ":"s","ᵴ":"s","ᶊ":"s","ȿ":"s","ɡ":"g","ß":"ss","ᴑ":"o","ᴓ":"o","ᴝ":"u","ť":"t","ţ":"t","ṱ":"t","ț":"t","ȶ":"t","ẗ":"t","ⱦ":"t","ṫ":"t","ṭ":"t","ƭ":"t","ṯ":"t","ᵵ":"t","ƫ":"t","ʈ":"t","ŧ":"t","ᵺ":"th","ɐ":"a","ᴂ":"ae","ǝ":"e","ᵷ":"g","ɥ":"h","ʮ":"h","ʯ":"h","ᴉ":"i","ʞ":"k","ꞁ":"l","ɯ":"m","ɰ":"m","ᴔ":"oe","ɹ":"r","ɻ":"r","ɺ":"r","ⱹ":"r","ʇ":"t","ʌ":"v","ʍ":"w","ʎ":"y","ꜩ":"tz","ú":"u","ŭ":"u","ǔ":"u","û":"u","ṷ":"u","ü":"u","ǘ":"u","ǚ":"u","ǜ":"u","ǖ":"u","ṳ":"u","ụ":"u","ű":"u","ȕ":"u","ù":"u","ủ":"u","ư":"u","ứ":"u","ự":"u","ừ":"u","ử":"u","ữ":"u","ȗ":"u","ū":"u","ṻ":"u","ų":"u","ᶙ":"u","ů":"u","ũ":"u","ṹ":"u","ṵ":"u","ᵫ":"ue","ꝸ":"um","ⱴ":"v","ꝟ":"v","ṿ":"v","ʋ":"v","ᶌ":"v","ⱱ":"v","ṽ":"v","ꝡ":"vy","ẃ":"w","ŵ":"w","ẅ":"w","ẇ":"w","ẉ":"w","ẁ":"w","ⱳ":"w","ẘ":"w","ẍ":"x","ẋ":"x","ᶍ":"x","ý":"y","ŷ":"y","ÿ":"y","ẏ":"y","ỵ":"y","ỳ":"y","ƴ":"y","ỷ":"y","ỿ":"y","ȳ":"y","ẙ":"y","ɏ":"y","ỹ":"y","ź":"z","ž":"z","ẑ":"z","ʑ":"z","ⱬ":"z","ż":"z","ẓ":"z","ȥ":"z","ẕ":"z","ᵶ":"z","ᶎ":"z","ʐ":"z","ƶ":"z","ɀ":"z","ff":"ff","ffi":"ffi","ffl":"ffl","fi":"fi","fl":"fl","ij":"ij","œ":"oe","st":"st","ₐ":"a","ₑ":"e","ᵢ":"i","ⱼ":"j","ₒ":"o","ᵣ":"r","ᵤ":"u","ᵥ":"v","ₓ":"x"}; + +//****************************************************************************** +// Added an initialize function which is essentially the code from the S +// constructor. Now, the S constructor calls this and a new method named +// setValue calls it as well. The setValue function allows constructors for +// modules that extend string.js to set the initial value of an object without +// knowing the internal workings of string.js. +// +// Also, all methods which return a new S object now call: +// +// return new this.constructor(s); +// +// instead of: +// +// return new S(s); +// +// This allows extended objects to keep their proper instanceOf and constructor. +//****************************************************************************** + + function initialize (object, s) { + if (s !== null && s !== undefined) { + if (typeof s === 'string') + object.s = s; + else + object.s = s.toString(); + } else { + object.s = s; //null or undefined + } + + object.orig = s; //original object, currently only used by toCSV() and toBoolean() + + if (s !== null && s !== undefined) { + if (object.__defineGetter__) { + object.__defineGetter__('length', function() { + return object.s.length; + }) + } else { + object.length = s.length; + } + } else { + object.length = -1; + } + } + + function S(s) { + initialize(this, s); + } + + var __nsp = String.prototype; + var __sp = S.prototype = { + + between: function(left, right) { + var s = this.s; + var startPos = s.indexOf(left); + var endPos = s.indexOf(right, startPos + left.length); + if (endPos == -1 && right != null) + return new this.constructor('') + else if (endPos == -1 && right == null) + return new this.constructor(s.substring(startPos + left.length)) + else + return new this.constructor(s.slice(startPos + left.length, endPos)); + }, + + //# modified slightly from https://github.com/epeli/underscore.string + camelize: function() { + var s = this.trim().s.replace(/(\-|_|\s)+(.)?/g, function(mathc, sep, c) { + return (c ? c.toUpperCase() : ''); + }); + return new this.constructor(s); + }, + + capitalize: function() { + return new this.constructor(this.s.substr(0, 1).toUpperCase() + this.s.substring(1).toLowerCase()); + }, + + charAt: function(index) { + return this.s.charAt(index); + }, + + chompLeft: function(prefix) { + var s = this.s; + if (s.indexOf(prefix) === 0) { + s = s.slice(prefix.length); + return new this.constructor(s); + } else { + return this; + } + }, + + chompRight: function(suffix) { + if (this.endsWith(suffix)) { + var s = this.s; + s = s.slice(0, s.length - suffix.length); + return new this.constructor(s); + } else { + return this; + } + }, + + //#thanks Google + collapseWhitespace: function() { + var s = this.s.replace(/[\s\xa0]+/g, ' ').replace(/^\s+|\s+$/g, ''); + return new this.constructor(s); + }, + + contains: function(ss) { + return this.s.indexOf(ss) >= 0; + }, + + count: function(ss) { + return require('./_count')(this.s, ss) + }, + + //#modified from https://github.com/epeli/underscore.string + dasherize: function() { + var s = this.trim().s.replace(/[_\s]+/g, '-').replace(/([A-Z])/g, '-$1').replace(/-+/g, '-').toLowerCase(); + return new this.constructor(s); + }, + + latinise: function() { + var s = this.replace(/[^A-Za-z0-9\[\] ]/g, function(x) { return latin_map[x] || x; }); + return new this.constructor(s); + }, + + decodeHtmlEntities: function() { //https://github.com/substack/node-ent/blob/master/index.js + var s = this.s; + s = s.replace(/&#(\d+);?/g, function (_, code) { + return String.fromCharCode(code); + }) + .replace(/&#[xX]([A-Fa-f0-9]+);?/g, function (_, hex) { + return String.fromCharCode(parseInt(hex, 16)); + }) + .replace(/&([^;\W]+;?)/g, function (m, e) { + var ee = e.replace(/;$/, ''); + var target = ENTITIES[e] || (e.match(/;$/) && ENTITIES[ee]); + + if (typeof target === 'number') { + return String.fromCharCode(target); + } + else if (typeof target === 'string') { + return target; + } + else { + return m; + } + }) + + return new this.constructor(s); + }, + + endsWith: function() { + var suffixes = Array.prototype.slice.call(arguments, 0); + for (var i = 0; i < suffixes.length; ++i) { + var l = this.s.length - suffixes[i].length; + if (l >= 0 && this.s.indexOf(suffixes[i], l) === l) return true; + } + return false; + }, + + escapeHTML: function() { //from underscore.string + return new this.constructor(this.s.replace(/[&<>"']/g, function(m){ return '&' + reversedEscapeChars[m] + ';'; })); + }, + + ensureLeft: function(prefix) { + var s = this.s; + if (s.indexOf(prefix) === 0) { + return this; + } else { + return new this.constructor(prefix + s); + } + }, + + ensureRight: function(suffix) { + var s = this.s; + if (this.endsWith(suffix)) { + return this; + } else { + return new this.constructor(s + suffix); + } + }, + + humanize: function() { //modified from underscore.string + if (this.s === null || this.s === undefined) + return new this.constructor('') + var s = this.underscore().replace(/_id$/,'').replace(/_/g, ' ').trim().capitalize() + return new this.constructor(s) + }, + + isAlpha: function() { + return !/[^a-z\xDF-\xFF]|^$/.test(this.s.toLowerCase()); + }, + + isAlphaNumeric: function() { + return !/[^0-9a-z\xDF-\xFF]/.test(this.s.toLowerCase()); + }, + + isEmpty: function() { + return this.s === null || this.s === undefined ? true : /^[\s\xa0]*$/.test(this.s); + }, + + isLower: function() { + return this.isAlpha() && this.s.toLowerCase() === this.s; + }, + + isNumeric: function() { + return !/[^0-9]/.test(this.s); + }, + + isUpper: function() { + return this.isAlpha() && this.s.toUpperCase() === this.s; + }, + + left: function(N) { + if (N >= 0) { + var s = this.s.substr(0, N); + return new this.constructor(s); + } else { + return this.right(-N); + } + }, + + lines: function() { //convert windows newlines to unix newlines then convert to an Array of lines + return this.replaceAll('\r\n', '\n').s.split('\n'); + }, + + pad: function(len, ch) { //https://github.com/component/pad + if (ch == null) ch = ' '; + if (this.s.length >= len) return new this.constructor(this.s); + len = len - this.s.length; + var left = Array(Math.ceil(len / 2) + 1).join(ch); + var right = Array(Math.floor(len / 2) + 1).join(ch); + return new this.constructor(left + this.s + right); + }, + + padLeft: function(len, ch) { //https://github.com/component/pad + if (ch == null) ch = ' '; + if (this.s.length >= len) return new this.constructor(this.s); + return new this.constructor(Array(len - this.s.length + 1).join(ch) + this.s); + }, + + padRight: function(len, ch) { //https://github.com/component/pad + if (ch == null) ch = ' '; + if (this.s.length >= len) return new this.constructor(this.s); + return new this.constructor(this.s + Array(len - this.s.length + 1).join(ch)); + }, + + parseCSV: function(delimiter, qualifier, escape, lineDelimiter) { //try to parse no matter what + delimiter = delimiter || ','; + escape = escape || '\\' + if (typeof qualifier == 'undefined') + qualifier = '"'; + + var i = 0, fieldBuffer = [], fields = [], len = this.s.length, inField = false, inUnqualifiedString = false, self = this; + var ca = function(i){return self.s.charAt(i)}; + if (typeof lineDelimiter !== 'undefined') var rows = []; + + if (!qualifier) + inField = true; + + while (i < len) { + var current = ca(i); + switch (current) { + case escape: + //fix for issues #32 and #35 + if (inField && ((escape !== qualifier) || ca(i+1) === qualifier)) { + i += 1; + fieldBuffer.push(ca(i)); + break; + } + if (escape !== qualifier) break; + case qualifier: + inField = !inField; + break; + case delimiter: + if(inUnqualifiedString) { + inField=false; + inUnqualifiedString=false; + } + if (inField && qualifier) + fieldBuffer.push(current); + else { + fields.push(fieldBuffer.join('')) + fieldBuffer.length = 0; + } + break; + case lineDelimiter: + if(inUnqualifiedString) { + inField=false; + inUnqualifiedString=false; + fields.push(fieldBuffer.join('')) + rows.push(fields); + fields = []; + fieldBuffer.length = 0; + } + else if (inField) { + fieldBuffer.push(current); + } else { + if (rows) { + fields.push(fieldBuffer.join('')) + rows.push(fields); + fields = []; + fieldBuffer.length = 0; + } + } + break; + case ' ': + if (inField) + fieldBuffer.push(current); + break; + default: + if (inField) + fieldBuffer.push(current); + else if(current!==qualifier) { + fieldBuffer.push(current); + inField=true; + inUnqualifiedString=true; + } + break; + } + i += 1; + } + + fields.push(fieldBuffer.join('')); + if (rows) { + rows.push(fields); + return rows; + } + return fields; + }, + + replaceAll: function(ss, r) { + //var s = this.s.replace(new RegExp(ss, 'g'), r); + var s = this.s.split(ss).join(r) + return new this.constructor(s); + }, + + strip: function() { + var ss = this.s; + for(var i= 0, n=arguments.length; i= 0) { + var s = this.s.substr(this.s.length - N, N); + return new this.constructor(s); + } else { + return this.left(-N); + } + }, + + setValue: function (s) { + initialize(this, s); + return this; + }, + + slugify: function() { + var sl = (new S(new S(this.s).latinise().s.replace(/[^\w\s-]/g, '').toLowerCase())).dasherize().s; + if (sl.charAt(0) === '-') + sl = sl.substr(1); + return new this.constructor(sl); + }, + + startsWith: function() { + var prefixes = Array.prototype.slice.call(arguments, 0); + for (var i = 0; i < prefixes.length; ++i) { + if (this.s.lastIndexOf(prefixes[i], 0) === 0) return true; + } + return false; + }, + + stripPunctuation: function() { + //return new this.constructor(this.s.replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()]/g,"")); + return new this.constructor(this.s.replace(/[^\w\s]|_/g, "").replace(/\s+/g, " ")); + }, + + stripTags: function() { //from sugar.js + var s = this.s, args = arguments.length > 0 ? arguments : ['']; + multiArgs(args, function(tag) { + s = s.replace(RegExp('<\/?' + tag + '[^<>]*>', 'gi'), ''); + }); + return new this.constructor(s); + }, + + template: function(values, opening, closing) { + var s = this.s + var opening = opening || Export.TMPL_OPEN + var closing = closing || Export.TMPL_CLOSE + + var open = opening.replace(/[-[\]()*\s]/g, "\\$&").replace(/\$/g, '\\$') + var close = closing.replace(/[-[\]()*\s]/g, "\\$&").replace(/\$/g, '\\$') + var r = new RegExp(open + '(.+?)' + close, 'g') + //, r = /\{\{(.+?)\}\}/g + var matches = s.match(r) || []; + + matches.forEach(function(match) { + var key = match.substring(opening.length, match.length - closing.length).trim();//chop {{ and }} + var value = typeof values[key] == 'undefined' ? '' : values[key]; + s = s.replace(match, value); + }); + return new this.constructor(s); + }, + + times: function(n) { + return new this.constructor(new Array(n + 1).join(this.s)); + }, + + toBoolean: function() { + if (typeof this.orig === 'string') { + var s = this.s.toLowerCase(); + return s === 'true' || s === 'yes' || s === 'on' || s === '1'; + } else + return this.orig === true || this.orig === 1; + }, + + toFloat: function(precision) { + var num = parseFloat(this.s) + if (precision) + return parseFloat(num.toFixed(precision)) + else + return num + }, + + toInt: function() { //thanks Google + // If the string starts with '0x' or '-0x', parse as hex. + return /^\s*-?0x/i.test(this.s) ? parseInt(this.s, 16) : parseInt(this.s, 10) + }, + + trim: function() { + var s; + if (typeof __nsp.trim === 'undefined') + s = this.s.replace(/(^\s*|\s*$)/g, '') + else + s = this.s.trim() + return new this.constructor(s); + }, + + trimLeft: function() { + var s; + if (__nsp.trimLeft) + s = this.s.trimLeft(); + else + s = this.s.replace(/(^\s*)/g, ''); + return new this.constructor(s); + }, + + trimRight: function() { + var s; + if (__nsp.trimRight) + s = this.s.trimRight(); + else + s = this.s.replace(/\s+$/, ''); + return new this.constructor(s); + }, + + truncate: function(length, pruneStr) { //from underscore.string, author: github.com/rwz + var str = this.s; + + length = ~~length; + pruneStr = pruneStr || '...'; + + if (str.length <= length) return new this.constructor(str); + + var tmpl = function(c){ return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' '; }, + template = str.slice(0, length+1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA' + + if (template.slice(template.length-2).match(/\w\w/)) + template = template.replace(/\s*\S+$/, ''); + else + template = new S(template.slice(0, template.length-1)).trimRight().s; + + return (template+pruneStr).length > str.length ? new S(str) : new S(str.slice(0, template.length)+pruneStr); + }, + + toCSV: function() { + var delim = ',', qualifier = '"', escape = '\\', encloseNumbers = true, keys = false; + var dataArray = []; + + function hasVal(it) { + return it !== null && it !== ''; + } + + if (typeof arguments[0] === 'object') { + delim = arguments[0].delimiter || delim; + delim = arguments[0].separator || delim; + qualifier = arguments[0].qualifier || qualifier; + encloseNumbers = !!arguments[0].encloseNumbers; + escape = arguments[0].escape || escape; + keys = !!arguments[0].keys; + } else if (typeof arguments[0] === 'string') { + delim = arguments[0]; + } + + if (typeof arguments[1] === 'string') + qualifier = arguments[1]; + + if (arguments[1] === null) + qualifier = null; + + if (this.orig instanceof Array) + dataArray = this.orig; + else { //object + for (var key in this.orig) + if (this.orig.hasOwnProperty(key)) + if (keys) + dataArray.push(key); + else + dataArray.push(this.orig[key]); + } + + var rep = escape + qualifier; + var buildString = []; + for (var i = 0; i < dataArray.length; ++i) { + var shouldQualify = hasVal(qualifier) + if (typeof dataArray[i] == 'number') + shouldQualify &= encloseNumbers; + + if (shouldQualify) + buildString.push(qualifier); + + if (dataArray[i] !== null && dataArray[i] !== undefined) { + var d = new S(dataArray[i]).replaceAll(qualifier, rep).s; + buildString.push(d); + } else + buildString.push('') + + if (shouldQualify) + buildString.push(qualifier); + + if (delim) + buildString.push(delim); + } + + //chop last delim + //console.log(buildString.length) + buildString.length = buildString.length - 1; + return new this.constructor(buildString.join('')); + }, + + toString: function() { + return this.s; + }, + + //#modified from https://github.com/epeli/underscore.string + underscore: function() { + var s = this.trim().s.replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/([A-Z\d]+)([A-Z][a-z])/,'$1_$2').replace(/[-\s]+/g, '_').toLowerCase(); + return new this.constructor(s); + }, + + unescapeHTML: function() { //from underscore.string + return new this.constructor(this.s.replace(/\&([^;]+);/g, function(entity, entityCode){ + var match; + + if (entityCode in escapeChars) { + return escapeChars[entityCode]; + } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) { + return String.fromCharCode(parseInt(match[1], 16)); + } else if (match = entityCode.match(/^#(\d+)$/)) { + return String.fromCharCode(~~match[1]); + } else { + return entity; + } + })); + }, + + valueOf: function() { + return this.s.valueOf(); + }, + + //#Added a New Function called wrapHTML. + wrapHTML: function (tagName, tagAttrs) { + var s = this.s, el = (tagName == null) ? 'span' : tagName, elAttr = '', wrapped = ''; + if(typeof tagAttrs == 'object') for(var prop in tagAttrs) elAttr += ' ' + prop + '="' +(new this.constructor(tagAttrs[prop])).escapeHTML() + '"'; + s = wrapped.concat('<', el, elAttr, '>', this, ''); + return new this.constructor(s); + } + } + + var methodsAdded = []; + function extendPrototype() { + for (var name in __sp) { + (function(name){ + var func = __sp[name]; + if (!__nsp.hasOwnProperty(name)) { + methodsAdded.push(name); + __nsp[name] = function() { + String.prototype.s = this; + return func.apply(this, arguments); + } + } + })(name); + } + } + + function restorePrototype() { + for (var i = 0; i < methodsAdded.length; ++i) + delete String.prototype[methodsAdded[i]]; + methodsAdded.length = 0; + } + + +/************************************* +/* Attach Native JavaScript String Properties +/*************************************/ + + var nativeProperties = getNativeStringProperties(); + for (var name in nativeProperties) { + (function(name) { + var stringProp = __nsp[name]; + if (typeof stringProp == 'function') { + //console.log(stringProp) + if (!__sp[name]) { + if (nativeProperties[name] === 'string') { + __sp[name] = function() { + //console.log(name) + return new this.constructor(stringProp.apply(this, arguments)); + } + } else { + __sp[name] = stringProp; + } + } + } + })(name); + } + + +/************************************* +/* Function Aliases +/*************************************/ + + __sp.repeat = __sp.times; + __sp.include = __sp.contains; + __sp.toInteger = __sp.toInt; + __sp.toBool = __sp.toBoolean; + __sp.decodeHTMLEntities = __sp.decodeHtmlEntities //ensure consistent casing scheme of 'HTML' + + +//****************************************************************************** +// Set the constructor. Without this, string.js objects are instances of +// Object instead of S. +//****************************************************************************** + + __sp.constructor = S; + + +/************************************* +/* Private Functions +/*************************************/ + + function getNativeStringProperties() { + var names = getNativeStringPropertyNames(); + var retObj = {}; + + for (var i = 0; i < names.length; ++i) { + var name = names[i]; + var func = __nsp[name]; + try { + // #127: pass extra parameter to keep shelljs happy + var type = typeof func.apply('test', ['string']); + retObj[name] = type; + } catch (e) {} + } + return retObj; + } + + function getNativeStringPropertyNames() { + var results = []; + if (Object.getOwnPropertyNames) { + results = Object.getOwnPropertyNames(__nsp); + results.splice(results.indexOf('valueOf'), 1); + results.splice(results.indexOf('toString'), 1); + return results; + } else { //meant for legacy cruft, this could probably be made more efficient + var stringNames = {}; + var objectNames = []; + for (var name in String.prototype) + stringNames[name] = name; + + for (var name in Object.prototype) + delete stringNames[name]; + + //stringNames['toString'] = 'toString'; //this was deleted with the rest of the object names + for (var name in stringNames) { + results.push(name); + } + return results; + } + } + + function Export(str) { + return new S(str); + }; + + //attach exports to StringJSWrapper + Export.extendPrototype = extendPrototype; + Export.restorePrototype = restorePrototype; + Export.VERSION = VERSION; + Export.TMPL_OPEN = '{{'; + Export.TMPL_CLOSE = '}}'; + Export.ENTITIES = ENTITIES; + + + +/************************************* +/* Exports +/*************************************/ + + if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { + module.exports = Export; + + } else { + + if(typeof define === "function" && define.amd) { + define([], function() { + return Export; + }); + } else { + window.S = Export; + } + } + + +/************************************* +/* 3rd Party Private Functions +/*************************************/ + + //from sugar.js + function multiArgs(args, fn) { + var result = [], i; + for(i = 0; i < args.length; i++) { + result.push(args[i]); + if(fn) fn.call(args, args[i], i); + } + return result; + } + + //from underscore.string + var escapeChars = { + lt: '<', + gt: '>', + quot: '"', + apos: "'", + amp: '&' + }; + + function escapeRegExp (s) { + // most part from https://github.com/skulpt/skulpt/blob/ecaf75e69c2e539eff124b2ab45df0b01eaf2295/src/str.js#L242 + var c; + var i; + var ret = []; + var re = /^[A-Za-z0-9]+$/; + s = ensureString(s); + for (i = 0; i < s.length; ++i) { + c = s.charAt(i); + + if (re.test(c)) { + ret.push(c); + } + else { + if (c === "\\000") { + ret.push("\\000"); + } + else { + ret.push("\\" + c); + } + } + } + return ret.join(""); + } + + function ensureString(string) { + return string == null ? '' : '' + string; + } + + //from underscore.string + var reversedEscapeChars = {}; + for(var key in escapeChars){ reversedEscapeChars[escapeChars[key]] = key; } + + ENTITIES = { + "amp" : "&", + "gt" : ">", + "lt" : "<", + "quot" : "\"", + "apos" : "'", + "AElig" : 198, + "Aacute" : 193, + "Acirc" : 194, + "Agrave" : 192, + "Aring" : 197, + "Atilde" : 195, + "Auml" : 196, + "Ccedil" : 199, + "ETH" : 208, + "Eacute" : 201, + "Ecirc" : 202, + "Egrave" : 200, + "Euml" : 203, + "Iacute" : 205, + "Icirc" : 206, + "Igrave" : 204, + "Iuml" : 207, + "Ntilde" : 209, + "Oacute" : 211, + "Ocirc" : 212, + "Ograve" : 210, + "Oslash" : 216, + "Otilde" : 213, + "Ouml" : 214, + "THORN" : 222, + "Uacute" : 218, + "Ucirc" : 219, + "Ugrave" : 217, + "Uuml" : 220, + "Yacute" : 221, + "aacute" : 225, + "acirc" : 226, + "aelig" : 230, + "agrave" : 224, + "aring" : 229, + "atilde" : 227, + "auml" : 228, + "ccedil" : 231, + "eacute" : 233, + "ecirc" : 234, + "egrave" : 232, + "eth" : 240, + "euml" : 235, + "iacute" : 237, + "icirc" : 238, + "igrave" : 236, + "iuml" : 239, + "ntilde" : 241, + "oacute" : 243, + "ocirc" : 244, + "ograve" : 242, + "oslash" : 248, + "otilde" : 245, + "ouml" : 246, + "szlig" : 223, + "thorn" : 254, + "uacute" : 250, + "ucirc" : 251, + "ugrave" : 249, + "uuml" : 252, + "yacute" : 253, + "yuml" : 255, + "copy" : 169, + "reg" : 174, + "nbsp" : 160, + "iexcl" : 161, + "cent" : 162, + "pound" : 163, + "curren" : 164, + "yen" : 165, + "brvbar" : 166, + "sect" : 167, + "uml" : 168, + "ordf" : 170, + "laquo" : 171, + "not" : 172, + "shy" : 173, + "macr" : 175, + "deg" : 176, + "plusmn" : 177, + "sup1" : 185, + "sup2" : 178, + "sup3" : 179, + "acute" : 180, + "micro" : 181, + "para" : 182, + "middot" : 183, + "cedil" : 184, + "ordm" : 186, + "raquo" : 187, + "frac14" : 188, + "frac12" : 189, + "frac34" : 190, + "iquest" : 191, + "times" : 215, + "divide" : 247, + "OElig;" : 338, + "oelig;" : 339, + "Scaron;" : 352, + "scaron;" : 353, + "Yuml;" : 376, + "fnof;" : 402, + "circ;" : 710, + "tilde;" : 732, + "Alpha;" : 913, + "Beta;" : 914, + "Gamma;" : 915, + "Delta;" : 916, + "Epsilon;" : 917, + "Zeta;" : 918, + "Eta;" : 919, + "Theta;" : 920, + "Iota;" : 921, + "Kappa;" : 922, + "Lambda;" : 923, + "Mu;" : 924, + "Nu;" : 925, + "Xi;" : 926, + "Omicron;" : 927, + "Pi;" : 928, + "Rho;" : 929, + "Sigma;" : 931, + "Tau;" : 932, + "Upsilon;" : 933, + "Phi;" : 934, + "Chi;" : 935, + "Psi;" : 936, + "Omega;" : 937, + "alpha;" : 945, + "beta;" : 946, + "gamma;" : 947, + "delta;" : 948, + "epsilon;" : 949, + "zeta;" : 950, + "eta;" : 951, + "theta;" : 952, + "iota;" : 953, + "kappa;" : 954, + "lambda;" : 955, + "mu;" : 956, + "nu;" : 957, + "xi;" : 958, + "omicron;" : 959, + "pi;" : 960, + "rho;" : 961, + "sigmaf;" : 962, + "sigma;" : 963, + "tau;" : 964, + "upsilon;" : 965, + "phi;" : 966, + "chi;" : 967, + "psi;" : 968, + "omega;" : 969, + "thetasym;" : 977, + "upsih;" : 978, + "piv;" : 982, + "ensp;" : 8194, + "emsp;" : 8195, + "thinsp;" : 8201, + "zwnj;" : 8204, + "zwj;" : 8205, + "lrm;" : 8206, + "rlm;" : 8207, + "ndash;" : 8211, + "mdash;" : 8212, + "lsquo;" : 8216, + "rsquo;" : 8217, + "sbquo;" : 8218, + "ldquo;" : 8220, + "rdquo;" : 8221, + "bdquo;" : 8222, + "dagger;" : 8224, + "Dagger;" : 8225, + "bull;" : 8226, + "hellip;" : 8230, + "permil;" : 8240, + "prime;" : 8242, + "Prime;" : 8243, + "lsaquo;" : 8249, + "rsaquo;" : 8250, + "oline;" : 8254, + "frasl;" : 8260, + "euro;" : 8364, + "image;" : 8465, + "weierp;" : 8472, + "real;" : 8476, + "trade;" : 8482, + "alefsym;" : 8501, + "larr;" : 8592, + "uarr;" : 8593, + "rarr;" : 8594, + "darr;" : 8595, + "harr;" : 8596, + "crarr;" : 8629, + "lArr;" : 8656, + "uArr;" : 8657, + "rArr;" : 8658, + "dArr;" : 8659, + "hArr;" : 8660, + "forall;" : 8704, + "part;" : 8706, + "exist;" : 8707, + "empty;" : 8709, + "nabla;" : 8711, + "isin;" : 8712, + "notin;" : 8713, + "ni;" : 8715, + "prod;" : 8719, + "sum;" : 8721, + "minus;" : 8722, + "lowast;" : 8727, + "radic;" : 8730, + "prop;" : 8733, + "infin;" : 8734, + "ang;" : 8736, + "and;" : 8743, + "or;" : 8744, + "cap;" : 8745, + "cup;" : 8746, + "int;" : 8747, + "there4;" : 8756, + "sim;" : 8764, + "cong;" : 8773, + "asymp;" : 8776, + "ne;" : 8800, + "equiv;" : 8801, + "le;" : 8804, + "ge;" : 8805, + "sub;" : 8834, + "sup;" : 8835, + "nsub;" : 8836, + "sube;" : 8838, + "supe;" : 8839, + "oplus;" : 8853, + "otimes;" : 8855, + "perp;" : 8869, + "sdot;" : 8901, + "lceil;" : 8968, + "rceil;" : 8969, + "lfloor;" : 8970, + "rfloor;" : 8971, + "lang;" : 9001, + "rang;" : 9002, + "loz;" : 9674, + "spades;" : 9824, + "clubs;" : 9827, + "hearts;" : 9829, + "diams;" : 9830 + } + + +}).call(this); + +},{"./_count":14}],16:[function(require,module,exports){ +// Underscore.js 1.8.3 +// http://underscorejs.org +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `exports` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var + push = ArrayProto.push, + slice = ArrayProto.slice, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind, + nativeCreate = Object.create; + + // Naked function reference for surrogate-prototype-swapping. + var Ctor = function(){}; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.8.3'; + + // Internal function that returns an efficient (for current engines) version + // of the passed-in callback, to be repeatedly applied in other Underscore + // functions. + var optimizeCb = function(func, context, argCount) { + if (context === void 0) return func; + switch (argCount == null ? 3 : argCount) { + case 1: return function(value) { + return func.call(context, value); + }; + case 2: return function(value, other) { + return func.call(context, value, other); + }; + case 3: return function(value, index, collection) { + return func.call(context, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(context, accumulator, value, index, collection); + }; + } + return function() { + return func.apply(context, arguments); + }; + }; + + // A mostly-internal function to generate callbacks that can be applied + // to each element in a collection, returning the desired result — either + // identity, an arbitrary callback, a property matcher, or a property accessor. + var cb = function(value, context, argCount) { + if (value == null) return _.identity; + if (_.isFunction(value)) return optimizeCb(value, context, argCount); + if (_.isObject(value)) return _.matcher(value); + return _.property(value); + }; + _.iteratee = function(value, context) { + return cb(value, context, Infinity); + }; + + // An internal function for creating assigner functions. + var createAssigner = function(keysFunc, undefinedOnly) { + return function(obj) { + var length = arguments.length; + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; + } + } + return obj; + }; + }; + + // An internal function for creating a new object that inherits from another. + var baseCreate = function(prototype) { + if (!_.isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + }; + + var property = function(key) { + return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + }; + + // Helper for collection methods to determine whether a collection + // should be iterated as an array or as an object + // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + var getLength = property('length'); + var isArrayLike = function(collection) { + var length = getLength(collection); + return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; + }; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles raw objects in addition to array-likes. Treats all + // sparse array-likes as if they were dense. + _.each = _.forEach = function(obj, iteratee, context) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { + iteratee(obj[i], i, obj); + } + } else { + var keys = _.keys(obj); + for (i = 0, length = keys.length; i < length; i++) { + iteratee(obj[keys[i]], keys[i], obj); + } + } + return obj; + }; + + // Return the results of applying the iteratee to each element. + _.map = _.collect = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + results = Array(length); + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + results[index] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Create a reducing function iterating left or right. + function createReduce(dir) { + // Optimized iterator function as using arguments.length + // in the main function will deoptimize the, see #1991. + function iterator(obj, iteratee, memo, keys, index, length) { + for (; index >= 0 && index < length; index += dir) { + var currentKey = keys ? keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + } + + return function(obj, iteratee, memo, context) { + iteratee = optimizeCb(iteratee, context, 4); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length, + index = dir > 0 ? 0 : length - 1; + // Determine the initial value if none is provided. + if (arguments.length < 3) { + memo = obj[keys ? keys[index] : index]; + index += dir; + } + return iterator(obj, iteratee, memo, keys, index, length); + }; + } + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. + _.reduce = _.foldl = _.inject = createReduce(1); + + // The right-associative version of reduce, also known as `foldr`. + _.reduceRight = _.foldr = createReduce(-1); + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, predicate, context) { + var key; + if (isArrayLike(obj)) { + key = _.findIndex(obj, predicate, context); + } else { + key = _.findKey(obj, predicate, context); + } + if (key !== void 0 && key !== -1) return obj[key]; + }; + + // Return all the elements that pass a truth test. + // Aliased as `select`. + _.filter = _.select = function(obj, predicate, context) { + var results = []; + predicate = cb(predicate, context); + _.each(obj, function(value, index, list) { + if (predicate(value, index, list)) results.push(value); + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, predicate, context) { + return _.filter(obj, _.negate(cb(predicate)), context); + }; + + // Determine whether all of the elements match a truth test. + // Aliased as `all`. + _.every = _.all = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (!predicate(obj[currentKey], currentKey, obj)) return false; + } + return true; + }; + + // Determine if at least one element in the object matches a truth test. + // Aliased as `any`. + _.some = _.any = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = !isArrayLike(obj) && _.keys(obj), + length = (keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = keys ? keys[index] : index; + if (predicate(obj[currentKey], currentKey, obj)) return true; + } + return false; + }; + + // Determine if the array or object contains a given item (using `===`). + // Aliased as `includes` and `include`. + _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + if (typeof fromIndex != 'number' || guard) fromIndex = 0; + return _.indexOf(obj, item, fromIndex) >= 0; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + var func = isFunc ? method : value[method]; + return func == null ? func : func.apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, _.property(key)); + }; + + // Convenience version of a common use case of `filter`: selecting only objects + // containing specific `key:value` pairs. + _.where = function(obj, attrs) { + return _.filter(obj, _.matcher(attrs)); + }; + + // Convenience version of a common use case of `find`: getting the first object + // containing specific `key:value` pairs. + _.findWhere = function(obj, attrs) { + return _.find(obj, _.matcher(attrs)); + }; + + // Return the maximum element (or element-based computation). + _.max = function(obj, iteratee, context) { + var result = -Infinity, lastComputed = -Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value > result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed > lastComputed || computed === -Infinity && result === -Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iteratee, context) { + var result = Infinity, lastComputed = Infinity, + value, computed; + if (iteratee == null && obj != null) { + obj = isArrayLike(obj) ? obj : _.values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value < result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + _.each(obj, function(value, index, list) { + computed = iteratee(value, index, list); + if (computed < lastComputed || computed === Infinity && result === Infinity) { + result = value; + lastComputed = computed; + } + }); + } + return result; + }; + + // Shuffle a collection, using the modern version of the + // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + _.shuffle = function(obj) { + var set = isArrayLike(obj) ? obj : _.values(obj); + var length = set.length; + var shuffled = Array(length); + for (var index = 0, rand; index < length; index++) { + rand = _.random(0, index); + if (rand !== index) shuffled[index] = shuffled[rand]; + shuffled[rand] = set[index]; + } + return shuffled; + }; + + // Sample **n** random values from a collection. + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `map`. + _.sample = function(obj, n, guard) { + if (n == null || guard) { + if (!isArrayLike(obj)) obj = _.values(obj); + return obj[_.random(obj.length - 1)]; + } + return _.shuffle(obj).slice(0, Math.max(0, n)); + }; + + // Sort the object's values by a criterion produced by an iteratee. + _.sortBy = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value: value, + index: index, + criteria: iteratee(value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + }; + + // An internal function used for aggregate "group by" operations. + var group = function(behavior) { + return function(obj, iteratee, context) { + var result = {}; + iteratee = cb(iteratee, context); + _.each(obj, function(value, index) { + var key = iteratee(value, index, obj); + behavior(result, value, key); + }); + return result; + }; + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = group(function(result, value, key) { + if (_.has(result, key)) result[key].push(value); else result[key] = [value]; + }); + + // Indexes the object's values by a criterion, similar to `groupBy`, but for + // when you know that your index values will be unique. + _.indexBy = group(function(result, value, key) { + result[key] = value; + }); + + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + _.countBy = group(function(result, value, key) { + if (_.has(result, key)) result[key]++; else result[key] = 1; + }); + + // Safely create a real, live array from anything iterable. + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (isArrayLike(obj)) return _.map(obj, _.identity); + return _.values(obj); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + if (obj == null) return 0; + return isArrayLike(obj) ? obj.length : _.keys(obj).length; + }; + + // Split a collection into two arrays: one whose elements all satisfy the given + // predicate, and one whose elements all do not satisfy the predicate. + _.partition = function(obj, predicate, context) { + predicate = cb(predicate, context); + var pass = [], fail = []; + _.each(obj, function(value, key, obj) { + (predicate(value, key, obj) ? pass : fail).push(value); + }); + return [pass, fail]; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head` and `take`. The **guard** check + // allows it to work with `_.map`. + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[0]; + return _.initial(array, array.length - n); + }; + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. + _.initial = function(array, n, guard) { + return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. + _.last = function(array, n, guard) { + if (array == null) return void 0; + if (n == null || guard) return array[array.length - 1]; + return _.rest(array, Math.max(0, array.length - n)); + }; + + // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. + // Especially useful on the arguments object. Passing an **n** will return + // the rest N values in the array. + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, n == null || guard ? 1 : n); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, _.identity); + }; + + // Internal implementation of a recursive `flatten` function. + var flatten = function(input, shallow, strict, startIndex) { + var output = [], idx = 0; + for (var i = startIndex || 0, length = getLength(input); i < length; i++) { + var value = input[i]; + if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { + //flatten current level of array or arguments object + if (!shallow) value = flatten(value, shallow, strict); + var j = 0, len = value.length; + output.length += len; + while (j < len) { + output[idx++] = value[j++]; + } + } else if (!strict) { + output[idx++] = value; + } + } + return output; + }; + + // Flatten out an array, either recursively (by default), or just one level. + _.flatten = function(array, shallow) { + return flatten(array, shallow, false); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iteratee, context) { + if (!_.isBoolean(isSorted)) { + context = iteratee; + iteratee = isSorted; + isSorted = false; + } + if (iteratee != null) iteratee = cb(iteratee, context); + var result = []; + var seen = []; + for (var i = 0, length = getLength(array); i < length; i++) { + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; + if (isSorted) { + if (!i || seen !== computed) result.push(value); + seen = computed; + } else if (iteratee) { + if (!_.contains(seen, computed)) { + seen.push(computed); + result.push(value); + } + } else if (!_.contains(result, value)) { + result.push(value); + } + } + return result; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(flatten(arguments, true, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersection = function(array) { + var result = []; + var argsLength = arguments.length; + for (var i = 0, length = getLength(array); i < length; i++) { + var item = array[i]; + if (_.contains(result, item)) continue; + for (var j = 1; j < argsLength; j++) { + if (!_.contains(arguments[j], item)) break; + } + if (j === argsLength) result.push(item); + } + return result; + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = flatten(arguments, true, true, 1); + return _.filter(array, function(value){ + return !_.contains(rest, value); + }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + return _.unzip(arguments); + }; + + // Complement of _.zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices + _.unzip = function(array) { + var length = array && _.max(array, getLength).length || 0; + var result = Array(length); + + for (var index = 0; index < length; index++) { + result[index] = _.pluck(array, index); + } + return result; + }; + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. + _.object = function(list, values) { + var result = {}; + for (var i = 0, length = getLength(list); i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; + + // Generator function to create the findIndex and findLastIndex functions + function createPredicateIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; + } + + // Returns the first index on an array-like that passes a predicate test + _.findIndex = createPredicateIndexFinder(1); + _.findLastIndex = createPredicateIndexFinder(-1); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = getLength(array); + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; + } + return low; + }; + + // Generator function to create the indexOf and lastIndexOf functions + function createIndexFinder(dir, predicateFind, sortedIndex) { + return function(array, item, idx) { + var i = 0, length = getLength(array); + if (typeof idx == 'number') { + if (dir > 0) { + i = idx >= 0 ? idx : Math.max(idx + length, i); + } else { + length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; + } + } else if (sortedIndex && idx && length) { + idx = sortedIndex(array, item); + return array[idx] === item ? idx : -1; + } + if (item !== item) { + idx = predicateFind(slice.call(array, i, length), _.isNaN); + return idx >= 0 ? idx + i : -1; + } + for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { + if (array[idx] === item) return idx; + } + return -1; + }; + } + + // Return the position of the first occurrence of an item in an array, + // or -1 if the item is not included in the array. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); + _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (stop == null) { + stop = start || 0; + start = 0; + } + step = step || 1; + + var length = Math.max(Math.ceil((stop - start) / step), 0); + var range = Array(length); + + for (var idx = 0; idx < length; idx++, start += step) { + range[idx] = start; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Determines whether to execute a function as a constructor + // or a normal function with the provided arguments + var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (_.isObject(result)) return result; + return self; + }; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if + // available. + _.bind = function(func, context) { + if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); + var args = slice.call(arguments, 2); + var bound = function() { + return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); + }; + return bound; + }; + + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. _ acts + // as a placeholder, allowing any combination of arguments to be pre-filled. + _.partial = function(func) { + var boundArgs = slice.call(arguments, 1); + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; + } + while (position < arguments.length) args.push(arguments[position++]); + return executeBound(func, bound, this, this, args); + }; + return bound; + }; + + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + _.bindAll = function(obj) { + var i, length = arguments.length, key; + if (length <= 1) throw new Error('bindAll must be passed function names'); + for (i = 1; i < length; i++) { + key = arguments[i]; + obj[key] = _.bind(obj[key], obj); + } + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memoize = function(key) { + var cache = memoize.cache; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); + if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); + return cache[address]; + }; + memoize.cache = {}; + return memoize; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ + return func.apply(null, args); + }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = _.partial(_.delay, _, 1); + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _.throttle = function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + if (!options) options = {}; + var later = function() { + previous = options.leading === false ? 0 : _.now(); + timeout = null; + result = func.apply(context, args); + if (!timeout) context = args = null; + }; + return function() { + var now = _.now(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0 || remaining > wait) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + previous = now; + result = func.apply(context, args); + if (!timeout) context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { + var timeout, args, context, timestamp, result; + + var later = function() { + var last = _.now() - timestamp; + + if (last < wait && last >= 0) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + if (!timeout) context = args = null; + } + } + }; + + return function() { + context = this; + args = arguments; + timestamp = _.now(); + var callNow = immediate && !timeout; + if (!timeout) timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + + return result; + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return _.partial(wrapper, func); + }; + + // Returns a negated version of the passed-in predicate. + _.negate = function(predicate) { + return function() { + return !predicate.apply(this, arguments); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var args = arguments; + var start = args.length - 1; + return function() { + var i = start; + var result = args[start].apply(this, arguments); + while (i--) result = args[i].call(this, result); + return result; + }; + }; + + // Returns a function that will only be executed on and after the Nth call. + _.after = function(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; + + // Returns a function that will only be executed up to (but not including) the Nth call. + _.before = function(times, func) { + var memo; + return function() { + if (--times > 0) { + memo = func.apply(this, arguments); + } + if (times <= 1) func = null; + return memo; + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = _.partial(_.before, 2); + + // Object Functions + // ---------------- + + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + function collectNonEnumProps(obj, keys) { + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { + keys.push(prop); + } + } + } + + // Retrieve the names of an object's own properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve all the property names of an object. + _.allKeys = function(obj) { + if (!_.isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; + }; + + // Returns the results of applying the iteratee to each element of the object + // In contrast to _.map it returns an object + _.mapObject = function(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var keys = _.keys(obj), + length = keys.length, + results = {}, + currentKey; + for (var index = 0; index < length; index++) { + currentKey = keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + }; + + // Convert an object into a list of `[key, value]` pairs. + _.pairs = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var pairs = Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [keys[i], obj[keys[i]]]; + } + return pairs; + }; + + // Invert the keys and values of an object. The values must be serializable. + _.invert = function(obj) { + var result = {}; + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + result[obj[keys[i]]] = keys[i]; + } + return result; + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = createAssigner(_.allKeys); + + // Assigns a given object with all the own properties in the passed-in object(s) + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + _.extendOwn = _.assign = createAssigner(_.keys); + + // Returns the first key on an object that passes a predicate test + _.findKey = function(obj, predicate, context) { + predicate = cb(predicate, context); + var keys = _.keys(obj), key; + for (var i = 0, length = keys.length; i < length; i++) { + key = keys[i]; + if (predicate(obj[key], key, obj)) return key; + } + }; + + // Return a copy of the object only containing the whitelisted properties. + _.pick = function(object, oiteratee, context) { + var result = {}, obj = object, iteratee, keys; + if (obj == null) return result; + if (_.isFunction(oiteratee)) { + keys = _.allKeys(obj); + iteratee = optimizeCb(oiteratee, context); + } else { + keys = flatten(arguments, false, false, 1); + iteratee = function(value, key, obj) { return key in obj; }; + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; + } + return result; + }; + + // Return a copy of the object without the blacklisted properties. + _.omit = function(obj, iteratee, context) { + if (_.isFunction(iteratee)) { + iteratee = _.negate(iteratee); + } else { + var keys = _.map(flatten(arguments, false, false, 1), String); + iteratee = function(value, key) { + return !_.contains(keys, key); + }; + } + return _.pick(obj, iteratee, context); + }; + + // Fill in a given object with default properties. + _.defaults = createAssigner(_.allKeys, true); + + // Creates an object that inherits from the given prototype object. + // If additional properties are provided then they will be added to the + // created object. + _.create = function(prototype, props) { + var result = baseCreate(prototype); + if (props) _.extendOwn(result, props); + return result; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Returns whether an object has a given set of `key:value` pairs. + _.isMatch = function(object, attrs) { + var keys = _.keys(attrs), length = keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; + } + return true; + }; + + + // Internal recursive comparison function for `isEqual`. + var eq = function(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + switch (className) { + // Strings, numbers, regular expressions, dates, and booleans are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + } + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && + _.isFunction(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + } + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } + + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var keys = _.keys(a), key; + length = keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (_.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (obj == null) return true; + if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; + return _.keys(obj).length === 0; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) === '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. + _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) === '[object ' + name + ']'; + }; + }); + + // Define a fallback version of the method in browsers (ahem, IE < 9), where + // there isn't any inspectable "Arguments" type. + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return _.has(obj, 'callee'); + }; + } + + // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, + // IE 11 (#1621), and in Safari 8 (#1929). + if (typeof /./ != 'function' && typeof Int8Array != 'object') { + _.isFunction = function(obj) { + return typeof obj == 'function' || false; + }; + } + + // Is a given object a finite number? + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; + + // Is the given value `NaN`? (NaN is the only number which does not equal itself). + _.isNaN = function(obj) { + return _.isNumber(obj) && obj !== +obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Shortcut function for checking if an object has a given property directly + // on itself (in other words, not on a prototype). + _.has = function(obj, key) { + return obj != null && hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iteratees. + _.identity = function(value) { + return value; + }; + + // Predicate-generating functions. Often useful outside of Underscore. + _.constant = function(value) { + return function() { + return value; + }; + }; + + _.noop = function(){}; + + _.property = property; + + // Generates a function for a given object that returns a given property. + _.propertyOf = function(obj) { + return obj == null ? function(){} : function(key) { + return obj[key]; + }; + }; + + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + _.matcher = _.matches = function(attrs) { + attrs = _.extendOwn({}, attrs); + return function(obj) { + return _.isMatch(obj, attrs); + }; + }; + + // Run a function **n** times. + _.times = function(n, iteratee, context) { + var accum = Array(Math.max(0, n)); + iteratee = optimizeCb(iteratee, context, 1); + for (var i = 0; i < n; i++) accum[i] = iteratee(i); + return accum; + }; + + // Return a random integer between min and max (inclusive). + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; + + // A (possibly faster) way to get the current timestamp as an integer. + _.now = Date.now || function() { + return new Date().getTime(); + }; + + // List of HTML entities for escaping. + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + var unescapeMap = _.invert(escapeMap); + + // Functions for escaping and unescaping strings to/from HTML interpolation. + var createEscaper = function(map) { + var escaper = function(match) { + return map[match]; + }; + // Regexes for identifying a key that needs to be escaped + var source = '(?:' + _.keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function(string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; + }; + _.escape = createEscaper(escapeMap); + _.unescape = createEscaper(unescapeMap); + + // If the value of the named `property` is a function then invoke it with the + // `object` as context; otherwise, return it. + _.result = function(object, property, fallback) { + var value = object == null ? void 0 : object[property]; + if (value === void 0) { + value = fallback; + } + return _.isFunction(value) ? value.call(object) : value; + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escaper = /\\|'|\r|\n|\u2028|\u2029/g; + + var escapeChar = function(match) { + return '\\' + escapes[match]; + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + // NB: `oldSettings` only exists for backwards compatibility. + _.template = function(text, settings, oldSettings) { + if (!settings && oldSettings) settings = oldSettings; + settings = _.defaults({}, settings, _.templateSettings); + + // Combine delimiters into one regular expression via alternation. + var matcher = RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset).replace(escaper, escapeChar); + index = offset + match.length; + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } else if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } else if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + + // Adobe VMs need the match returned to produce the correct offest. + return match; + }); + source += "';\n"; + + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + 'return __p;\n'; + + try { + var render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + var template = function(data) { + return render.call(this, data, _); + }; + + // Provide the compiled source as a convenience for precompilation. + var argument = settings.variable || 'obj'; + template.source = 'function(' + argument + '){\n' + source + '}'; + + return template; + }; + + // Add a "chain" function. Start chaining a wrapped Underscore object. + _.chain = function(obj) { + var instance = _(obj); + instance._chain = true; + return instance; + }; + + // OOP + // --------------- + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + + // Helper function to continue chaining intermediate results. + var result = function(instance, obj) { + return instance._chain ? _(obj).chain() : obj; + }; + + // Add your own custom functions to the Underscore object. + _.mixin = function(obj) { + _.each(_.functions(obj), function(name) { + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result(this, func.apply(_, args)); + }; + }); + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; + return result(this, obj); + }; + }); + + // Add all accessor Array functions to the wrapper. + _.each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result(this, method.apply(this._wrapped, arguments)); + }; + }); + + // Extracts the result from a wrapped and chained object. + _.prototype.value = function() { + return this._wrapped; + }; + + // Provide unwrapping proxy for some methods used in engine operations + // such as arithmetic and JSON stringification. + _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; + + _.prototype.toString = function() { + return '' + this._wrapped; + }; + + // AMD registration happens at the end for compatibility with AMD loaders + // that may not enforce next-turn semantics on modules. Even though general + // practice for AMD registration is to be anonymous, underscore registers + // as a named module because, like jQuery, it is a base library that is + // popular enough to be bundled in a third party lib, but not be part of + // an AMD load request. Those cases could generate an error when an + // anonymous define() is called outside of a loader request. + if (typeof define === 'function' && define.amd) { + define('underscore', [], function() { + return _; + }); + } +}.call(this)); + +},{}],"/home/raskolnikov/dev/mixco/script/novation_twitch.mixco":[function(require,module,exports){ +// script.twitch +// ============= +// +// > This file is part of the [Mixco framework](http://sinusoid.es/mixco). +// > - **View me [on a static web](http://sinusoid.es/mixco/script/novation_twitch.mixco.html)** +// > - **View me [on GitHub](https://github.com/arximboldi/mixco/blob/master/script/novation_twitch.mixco.litcoffee)** +// +// Mixx script file for the **Novation Twitch** controller. +// +// This script serves as **tutorial** for creating scripts using the +// *Mixco* framework, but programming directly in JavaScript. Still, +// we recommend you to try CoffeeScript, since it is a bit of a nicer +// language. +// +// If you want to modify this script, you may want to read the +// [Novation Twitch Programmer Guide](https://us.novationmusic.com/support/downloads/twitch-programmers-reference-guide) +// +// ### Note for Linux Users +// +// The Linux Kernel version 3.10 is required to get Novation Twitch +// detected as soundcard or MIDI device. +// +// ![Novation Twitch Layout](http://sinusoid.es/mixco/pic/novation_twitch.png) +// +// Dependencies +// ------------ +// +// First, we have to import the modules from the framework. We use +// that the *NodeJS* `require` function. Note that all other NodeJS +// modules are usable too when writing your script with the *Mixco* +// framework. + +var _ = require('underscore') +var mixco = require('mixco') +var c = mixco.control +var b = mixco.behaviour +var v = mixco.value + +// The script +// ---------- +// +// When writing a controller script we use the `script.register` +// function to generate and install a script instance in the current +// module. The first parameter is the current module as defined by +// *NodeJS*, the second parameter is the JavaScript object with all +// the functions and information about our script. + +mixco.script.register(module, { + + // ### Metadata + // + // Then the `info` object contains the meta-data that is displayed + // to the user in the MIDI mapping chooser of Mixxx. + + info: { + name: "[mixco] Novation Twitch", + author: "Juan Pedro Bolivar Puente ", + forums: 'https://github.com/arximboldi/mixco/issues', + wiki: 'https://sinusoid.es/mixco/script/korg_nanokontrol2.mixco.html', + description: "Controller mapping for Novation Twitch (in basic mode).", + }, + + // ### Constructor + // + // The constructor contains the definition of the MIDI mapping. + // Here we create all the different control objects and add them + // to the script instance. + + constructor: function () { + + // #### Master section + // + // Many of the master controls of the that the *pre-hear + // volume*, *pre-hear mix*, *booth volume* and *master volume* + // knobs are handled directly by the integrated soundcard of + // the controller. We map the rest here. + // + // * *Crossfader* slider. + + c.input(0x08, 0x07).does("[Master]", "crossfader") + + // #### Mic/aux and effects + // + // Sadly, the buttons *Aux*, *Deck A*, *Deck B* and *Pre-hear* + // of the effects and microphone sections are controlled by + // the hardware in a bit of a useless way, so they do nothing + // -- other than light up when they are pressed. + + var ccIdFxBanks = function (index) { + banks = 5 + params = 4 + ids = [] + for (var j = 0; j < banks; ++j) + ids.push.apply(ids, c.ccIds(index + params * j, 0xB)) + return ids + } + + // * Microphone *volume* control and *on/off* button. + + c.input(ccIdFxBanks(0x3)).does(b.soft("[Microphone]", "pregain")) + c.control(c.noteIds(0x23, 0xB)).does("[Microphone]", "talkover") + + // * The the *Depth* and *Mix* knobs in the *Master FX* + // section are mapped to *mix* and *super* of the first + // effect unit. + + c.input(ccIdFxBanks(0x0)) + .does("[EffectRack1_EffectUnit1]", "mix") + c.input(ccIdFxBanks(0x1)) + .option(scaledDiff(1/2)) + .does("[EffectRack1_EffectUnit1]", "super1") + + // * The *beats* knob can be used to change the selected effect. + + c.input(ccIdFxBanks(0x2)) + .does("[EffectRack1_EffectUnit1]", "chain_selector") + + // * The *on/off* button of the FX section completley toggles + // the first effect unit. + + c.control(c.noteIds(0x22, 0xB)) + .does("[EffectRack1_EffectUnit1]", "enabled") + + // #### Browse + // + // * The *back* and *fwd* can be used to scroll the sidebar. + + c.input(c.noteIds(0x54, 0x7)).does( + "[Playlist]", "SelectPrevPlaylist") + c.input(c.noteIds(0x56, 0x7)).does( + "[Playlist]", "SelectNextPlaylist") + + // * The *scroll* encoder scrolls the current view. When + // pressed it moves faster. + + scrollFaster = b.modifier() + + c.input(c.noteIds(0x55, 0x7)).does(scrollFaster) + c.input(0x55, 0x7) + .when (scrollFaster, + b.map("[Playlist]", "SelectTrackKnob") + .option(scaledSelectKnob(8))) + .else_(b.map("[Playlist]", "SelectTrackKnob") + .options.selectknob) + + // * The *area* toggles the maximized library. + + c.control(c.noteIds(0x50, 0x7)).does( + "[Master]", "maximize_library") + + // * The *view* button in the *browser* section lets you tap + // the tempo for the track that is currently on pre-hear. + + this.viewButton = c.control(c.noteIds(0x51, 0x7)) + + // ### Per deck controls + // + // We use a `behaviou.chooser` for the PFL selection. This + // will make sure that only one prehear channel is selected at + // a time for greater convenience. Then, we define a `addDeck` + // function that will add the actual controls for each of the + // decks. + + this.decks = b.chooser() + this.addDeck(0) + this.addDeck(1) + + }, + + addDeck: function (i) { + var g = "[Channel" + (i+1) + "]" + var ccId = function (cc) { return c.ccIds(cc, 0x07+i) } + var ccIdShift = function (cc) { return c.ccIds(cc, 0x09+i) } + var ccIdAll = function (cc) { return _.union(ccId(cc), + ccIdShift(cc)) } + var noteId = function (note) { return c.noteIds(note, 0x07+i) } + var noteIdShift = function (note) { return c.noteIds(note, 0x09+i) } + var noteIdAll = function (cc) { return _.union(noteId(cc), + noteIdShift(cc)) } + + // #### Mixer section + // + // * Pre-hear deck selection. + + c.control(noteIdAll(0x0A)).does(this.decks.add(g, "pfl")) + + this.viewButton.when(this.decks.activator(i), + g, "bpm_tap", g, "beat_active") + + // * *Volume* fader and *low*, *mid*, *high* and *trim* knobs. + // *Trim* is the deck *gain* knob in Mixxx. + + c.input(ccIdAll(0x07)).does(g, "volume") + c.input(ccIdAll(0x46)).does(g, "filterLow") + c.input(ccIdAll(0x47)).does(g, "filterMid") + c.input(ccIdAll(0x48)).does(g, "filterHigh") + c.input(ccIdAll(0x09)).does(g, "pregain") + + // * *Volume* meters for each channel. + + c.output(noteIdAll(0x5f)).does(b.mapOut(g, "VuMeter").meter()) + + // * The **fader FX** we use to control the quick filter. The + // **on/off** button below can be used to toggle it. + // Likewise, pressing the knob momentarily toggles it. + + c.input(ccIdAll(0x06)) + .option(scaledDiff(1/2)) + .does("[QuickEffectRack1_"+g+"]", 'super1') + c.control(noteIdAll(0x06)) + .does("[QuickEffectRack1_"+g+"]", 'enabled') + c.control(noteIdAll(0x0D)) + .does("[QuickEffectRack1_"+g+"]", 'enabled') + + // #### Effects + // + // * In the *Master FX* section, the *FX Select* left and + // right enable the first effect unit on the deck in the + // direction of the arrow. + + c.control(c.noteIds(0x20+i, 0xB)) + .does("[EffectRack1_EffectUnit1]", "group_"+g+"_enable") + + // #### Browse + // + // * The *load A* or *load B* buttons load the selected track + // to the given deck. + + c.control(c.noteIds(0x52+i, 0x7)).does(g, "LoadSelectedTrack") + + // #### Deck transport + // + // * The *play* and *cue* buttons work as expected. On + // *shift*, the cue button does a reverse effect. + + var redLed = 0x00 + var amberLed = 0x40 + var greenLed = 0x70 + var pad = function (ids, color) { + return c.control(ids).states({ + on: color + 0xf, + off: color + 0x1 + }) + } + + pad(noteIdAll(0x17), greenLed).does(g, "play") + pad(noteId(0x16), redLed).does(g, "cue_default", g, "cue_indicator") + pad(noteIdShift(0x16), amberLed).does(g, "reverse") + + // * The *keylock* button toggles the pitch-independent time + // stretching. On *shift*, it toggles *slip mode*, in which + // loops and scratching continue playback on the background + // thus returning the playhead to where the track would have + // been. + + slipMode = b.switch_() + c.control(noteId(0x12)).does(g, "keylock") + c.control(noteIdShift(0x12)).does(slipMode) + + // * The *sync* button. Like the button in the UI, it can be + // held pressed to enable the deck in the *master sync* + // group. + + c.control(noteIdAll(0x13)).does(g, "sync_enabled") + + // #### Beat grid + // + // * The *adjust* button *aligns the beatgrid* to the current + // play position. + + c.control(noteIdAll(0x11)).does(g, "beats_translate_curpos") + + // * The *set* button toggles loop and hot-cue *quantization* + // on or off. + + c.control(noteIdAll(0x10)).does(g, "quantize") + + // #### Pitch and transport bar + // + // * The *pitch* encoder moves the pitch slider up and + // down. When it is pressed, it moves it pitch faster. + + var coarseRateFactor = 1/10 + var coarseRateOn = b.modifier() + + c.input(noteIdAll(0x03)).does(coarseRateOn) + c.input(ccIdAll(0x03)) + .when (coarseRateOn, + b.map(g, "rate").option(scaledDiff(2))) + .else_(b.map(g, "rate").option(scaledDiff(1/12))) + + // * In *drop* mode, the touch strip scrolls through the song. + + c.input(ccId(0x34)).does(g, "playposition") + + // * In *swipe* mode, the touch strip nudges the pitch up and + // down. When *shift* is held it simulates scratching. + + c.input(ccId(0x35)).does(g, "jog") + .option(scaledSelectKnob(-1/3)) + c.input(ccIdShift(0x35)).does(b.scratchTick(i+1)) + .options.selectknob, + c.input(noteIdShift(0x47)) + .does(b.scratchEnable(i+1, 128)) + .when(slipMode, b.map(g, "slip_enabled").options.switch_) + + // #### Performance modes + // + // ##### Hot cues + // + // * In *hot-cues* mode, the performance buttons control the + // hot cues. One may *clear* hot-cues with *shift*. + + for (var j = 0; j < 8; ++j) { + pad(noteId(0x60+j), amberLed).does( + g, "hotcue_" + (j+1) + "_activate", + g, "hotcue_" + (j+1) + "_enabled") + pad(noteIdShift(0x60+j), amberLed).does( + g, "hotcue_" + (j+1) + "_clear", + g, "hotcue_" + (j+1) + "_enabled") + } + + // ##### Slicer + // + // There is no functionality like a *slicer* in Mixxx, but we + // reuse these pads for various purposes in this mode. + // + // * The buttons *1 to 4* trigger the first four samplers. + // The sample plays as long as the button is held. + + for (var j = 0; j < 4; ++j) + pad(noteIdAll(0x68+j), redLed).does( + "[Sampler" + (j+1) + "]", "cue_preview") + + // * The buttons *5 and 6* trigger a *spinback* and *brake* + // effect respectively. + + pad(noteIdAll(0x6C), greenLed).does(b.spinback(i+1)) + pad(noteIdAll(0x6D), greenLed).does(b.brake(i+1)) + + // * The buttons *7 and 8* perform a stutter effect at + // different speeds. + + pad(noteIdAll(0x6E), amberLed).does(b.stutter(g, 1/8)) + pad(noteIdAll(0x6F), amberLed).does(b.stutter(g, 1/4)) + + // ##### Auto loop + // + // * In *auto-loop* mode, the pads select *loops* of sizes + // 0.5, 1, 2, 4, 8, 16, 32 or 64, beats (starting at the + // top-left pad). On *shift*, it creates loops of sizes + // 1/32, 1/16, 1/8, 1/4, 1/2, 1, 2, or 4 beats. + + loopSize = [ "0.03125", "0.0625", "0.125", "0.25", + "0.5", "1", "2", "4", + "8", "16", "32", "64" ] + for (var j = 0; j < 8; ++j) + pad(noteId(0x70+j), greenLed).does( + g, "beatloop_" + loopSize[4+j] + "_toggle", + g, "beatloop_" + loopSize[4+j] + "_enabled") + for (var j = 0; j < 8; ++j) + pad(noteIdShift(0x70+j), greenLed).does( + g, "beatloop_" + loopSize[j] + "_toggle", + g, "beatloop_" + loopSize[j] + "_enabled") + + // ##### Loop roll + // + // * In *loop-roll* mode, momentarily creates a loop and, on + // release returns the playhead to where it would have been + // without looping. Loop sizes are 1/32, 1/16, 1/8, 1/4, + // 1/2, 1, 2, or 4 beats (starting at the top-left pad). On + // *shift*, it is 0.5, 1, 2, 4, 8, 16, 32 or 64 beats. + + loopSize = [ "0.03125", "0.0625", "0.125", "0.25", + "0.5", "1", "2", "4", + "8", "16", "32", "64" ] + for (var j = 0; j < 8; ++j) + pad(noteId(0x78+j), greenLed).does( + g, "beatlooproll_" + loopSize[j] + "_activate", + g, "beatloop_" + loopSize[j] + "_enabled") + for (var j = 0; j < 8; ++j) + pad(noteIdShift(0x78+j), greenLed).does( + g, "beatlooproll_" + loopSize[4+j] + "_activate", + g, "beatloop_" + loopSize[4+j] + "_enabled") + + }, + + // ### Initialization + // + // The `preinit` function is called before the MIDI controls are + // initialized. We are going to set the device in *basic mode*, + // as mentioned in the manual. This means that mode management is + // done by the device -- this will simplify the script and let + // have direct lower latency mappings more often. + + preinit: function () { + this.mixxx.midi.sendShortMsg(0xb7, 0x00, 0x6f) + this.mixxx.midi.sendShortMsg(0xb7, 0x00, 0x00) + }, + + init: function () { + this.decks.activate(0) + }, + + // ### Shutdown + // + // The documentation suggests to reset the device when the program + // shuts down. This means that all the lights are turned off and + // the device is in basic mode, ready to be used by some other + // program. + + postshutdown: function () { + this.mixxx.midi.sendShortMsg(0xb7, 0x00, 0x00) + } + +}); + +// Utilities +// --------- +// +// The *scaledDiff* function returns a behaviour option that is useful +// to define encoders with a specific sensitivity, which is useful to +// correct the issues of the stepped encoders. + +function scaledDiff (factor) { + return function (v, v0) { + return (v0 + factor * (v > 64 ? v - 128 : v)).clamp(0, 128) + } +} + +function scaledSelectKnob (factor) { + return function (v) { + return factor * (v > 64 ? v - 128 : v) + } +} + +// > Copyright (C) 2013 Juan Pedro Bolívar Puente +// > +// > 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 . + +},{"mixco":2,"underscore":16}],17:[function(require,module,exports){ +var _, assert, bind, copy, events, extend, factory, indent, isinstance, makeOptionsChooser, map, multi, option, ref, ref1, ref2, toOption, transform, value, + extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + slice = [].slice; + +events = require('events'); + +transform = require('./transform'); + +value = require('./value'); + +ref = require('./util'), indent = ref.indent, assert = ref.assert, factory = ref.factory, copy = ref.copy; + +ref1 = require('heterarchy'), multi = ref1.multi, isinstance = ref1.isinstance; + +_ = (ref2 = require('underscore'), extend = ref2.extend, bind = ref2.bind, map = ref2.map, ref2); + +exports.Actor = (function(superClass) { + extend1(Actor, superClass); + + function Actor() { + return Actor.__super__.constructor.apply(this, arguments); + } + + Actor.prototype.send = void 0; + + return Actor; + +})(events.EventEmitter); + +toOption = function(option) { + var result; + result = option; + if (isinstance(option, Function)) { + result = { + transform: option + }; + } + if ((result.transform != null) && (result.process == null)) { + result.process = result.transform.length === 1 ? function(ev, b) { + return ev.value = this.transform(ev.value); + } : function(ev, b) { + return ev.value = this.transform(ev.value, b.midiValue); + }; + } + return result; +}; + +option = exports.option = (function() { + var add, result, rot64; + result = {}; + add = function() { + var desc, i, mixxxName, name, names, option; + names = 2 <= arguments.length ? slice.call(arguments, 0, i = arguments.length - 1) : (i = 0, []), option = arguments[i++]; + mixxxName = names[0], name = names[1]; + desc = toOption(option); + desc.name = mixxxName; + result[name != null ? name : mixxxName] = desc; + return result; + }; + rot64 = function(sign) { + return function(v1, v0) { + var diff; + diff = v1 - (64..diff = diff === -1 || diff === 1 ? diff / 16.0 : diff - diff.sign()); + return (v0 + diff * sign).clamp(0, 127); + }; + }; + add('invert', function(v) { + return 127.0 - v; + }); + add('rot64', rot64(1)); + add('rot64inv', rot64(-1)); + add('rot64fast', function(v1, v0) { + return (v0 + (v1 - 64) * 1.5).clamp(0, 127); + }); + add('diff', function(v1, v0) { + return v0 + (v1 > 64 ? v1 - 128 : v1); + }); + add('button', function(v) { + return v !== 0; + }); + add('switch', function(v) { + return 1; + }); + result.switch_ = result["switch"]; + add('hercjog', function(v1, v0) { + return v0 + (v1 > 64 ? v1 - 128 : v1); + }); + add('spread64', function(v) { + return v - 64; + }); + add('selectknob', function(v) { + if (v > 64) { + return v - 128; + } else { + return v; + } + }); + return add('soft-takeover', 'softTakeover', { + enable: function(b) { + if (isinstance(b, exports.MapIn)) { + return b.script.mixxx.engine.softTakeover(b.group, b.key, true); + } + }, + disable: function(b) { + if (isinstance(b, exports.MapIn)) { + return b.script.mixxx.engine.softTakeover(b.group, b.key, false); + } + } + }); +})(); + +exports.makeOptionsChooser = makeOptionsChooser = function(obj) { + var key, opt, result; + result = {}; + for (key in option) { + opt = option[key]; + Object.defineProperty(result, key, { + get: (function(opt) { + return function() { + return obj.option(opt); + }; + })(opt) + }); + } + return result; +}; + +exports.Behaviour = (function(superClass) { + extend1(Behaviour, superClass); + + function Behaviour() { + return Behaviour.__super__.constructor.apply(this, arguments); + } + + Behaviour.prototype.enable = function(script, actor) { + var i, len, opt, ref3, results; + assert(this.actor == null); + assert(this.script == null); + this.script = script; + this.actor = actor; + this._eventListener = (function(_this) { + return function(ev) { + var i, len, opt, ref3; + if (_this._options != null) { + ev = copy(ev); + ref3 = _this._options; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (typeof opt.process === "function") { + opt.process(ev, _this); + } + } + } + return _this.onMidiEvent(ev); + }; + })(this); + actor.on('event', this._eventListener); + if (this._options != null) { + ref3 = this._options; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + results.push(typeof opt.enable === "function" ? opt.enable(this) : void 0); + } + return results; + } + }; + + Behaviour.prototype.disable = function(script, actor) { + var i, len, opt, ref3; + assert(this.script === script); + assert(this.actor === actor); + if (this._options != null) { + ref3 = this._options; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (typeof opt.disable === "function") { + opt.disable(this); + } + } + } + actor.removeListener('event', this._eventListener); + delete this.script; + return delete this.actor; + }; + + Behaviour.prototype.option = function() { + var i, len, opt, options, ref3; + options = 1 <= arguments.length ? slice.call(arguments, 0) : []; + for (i = 0, len = options.length; i < len; i++) { + opt = options[i]; + assert(opt); + } + (ref3 = (this._options != null ? this._options : this._options = [])).push.apply(ref3, map(options, toOption)); + return this; + }; + + Behaviour.property('options', function() { + return makeOptionsChooser(this); + }); + + Behaviour.prototype.directInMapping = function() { + return null; + }; + + Behaviour.prototype.directOutMapping = function() { + return null; + }; + + Behaviour.prototype.onMidiEvent = function(ev) { + return null; + }; + + Behaviour.prototype.getMidiValue = function() { + return this.value; + }; + + Behaviour.property('midiValue', function() { + return this.getMidiValue(); + }); + + return Behaviour; + +})(value.Value); + +exports.Call = (function(superClass) { + extend1(Call, superClass); + + function Call(onMidiEvent) { + this.onMidiEvent = onMidiEvent; + Call.__super__.constructor.call(this); + } + + return Call; + +})(exports.Behaviour); + +exports.call = factory(exports.Call); + +exports.Output = (function(superClass) { + extend1(Output, superClass); + + Output.prototype.minimum = 1; + + Output.prototype.maximum = void 0; + + function Output() { + Output.__super__.constructor.apply(this, arguments); + this.output = value.value(); + } + + Output.prototype.enable = function() { + Output.__super__.enable.apply(this, arguments); + if (this.actor.send != null) { + if (this._updateOutputCallback == null) { + this._updateOutputCallback = (function(_this) { + return function() { + return _this.updateOutput(); + }; + })(this); + } + this.output.on('value', this._updateOutputCallback); + } + if (this.actor.doSend != null) { + return this.updateOutput(this.actor.doSend); + } + }; + + Output.prototype.disable = function() { + if (this._updateOutputCallback != null) { + this.removeListener('value', this._updateOutputCallback); + this._updateOutputCallback = void 0; + } + return Output.__super__.disable.apply(this, arguments); + }; + + Output.prototype.updateOutput = function(sendfn) { + if (sendfn == null) { + sendfn = null; + } + if (sendfn == null) { + sendfn = this.actor.send; + } + return sendfn.call(this.actor, (Math.abs(this.output.value) >= this.minimum ? 'on' : 'off')); + }; + + return Output; + +})(exports.Behaviour); + +exports.Transform = (function(superClass) { + extend1(Transform, superClass); + + function Transform(transformer1, initial) { + this.transformer = transformer1; + if (initial == null) { + initial = void 0; + } + Transform.__super__.constructor.call(this, { + initial: initial + }); + } + + Transform.prototype.onMidiEvent = function(ev) { + var result; + result = this.transformer(ev, this.midiValue); + if (result != null) { + return this.output.value = this.value = result; + } + }; + + Transform.prototype.getMidiValue = function() { + var base, ref3; + return (ref3 = typeof (base = this.transformer).inverse === "function" ? base.inverse(this.value) : void 0) != null ? ref3 : this.value; + }; + + return Transform; + +})(exports.Output); + +exports.transform = factory(exports.Transform); + +exports.modifier = function() { + return exports.transform(transform.momentaryT, false); +}; + +exports["switch"] = function() { + return exports.transform(transform.binaryT, false); +}; + +exports.switch_ = exports["switch"]; + +exports.MapIn = (function(superClass) { + extend1(MapIn, superClass); + + function MapIn(ingroupOrParams, inkey) { + var ref3; + if (inkey == null) { + inkey = void 0; + } + MapIn.__super__.constructor.apply(this, arguments); + ref3 = !isinstance(ingroupOrParams, String) ? ingroupOrParams : { + group: ingroupOrParams, + key: inkey + }, this.group = ref3.group, this.key = ref3.key; + this._transform = transform.mappings[this.key]; + } + + MapIn.prototype.transform = function(trans) { + this._transform = trans; + return this; + }; + + MapIn.prototype.enable = function(script, actor) { + var engine; + MapIn.__super__.enable.apply(this, arguments); + engine = script.mixxx.engine; + this.value = engine.getValue(this.group, this.key); + if (this.listeners('value').length > 0) { + if (this._inHandler == null) { + this._inHandler = script.registerHandler((function(_this) { + return function(v) { + return _this.value = v; + }; + })(this)); + } + engine.connectControl(this.group, this.key, this._inHandler); + return this._inHandlerConnected = true; + } + }; + + MapIn.prototype.disable = function() { + if (this._inHandlerConnected != null) { + this.script.mixxx.engine.connectControl(this.group, this.key, this._inHandler, true); + this._inHandlerConnected = false; + } + return MapIn.__super__.disable.apply(this, arguments); + }; + + MapIn.prototype.directInMapping = function() { + if (this._transform === transform.mappings[this.key]) { + return { + group: this.group, + key: this.key + }; + } + }; + + MapIn.prototype.onMidiEvent = function(ev) { + var val; + val = this._transform(ev, this.midiValue); + if (val != null) { + this.script.mixxx.engine.setValue(this.group, this.key, val); + if (this.listeners('value').length === 0) { + return this.value = val; + } + } + }; + + MapIn.prototype.getMidiValue = function() { + var ref3, ref4; + return (ref3 = (ref4 = this._transform) != null ? typeof ref4.inverse === "function" ? ref4.inverse(this.value) : void 0 : void 0) != null ? ref3 : this.value; + }; + + return MapIn; + +})(exports.Behaviour); + +exports.mapIn = factory(exports.MapIn); + +exports.MapOut = (function(superClass) { + extend1(MapOut, superClass); + + function MapOut(outgroupOrParams, outkey) { + var ref3; + if (outkey == null) { + outkey = void 0; + } + MapOut.__super__.constructor.apply(this, arguments); + ref3 = !isinstance(outgroupOrParams, String) ? outgroupOrParams : { + outgroup: outgroupOrParams, + outkey: outkey + }, this.outgroup = ref3.outgroup, this.outkey = ref3.outkey; + } + + MapOut.prototype.meter = function(transformer) { + if (transformer == null) { + transformer = void 0; + } + this._outTransform = transformer; + if (this._outTransform == null) { + this._outTransform = transform.mappings[this.outkey].inverse; + } + this.updateOutput = function() { + return this.actor.send(Math.floor(this._outTransform(this.output.value))); + }; + return this; + }; + + MapOut.prototype.enable = function(script, actor) { + var engine; + MapOut.__super__.enable.apply(this, arguments); + engine = script.mixxx.engine; + this.output.value = engine.getValue(this.outgroup, this.outkey); + if (this.output.listeners('value').length > 0) { + if (this._outHandler == null) { + this._outHandler = script.registerHandler((function(_this) { + return function(v) { + return _this.output.value = v; + }; + })(this)); + } + engine.connectControl(this.outgroup, this.outkey, this._outHandler); + return this._outHandlerConnected = true; + } + }; + + MapOut.prototype.disable = function() { + if (this._outHandlerConnected != null) { + this.script.mixxx.engine.connectControl(this.outgroup, this.outkey, this._outHandler, true); + this._outHandlerConnected = false; + } + return MapOut.__super__.disable.apply(this, arguments); + }; + + MapOut.prototype.directOutMapping = function() { + if (this._outTransform == null) { + return { + group: this.outgroup, + key: this.outkey, + minimum: this.minimum + }; + } + }; + + return MapOut; + +})(exports.Output); + +exports.mapOut = factory(exports.MapOut); + +exports.Map = (function(superClass) { + extend1(Map, superClass); + + function Map(groupOrParams, key, outgroup, outkey) { + var params; + params = !isinstance(groupOrParams, String) ? groupOrParams : { + group: groupOrParams, + key: key, + outgroup: outgroup, + outkey: outkey + }; + if (params.outgroup == null) { + params.outgroup = params.group; + } + if (params.outkey == null) { + params.outkey = params.key; + } + Map.__super__.constructor.call(this, params); + } + + return Map; + +})(multi(exports.MapIn, exports.MapOut)); + +exports.map = factory(exports.Map); + +exports.toBehaviour = function() { + var args, behaviour; + behaviour = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + if (args.length > 0) { + return exports.map.apply(exports, [behaviour].concat(slice.call(args))); + } else { + return behaviour; + } +}; + +exports.soft = function() { + return exports.map.apply(exports, arguments).option(option.softTakeover); +}; + +exports.toggle = function() { + var args, offValue, onValue; + offValue = arguments[0], onValue = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; + return exports.map.apply(exports, args).transform(function(ev) { + if (ev.pressed) { + return onValue; + } else { + return offValue; + } + }); +}; + +exports.set = function() { + var args, valueToSet; + valueToSet = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.toggle.apply(exports, [valueToSet, null].concat(slice.call(args))); +}; + +exports.Chooser = (function(superClass) { + extend1(Chooser, superClass); + + function Chooser(arg) { + var ref3; + ref3 = arg != null ? arg : {}, this.autoExclusive = ref3.autoExclusive, this.onDisable = ref3.onDisable; + Chooser.__super__.constructor.apply(this, arguments); + this._selectedIndex = null; + this._chooseOptions = []; + this._chooseActivators = []; + this._chooseSelectors = []; + this._chooseHandles = []; + } + + Chooser.prototype.add = function(group, key, listen) { + var activator, idx; + if (listen == null) { + listen = null; + } + idx = this._chooseOptions.length; + activator = exports.map(group, key).transform((function(_this) { + return function(ev) { + if (ev.pressed) { + _this.activate(idx); + } + return null; + }; + })(this)); + this._chooseOptions.push([group, key, listen]); + this._chooseActivators.push(activator); + return activator; + }; + + Chooser.prototype.enable = function(script) { + var engine, group, i, key, len, listen, ref3, ref4; + Chooser.__super__.enable.apply(this, arguments); + if (this._updateValueHandler == null) { + this._updateValueHandler = script.registerHandler((function(_this) { + return function() { + return _this._updateValue(); + }; + })(this)); + } + engine = script.mixxx.engine; + ref3 = this._chooseOptions; + for (i = 0, len = ref3.length; i < len; i++) { + ref4 = ref3[i], group = ref4[0], key = ref4[1], listen = ref4[2]; + if (listen == null) { + listen = key; + } + engine.connectControl(group, listen, this._updateValueHandler); + } + return this._updateValue(); + }; + + Chooser.prototype.disable = function(script) { + var engine, group, i, key, len, listen, ref3, ref4; + assert(this._updateValueHandler); + engine = script.mixxx.engine; + ref3 = this._chooseOptions; + for (i = 0, len = ref3.length; i < len; i++) { + ref4 = ref3[i], group = ref4[0], key = ref4[1], listen = ref4[2]; + if (listen == null) { + listen = key; + } + engine.connectControl(group, listen, this._updateValueHandler, true); + } + return Chooser.__super__.disable.apply(this, arguments); + }; + + Chooser.prototype.activator = function(idx) { + assert((0 <= idx && idx < this._chooseOptions.length)); + return this._chooseActivators[idx]; + }; + + Chooser.prototype.selector = function() { + var select, selector; + select = (function(_this) { + return function(ev) { + var v; + v = (ev.value / 128.0 * _this._chooseOptions.length).clamp(0, _this._chooseOptions.length - 1); + _this._update({ + index: Math.floor(v) + }); + return v; + }; + })(this); + select.inverse = (function(_this) { + return function(v) { + return v / _this._chooseOptions.length * 128.0; + }; + })(this); + selector = extend(exports.transform(select), { + _updateValue: function(newv) { + if (Math.floor(newv) !== Math.floor(this.value)) { + return this.value = this.output.value = newv; + } + } + }); + this._chooseSelectors.push(selector); + return selector; + }; + + Chooser.prototype.momentary = function() { + return exports.action({ + press: (function(_this) { + return function() { + return _this._update({ + enable: true + }); + }; + })(this), + release: (function(_this) { + return function() { + return _this._update({ + enable: false + }); + }; + })(this) + }); + }; + + Chooser.prototype.activate = function(idx) { + this._update({ + index: idx, + enable: true + }); + return this; + }; + + Chooser.prototype.select = function(idx) { + if (this.actor != null) { + this._update({ + index: idx, + enable: true + }); + } else { + this._selectedIndex = idx; + } + return this; + }; + + Chooser.prototype.onMidiEvent = function(event) { + var enable; + if (event.pressed) { + enable = !this.value; + this._update({ + enable: enable + }); + if (!enable) { + return typeof this.onDisable === "function" ? this.onDisable() : void 0; + } + } + }; + + Chooser.prototype._update = function(arg) { + var enable, group, i, idx, index, key, len, listen, ref3, ref4, ref5, ref6, ref7, script; + ref3 = arg != null ? arg : {}, index = ref3.index, enable = ref3.enable; + if (enable == null) { + enable = this.value; + } + if (index == null) { + index = this._selectedIndex; + } + index = index != null ? index.clamp(0, this._chooseOptions.length - 1) : void 0; + if (index !== this._selectedIndex || enable !== this.value) { + script = (ref4 = this.script) != null ? ref4 : this._chooseActivators[index].script; + if (index != null) { + ref5 = this._chooseOptions[index], group = ref5[0], key = ref5[1], listen = ref5[2]; + script.mixxx.engine.setValue(group, key, enable); + } + if (!this.autoExclusive || !enable) { + ref6 = this._chooseOptions; + for (idx = i = 0, len = ref6.length; i < len; idx = ++i) { + ref7 = ref6[idx], group = ref7[0], key = ref7[1]; + if (idx !== index) { + script.mixxx.engine.setValue(group, key, false); + } + } + } + return this._selectedIndex = index; + } + }; + + Chooser.prototype._updateValue = function() { + var engine, i, len, ref3, selector; + if (this.script != null) { + engine = this.script.mixxx.engine; + this.value = this.output.value = _.some(this._chooseOptions, function(arg) { + var group, key, listen; + group = arg[0], key = arg[1], listen = arg[2]; + if (listen == null) { + listen = key; + } + return engine.getValue(group, listen); + }); + ref3 = this._chooseSelectors; + for (i = 0, len = ref3.length; i < len; i++) { + selector = ref3[i]; + selector._updateValue(this._selectedIndex); + } + } + return this; + }; + + return Chooser; + +})(exports.Output); + +exports.chooser = factory(exports.Chooser); + +exports.When = (function(superClass) { + extend1(When, superClass); + + function When() { + var _condition, base, wrapped; + _condition = arguments[0], wrapped = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this._condition = _condition; + this["else"] = (function(_this) { + return function() { + return _this._else.apply(_this, arguments); + }; + })(this); + this["else"].when = (function(_this) { + return function() { + return _this._elseWhen.apply(_this, arguments); + }; + })(this); + this.when = this["else"].when; + this.else_ = this["else"]; + When.__super__.constructor.call(this); + this._wrapped = exports.toBehaviour.apply(exports, wrapped); + this._condition.on('value', (function(_this) { + return function() { + return _this._update(); + }; + })(this)); + if (this._lastCondition !== 'no-more-negations') { + this._lastCondition = this._condition; + if ((base = this._lastCondition).negation == null) { + base.negation = value.not(this._condition); + } + } + } + + When.prototype.option = function() { + var ref3; + When.__super__.option.apply(this, arguments); + (ref3 = this._wrapped).option.apply(ref3, arguments); + return this; + }; + + When.prototype._elseWhen = function() { + var args, condition, nextCondition; + condition = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + assert(this._lastCondition != null, "Can not define more conditions after 'else'"); + nextCondition = value.and(condition, value.not(this._lastCondition)); + nextCondition.negation = value.and(this._lastCondition.negation, value.not(condition)); + this._lastCondition = nextCondition; + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(exports.When, [nextCondition].concat(slice.call(args)), function(){}); + }; + + When.prototype._else = function() { + var args, nextCondition; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastCondition != null, "Can not define more conditions after 'else'"); + nextCondition = this._lastCondition.negation; + nextCondition.negation = 'no-more-negations'; + delete this._lastCondition; + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(exports.When, [nextCondition].concat(slice.call(args)), function(){}); + }; + + When.prototype.enable = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + When.__super__.enable.apply(this, arguments); + this._enableOn = args; + this._enableRequested = true; + return this._update(); + }; + + When.prototype.disable = function() { + this._enableRequested = false; + this._update(); + return When.__super__.disable.apply(this, arguments); + }; + + When.prototype._update = function() { + var ref3, ref4; + this.value = this._enableRequested && this._condition.value; + if (this._wrapped.actor && !this.value) { + (ref3 = this._wrapped).disable.apply(ref3, this._enableOn); + } + if (!this._wrapped.actor && this.value) { + return (ref4 = this._wrapped).enable.apply(ref4, this._enableOn); + } + }; + + When.prototype.directOutMapping = function() { + return null; + }; + + When.prototype.directInMapping = function() { + return null; + }; + + return When; + +})(exports.Behaviour); + +exports.when = factory(exports.When); + +exports.Action = (function(superClass) { + extend1(Action, superClass); + + Action.prototype.minimum = true; + + function Action(action) { + this.action = action != null ? action : void 0; + Action.__super__.constructor.call(this); + if (this.onPress == null) { + this.onPress = this.action.press; + } + if (this.onRelease == null) { + this.onRelease = this.action.release; + } + } + + Action.prototype.onMidiEvent = function(ev) { + var val; + val = this.value = this.output.value = ev.pressed; + if (val) { + return typeof this.onPress === "function" ? this.onPress() : void 0; + } else { + return typeof this.onRelease === "function" ? this.onRelease() : void 0; + } + }; + + return Action; + +})(exports.Output); + +exports.action = factory(exports.Action); + +exports.punchIn = function(threshold, threshold2) { + var inThreshold, oldxfader; + if (threshold2 == null) { + threshold2 = void 0; + } + oldxfader = void 0; + inThreshold = function(newxfader, threshold) { + return (threshold < 0 && newxfader < threshold) || (threshold > 0 && newxfader > threshold); + }; + return exports.action({ + press: function() { + var engine, newxfader; + engine = this.script.mixxx.engine; + newxfader = engine.getValue("[Master]", "crossfader"); + if (inThreshold(newxfader, threshold) || ((threshold2 != null) && inThreshold(newxfader, threshold2))) { + oldxfader = newxfader; + return engine.setValue("[Master]", "crossfader", 0); + } + }, + release: function() { + var engine; + engine = this.script.mixxx.engine; + if (oldxfader != null) { + engine.setValue("[Master]", "crossfader", oldxfader); + return oldxfader = void 0; + } + } + }); +}; + +exports.scratchEnable = function(deck, intervalsPerRev, rpm, alpha, beta, ramp) { + if (intervalsPerRev == null) { + intervalsPerRev = 128 * 4; + } + if (rpm == null) { + rpm = 44.0; + } + if (alpha == null) { + alpha = 1.0 / 8.0; + } + if (beta == null) { + beta = 1.0 / 8.0 / 32.0; + } + if (ramp == null) { + ramp = true; + } + return exports.action({ + press: function() { + var enable; + enable = this.script.mixxx.engine.scratchEnable; + return enable(deck, intervalsPerRev, rpm, alpha, beta, ramp); + }, + release: function() { + return this.script.mixxx.engine.scratchDisable(deck, ramp); + } + }); +}; + +exports.scratchTick = function(deck, transform) { + if (transform == null) { + transform = function(x) { + return x; + }; + } + return exports.call(function(ev) { + var engine; + engine = this.script.mixxx.engine; + return engine.scratchTick(deck, transform(ev.value)); + }); +}; + +exports.spinback = function() { + var args, deck; + deck = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.modifier().on('value', function() { + var ref3; + return (ref3 = this.script.mixxx.engine).spinback.apply(ref3, [deck, this.value].concat(slice.call(args))); + }); +}; + +exports.brake = function() { + var args, deck; + deck = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + return exports.modifier().on('value', function() { + var ref3; + return (ref3 = this.script.mixxx.engine).brake.apply(ref3, [deck, this.value].concat(slice.call(args))); + }); +}; + +exports.playhead = function(g) { + return exports.mapOut(g, "playposition").meter((function() { + var step; + step = 0; + return function(pos) { + var duration, engine; + engine = this.script.mixxx.engine; + duration = (function() { + switch (false) { + case !!engine.getValue(g, "play"): + return void 0; + case !(pos > .9): + return 5; + case !(pos > .8): + return 9; + case !(pos > .75): + return 13; + default: + return void 0; + } + })(); + if (duration != null) { + step = (step + 1) % duration; + if (step > duration / 2) { + return 0; + } else { + return pos * 127; + } + } else { + step = 0; + return pos * 127; + } + }; + })()); +}; + +exports.beatEffect = function(channel, type) { + var i, len, result, size, sizes; + if (type == null) { + type = ''; + } + sizes = ["0.0625", "0.125", "0.25", "0.5", "1", "2", "4", "8", "16", "32", "64"]; + result = exports.chooser({ + autoExclusive: true, + onDisable: function() { + var engine; + engine = this.script.mixxx.engine; + if (type !== 'roll' && engine.getValue(channel, "loop_enabled")) { + return engine.setValue(channel, "reloop_exit", true); + } + } + }); + for (i = 0, len = sizes.length; i < len; i++) { + size = sizes[i]; + result.add(channel, "beatloop" + type + "_" + size + "_activate", "beatloop_" + size + "_enabled"); + } + return result.select(4); +}; + +exports.stutter = function(group, beats) { + var tick; + if (beats == null) { + beats = 0.25; + } + tick = function() { + var engine, gain, newgain; + engine = this.script.mixxx.engine; + gain = engine.getValue(group, "pregain"); + newgain = gain > 0 ? (this._oldgain = gain, 0) : this._oldgain; + return engine.setValue(group, "pregain", newgain); + }; + return exports.action({ + press: function() { + var bpm, delta, engine; + engine = this.script.mixxx.engine; + bpm = engine.getValue(group, "bpm"); + delta = beats * 60000 / bpm; + if (this._timerHandle == null) { + this._timerHandle = this.script.registerHandler(bind(tick, this)); + } + return this._timerId != null ? this._timerId : this._timerId = engine.beginTimer(delta, this._timerHandle); + }, + release: function() { + var engine; + engine = this.script.mixxx.engine; + engine.stopTimer(this._timerId); + if (this._oldgain != null) { + engine.setValue(group, "pregain", this._oldgain); + } + delete this._timerId; + return delete this._oldgain; + } + }); +}; + + +},{"./transform":21,"./util":22,"./value":23,"events":10,"heterarchy":13,"underscore":16}],18:[function(require,module,exports){ +var assert, exports, konsole; + +assert = require('./util').assert; + +konsole = this; + +exports = konsole; + +if (konsole.log == null) { + konsole.log = function() { + return print("" + arguments); + }; +} + +if (konsole.info == null) { + konsole.info = konsole.log; +} + +if (konsole.warn == null) { + konsole.warn = konsole.log; +} + +if (konsole.error == null) { + konsole.error = konsole.log; +} + +if (konsole.time == null) { + konsole.time = function() { + return assert(False, "time not implemented in konsole"); + }; +} + +if (konsole.timeEnd == null) { + konsole.timeEnd = function() { + return assert(False, "time not implemented in konsole"); + }; +} + +if (konsole.trace == null) { + konsole.trace = function() { + var err; + err = new Error(); + err.name = "Trace"; + err.message = "" + arguments; + return konsole.error(err.stack); + }; +} + +if (konsole.dir == null) { + konsole.dir = function() { + return konsole.log(object + "\n"); + }; +} + +if (konsole.assert == null) { + konsole.assert = assert; +} + + +},{"./util":22}],19:[function(require,module,exports){ +var MIDI_CC, MIDI_NOTE_OFF, MIDI_NOTE_ON, MIDI_PITCHBEND, assert, behaviour, ccIds, event, extend, factory, hexStr, indent, joinLn, midiId, multi, noteIds, noteOnIds, pbIds, ref, ref1, some, xmlTag, + slice = [].slice, + extend1 = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + +multi = require('heterarchy').multi; + +ref = require('./util'), indent = ref.indent, hexStr = ref.hexStr, assert = ref.assert, factory = ref.factory, xmlTag = ref.xmlTag, joinLn = ref.joinLn; + +behaviour = require('./behaviour'); + +ref1 = require('underscore'), some = ref1.some, extend = ref1.extend; + +exports.MIDI_NOTE_ON = MIDI_NOTE_ON = 0x9; + +exports.MIDI_NOTE_OFF = MIDI_NOTE_OFF = 0x8; + +exports.MIDI_CC = MIDI_CC = 0xB; + +exports.MIDI_PITCHBEND = MIDI_PITCHBEND = 0xE; + +midiId = function(message, midino, channel) { + if (message == null) { + message = MIDI_CC; + } + if (midino == null) { + midino = 0; + } + if (channel == null) { + channel = 0; + } + return { + message: message, + midino: midino, + channel: channel, + status: function() { + return (this.message << 4) | this.channel; + }, + configMidi: function(depth) { + return (indent(depth)) + "" + (hexStr(this.status())) + "\n" + (indent(depth)) + "" + (hexStr(this.midino)) + ""; + } + }; +}; + +exports.midiId = midiId; + +pbIds = function() { + return [midiId.apply(null, [MIDI_PITCHBEND, 0].concat(slice.call(arguments)))]; +}; + +noteOnIds = function() { + return [midiId.apply(null, [MIDI_NOTE_ON].concat(slice.call(arguments)))]; +}; + +noteIds = function() { + return [midiId.apply(null, [MIDI_NOTE_ON].concat(slice.call(arguments))), midiId.apply(null, [MIDI_NOTE_OFF].concat(slice.call(arguments)))]; +}; + +ccIds = function() { + return [midiId.apply(null, [MIDI_CC].concat(slice.call(arguments)))]; +}; + +exports.pbIds = pbIds; + +exports.noteOnIds = noteOnIds; + +exports.noteIds = noteIds; + +exports.ccIds = ccIds; + +exports.event = event = function(channel, control, value, status, group) { + return { + channel: channel, + control: control, + value: (function() { + switch (status >> 4) { + case MIDI_PITCHBEND: + return (value * 128.0 + control) / 128.0; + default: + return value; + } + })(), + status: status, + group: group, + message: function() { + return this.status >> 4; + }, + pressed: status >> 4 !== MIDI_NOTE_OFF && value + }; +}; + +exports.Control = (function(superClass) { + extend1(Control, superClass); + + function Control() { + var args, ids; + ids = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this.ids = ids != null ? ids : [midiId()]; + this["else"] = (function(_this) { + return function() { + return _this._else.apply(_this, arguments); + }; + })(this); + this["else"].when = (function(_this) { + return function() { + return _this._elseWhen.apply(_this, arguments); + }; + })(this); + this.else_ = this["else"]; + Control.__super__.constructor.call(this); + if (!(this.ids instanceof Array)) { + this.ids = ccIds.apply(null, [this.ids].concat(slice.call(args))); + } + this._behaviours = []; + if (typeof this._controlRegistry === "function") { + this._controlRegistry(this); + } + } + + Control.prototype.does = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit); + this._behaviours.push(this.registerBehaviour(behaviour.toBehaviour.apply(behaviour, args))); + return this; + }; + + Control.prototype.when = function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit); + this._lastWhen = behaviour.when.apply(behaviour, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + return this; + }; + + Control.prototype._elseWhen = function() { + var args, ref2; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastWhen != null, "'elseWhen' must be preceded by 'when' or 'elseWhen'"); + this._lastWhen = (ref2 = this._lastWhen["else"]).when.apply(ref2, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + return this; + }; + + Control.prototype._else = function() { + var args, ref2; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(this._lastWhen != null, "'else' must be preceded by 'when' or 'elseWhen'"); + this._lastWhen = (ref2 = this._lastWhen)["else"].apply(ref2, args); + this._behaviours.push(this.registerBehaviour(this._lastWhen)); + this._lastWhen = void 0; + return this; + }; + + Control.prototype.init = function(script) { + var b, i, len, ref2; + this.script = script; + assert(!this._isInit); + ref2 = this._behaviours; + for (i = 0, len = ref2.length; i < len; i++) { + b = ref2[i]; + b.enable(script, this); + } + return this._isInit = true; + }; + + Control.prototype.shutdown = function(script) { + var b, i, len, ref2; + assert(script === this.script); + assert(this._isInit); + ref2 = this._behaviours; + for (i = 0, len = ref2.length; i < len; i++) { + b = ref2[i]; + b.disable(script, this); + } + this._isInit = false; + return delete this.script; + }; + + Control.prototype.registerBehaviour = function(b) { + return b; + }; + + Control.prototype.configInputs = function(depth, script) {}; + + Control.prototype.configOutputs = function(depth, script) {}; + + Control.prototype.setRegistry = function(registry) { + assert((this._controlRegistry == null) || (registry == null)); + return this._controlRegistry = registry; + }; + + return Control; + +})(behaviour.Actor); + +exports.InControl = (function(superClass) { + extend1(InControl, superClass); + + function InControl() { + return InControl.__super__.constructor.apply(this, arguments); + } + + InControl.prototype.init = function(script) { + InControl.__super__.init.apply(this, arguments); + if (this.needsHandler()) { + return script.registerHandler(((function(_this) { + return function() { + var args; + args = 1 <= arguments.length ? slice.call(arguments, 0) : []; + return _this.emit('event', event.apply(null, args)); + }; + })(this)), this.handlerId()); + } + }; + + InControl.prototype.option = function() { + var beh, i, len, options, ref2, ref3; + options = 1 <= arguments.length ? slice.call(arguments, 0) : []; + (ref2 = (this._options != null ? this._options : this._options = [])).push.apply(ref2, options); + ref3 = this._behaviours; + for (i = 0, len = ref3.length; i < len; i++) { + beh = ref3[i]; + beh.option.apply(beh, options); + } + return this; + }; + + InControl.property('options', function() { + return behaviour.makeOptionsChooser(this); + }); + + InControl.prototype.registerBehaviour = function(beh) { + if (this._options != null) { + beh.option.apply(beh, this._options); + } + return beh; + }; + + InControl.prototype.needsHandler = function() { + return this._behaviours.length !== 1 || !this._behaviours[0].directInMapping() || some(this._behaviours[0]._options, function(opt) { + return !opt.name; + }); + }; + + InControl.prototype.handlerId = function() { + return "x" + (this.ids[0].status().toString(16)) + "_x" + (this.ids[0].midino.toString(16)); + }; + + InControl.prototype.configInputs = function(depth, script) { + var id, mapping; + if (this.needsHandler()) { + mapping = { + group: "[Master]", + key: script.handlerKey(this.handlerId()) + }; + } else { + mapping = this._behaviours[0].directInMapping(); + } + return joinLn((function() { + var i, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + results.push(this.configInMapping(depth, mapping, id)); + } + return results; + }).call(this)); + }; + + InControl.prototype.configInMapping = function(depth, mapping, id) { + return (indent(depth)) + "\n" + (indent(depth + 1)) + "" + mapping.group + "\n" + (indent(depth + 1)) + "" + mapping.key + "\n" + (id.configMidi(depth + 1)) + "\n" + (indent(depth + 1)) + "\n" + (this.configOptions(depth + 2)) + "\n" + (indent(depth + 1)) + "\n" + (indent(depth)) + ""; + }; + + InControl.prototype.configOptions = function(depth) { + var opt, ref2; + if (this.needsHandler()) { + return (indent(depth)) + ""; + } else if (((ref2 = this._behaviours[0]._options) != null ? ref2.length : void 0) > 0) { + return joinLn((function() { + var i, len, ref3, results; + ref3 = this._behaviours[0]._options; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + opt = ref3[i]; + if (opt.name != null) { + results.push((indent(depth)) + "<" + opt.name + "/>"); + } else { + results.push(void 0); + } + } + return results; + }).call(this)); + } else { + return (indent(depth)) + ""; + } + }; + + return InControl; + +})(exports.Control); + +exports.OutControl = (function(superClass) { + extend1(OutControl, superClass); + + function OutControl() { + OutControl.__super__.constructor.apply(this, arguments); + this._states = { + on: 0x7f, + off: 0x00, + disable: 0x00 + }; + } + + OutControl.prototype.send = function(state) { + return this.doSend(state); + }; + + OutControl.prototype.states = function(states) { + extend(this._states, states); + return this; + }; + + OutControl.prototype.doSend = function(state) { + var i, id, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + if (id.message !== MIDI_NOTE_OFF) { + if (state in this._states) { + results.push(this.script.mixxx.midi.sendShortMsg(id.status(), id.midino, this._states[state])); + } else { + results.push(this.script.mixxx.midi.sendShortMsg(id.status(), id.midino, state)); + } + } else { + results.push(void 0); + } + } + return results; + }; + + OutControl.prototype.init = function() { + if (!this.needsSend()) { + this.send = void 0; + } + return OutControl.__super__.init.apply(this, arguments); + }; + + OutControl.prototype.shutdown = function() { + this.doSend('disable'); + return OutControl.__super__.shutdown.apply(this, arguments); + }; + + OutControl.prototype.needsSend = function() { + return this._behaviours.length !== 1 || !this._behaviours[0].directOutMapping(); + }; + + OutControl.prototype.configOutputs = function(depth, script) { + var id, mapping; + mapping = !this.needsSend() && this._behaviours[0].directOutMapping(); + if (mapping) { + return joinLn((function() { + var i, len, ref2, results; + ref2 = this.ids; + results = []; + for (i = 0, len = ref2.length; i < len; i++) { + id = ref2[i]; + results.push(this.configOutMapping(depth, mapping, id)); + } + return results; + }).call(this)); + } + }; + + OutControl.prototype.configOutMapping = function(depth, mapping, id) { + var options; + if (id.message !== MIDI_NOTE_OFF) { + options = joinLn([xmlTag('minimum', mapping.minimum, depth + 1), xmlTag('maximum', mapping.maximum, depth + 1)]); + return (indent(depth)) + "\n" + (indent(depth + 1)) + "" + mapping.group + "\n" + (indent(depth + 1)) + "" + mapping.key + "\n" + (id.configMidi(depth + 1)) + "\n" + (indent(depth + 1)) + "" + (hexStr(this._states['on'])) + "\n" + (indent(depth + 1)) + "" + (hexStr(this._states['off'])) + "\n" + options + "\n" + (indent(depth)) + ""; + } + }; + + return OutControl; + +})(exports.Control); + +exports.input = factory(exports.InControl); + +exports.output = factory(exports.OutControl); + +exports.InOutControl = (function(superClass) { + extend1(InOutControl, superClass); + + function InOutControl() { + return InOutControl.__super__.constructor.apply(this, arguments); + } + + return InOutControl; + +})(multi(exports.InControl, exports.OutControl)); + +exports.control = factory(exports.InOutControl); + + +},{"./behaviour":17,"./util":22,"heterarchy":13,"underscore":16}],20:[function(require,module,exports){ +(function (process){ +var Control, S, _, assert, basename, bind, catching, flatten, indent, issubclass, mro, ref, ref1, ref2, xmlEscape, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, + slice = [].slice; + +ref = require('underscore'), flatten = ref.flatten, bind = ref.bind; + +ref1 = require('heterarchy'), issubclass = ref1.issubclass, mro = ref1.mro; + +Control = require('./control').Control; + +ref2 = require('./util'), indent = ref2.indent, xmlEscape = ref2.xmlEscape, catching = ref2.catching, assert = ref2.assert; + +require('./console'); + +basename = require('path').basename; + +S = require('string'); + +_ = require('underscore'); + +exports.nameFromFilename = function(fname) { + var extensions, name; + extensions = [".mixco.coffee", ".mixco.litcoffee", ".mixco.js", ".mixco"]; + fname = basename(fname); + assert(_.some(extensions, function(x) { + return S(fname).endsWith(x); + }), "Script file name: " + fname + " must end in one of: " + extensions); + name = extensions.reduce((function(fname, ext) { + return fname.replace(ext, ""); + }), fname); + assert(name.match(/^[a-zA-Z_$][0-9a-zA-Z_$].*$/, "Script name must be a valid JavaScript identifier")); + return name; +}; + +exports.register = function(targetModule, scriptTypeOrDefinition) { + var instance, name, scriptType; + name = targetModule.filename != null ? exports.nameFromFilename(targetModule.filename) : typeof MIXCO_SCRIPT_FILENAME !== "undefined" && MIXCO_SCRIPT_FILENAME !== null ? exports.nameFromFilename(MIXCO_SCRIPT_FILENAME) : assert(false, "Invalid script"); + scriptType = issubclass(scriptTypeOrDefinition, exports.Script) ? scriptTypeOrDefinition : exports.create(scriptTypeOrDefinition); + instance = new scriptType; + instance.__registeredName = name; + targetModule.exports[name] = instance; + if (targetModule === require.main) { + return instance.main(); + } +}; + +exports.create = function(scriptDefinition) { + var NewScript, constructor, init, k, shutdown, special, v; + assert(scriptDefinition.constructor != null, "Script definition must have a constructor"); + constructor = scriptDefinition.constructor, init = scriptDefinition.init, shutdown = scriptDefinition.shutdown; + NewScript = (function(superClass) { + extend(NewScript, superClass); + + function NewScript() { + NewScript.__super__.constructor.apply(this, arguments); + try { + Control.prototype.setRegistry(bind(this.add, this)); + constructor.apply(this, arguments); + } finally { + Control.prototype.setRegistry(null); + } + this; + } + + NewScript.prototype.init = function() { + var ref3; + if ((ref3 = this.preinit) != null) { + ref3.apply(this, arguments); + } + NewScript.__super__.init.apply(this, arguments); + return init != null ? init.apply(this, arguments) : void 0; + }; + + NewScript.prototype.shutdown = function() { + var ref3; + if (shutdown != null) { + shutdown.apply(this, arguments); + } + NewScript.__super__.shutdown.apply(this, arguments); + return (ref3 = this.postshutdown) != null ? ref3.apply(this, arguments) : void 0; + }; + + return NewScript; + + })(exports.Script); + special = ['name', 'constructor', 'init', 'shutdown']; + for (k in scriptDefinition) { + v = scriptDefinition[k]; + if (indexOf.call(special, k) < 0) { + NewScript.prototype[k] = v; + } + } + return NewScript; +}; + +exports.Script = (function() { + Script.prototype.info = { + name: "[mixco] Generic Script", + author: "Juan Pedro Bolivar Puente ", + description: "", + forums: "", + wiki: "" + }; + + Script.property('name', { + get: function() { + assert(this.__registeredName, "Script must be registered"); + return this.__registeredName; + } + }); + + Script.prototype.add = function() { + var controls, ref3; + controls = 1 <= arguments.length ? slice.call(arguments, 0) : []; + assert(!this._isInit, "Can only add controls in constructor"); + return (ref3 = this.controls).push.apply(ref3, flatten(controls)); + }; + + Script.prototype.init = catching(function() { + var control, i, len, ref3, results; + this._isInit = true; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.init(this)); + } + return results; + }); + + Script.prototype.shutdown = catching(function() { + var control, i, len, ref3; + ref3 = this.controls; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + control.shutdown(this); + } + return delete this._isInit; + }); + + function Script() { + this.controls = []; + } + + Script.prototype.mixxx = { + engine: (typeof engine !== "undefined" && engine !== null ? engine : void 0), + midi: (typeof midi !== "undefined" && midi !== null ? midi : void 0), + script: (typeof script !== "undefined" && script !== null ? script : void 0) + }; + + Script.prototype.main = function() { + var arg, i, len, ref3, results; + ref3 = process.argv; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + arg = ref3[i]; + if (arg === '-h' || arg === '--help') { + console.info(this.help()); + break; + } + if (arg === '-g' || arg === '--generate-config') { + console.info(this.config()); + break; + } else { + results.push(void 0); + } + } + return results; + }; + + Script.prototype.help = function() { + return "Mixxx Controller Script\n=======================\n\nName: " + this.info.name + "\nAuthor: " + this.info.author + "\nDescription: " + this.info.description + "\nForums: " + this.info.description + "\n\nUsage\n-----\n1. Generate Mixxx config:\n coffee " + this.name + ".coffee -g > " + this.name + ".xml\n\n2. Generate Mixxx script:\n coffee -c " + this.name + ".coffee"; + }; + + Script.prototype.config = function() { + return "\n\n" + (indent(1)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.name)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.author)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.description)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.wiki)) + "\n" + (indent(2)) + "" + (xmlEscape(this.info.forums)) + "\n" + (indent(1)) + "\n" + (indent(1)) + "\n" + (indent(2)) + "\n" + (indent(3)) + "\n" + (indent(2)) + "\n" + (indent(2)) + "\n" + (this.configInputs(3)) + "\n" + (indent(2)) + "\n" + (indent(2)) + "\n" + (this.configOutputs(3)) + "\n" + (indent(2)) + "\n" + (indent(1)) + "\n"; + }; + + Script.prototype.configInputs = function(depth) { + var control; + return ((function() { + var i, len, ref3, results; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.configInputs(depth, this)); + } + return results; + }).call(this)).filter(function(x) { + return x; + }).join('\n'); + }; + + Script.prototype.configOutputs = function(depth) { + var control; + return ((function() { + var i, len, ref3, results; + ref3 = this.controls; + results = []; + for (i = 0, len = ref3.length; i < len; i++) { + control = ref3[i]; + results.push(control.configOutputs(depth, this)); + } + return results; + }).call(this)).filter(function(x) { + return x; + }).join('\n'); + }; + + Script.prototype._nextCallbackId = 1; + + Script.prototype.registerHandler = function(callback, id) { + var handlerName; + if (id == null) { + id = void 0; + } + id || (id = this._nextCallbackId++); + handlerName = "__handle_" + id; + assert(!this[handlerName], "Handlers can be registered only once (" + handlerName + ")"); + this[handlerName] = callback; + return this.handlerKey(id); + }; + + Script.prototype.handlerKey = function(id) { + if (id == null) { + id = void 0; + } + if (id == null) { + id = this._nextCallbackId - 1; + } + return this.name + ".__handle_" + id; + }; + + return Script; + +})(); + + +}).call(this,require('_process')) +},{"./console":18,"./control":19,"./util":22,"_process":12,"heterarchy":13,"path":11,"string":15,"underscore":16}],21:[function(require,module,exports){ +var binaryT, centeredT, defaultT, identityT, linearT, momentaryT, + slice = [].slice; + +exports.identity = function(v) { + return v; +}; + +exports.identity.inverse = exports.identity; + +exports.momentary = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } +}; + +exports.momentary.inverse = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } +}; + +exports.binary = function(v, oldv) { + if (v > 0) { + return !oldv; + } else { + return null; + } +}; + +exports.binary.inverse = function(v) { + if (v > 0) { + return 1; + } else { + return 0; + } +}; + +exports.linear = function(v, min, max) { + return min + v * (max - min); +}; + +exports.linear.inverse = function(v, min, max) { + return (v - min) / (max - min); +}; + +exports.centered = function(v, min, center, max) { + if (v < .5) { + return linear(v * 2, min, center); + } else { + return linear((v - .5) * 2, center, max); + } +}; + +exports.centered.inverse = function(v, min, center, max) { + if (v < center) { + return 0.5 * linear.inverse(v, min, center); + } else { + return 0.5 + 0.5 * linear.inverse(v, center, max); + } +}; + +exports.transform = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.value / 127.0].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return 127 * f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; +}; + +exports.transformI = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.value].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; +}; + +exports.transformB = function() { + var args, f, result; + f = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; + result = function(ev, oldv) { + return f.apply(null, [ev.pressed / 127.0].concat(slice.call(args), [oldv])); + }; + result.inverse = function(v) { + return 127 * f.inverse.apply(f, [v].concat(slice.call(args))); + }; + return result; +}; + +exports.identityT = identityT = exports.transformI(exports.identity); + +exports.momentaryT = momentaryT = exports.transformB(exports.momentary); + +exports.binaryT = binaryT = exports.transformB(exports.binary); + +exports.linearT = linearT = function() { + return exports.transform.apply(exports, [exports.linear].concat(slice.call(arguments))); +}; + +exports.centeredT = centeredT = function() { + return exports.transform.apply(exports, [exports.centered].concat(slice.call(arguments))); +}; + +exports.defaultT = defaultT = linearT(0.0, 1.0); + +exports.mappings = { + "beatloop_0.0625_activate": momentaryT, + "beatloop_0.0625_toggle": momentaryT, + "beatloop_0.125_activate": momentaryT, + "beatloop_0.125_toggle": momentaryT, + "beatloop_0.5_activate": momentaryT, + "beatloop_0.5_toggle": momentaryT, + "beatlooproll_0.0625_activate": momentaryT, + "beatlooproll_0.125_activate": momentaryT, + "beatlooproll_0.5_activate": momentaryT, + back: momentaryT, + balance: linearT(-1.0, 1.0), + beatloop_16_activate: momentaryT, + beatloop_16_toggle: momentaryT, + beatloop_1_activate: momentaryT, + beatloop_1_toggle: momentaryT, + beatloop_2_activate: momentaryT, + beatloop_2_toggle: momentaryT, + beatloop_32_activate: momentaryT, + beatloop_32_toggle: momentaryT, + beatloop_4_activate: momentaryT, + beatloop_4_toggle: momentaryT, + beatloop_8_activate: momentaryT, + beatloop_8_toggle: momentaryT, + beatlooproll_16_activate: momentaryT, + beatlooproll_1_activate: momentaryT, + beatlooproll_2_activate: momentaryT, + beatlooproll_32_activate: momentaryT, + beatlooproll_4_activate: momentaryT, + beatlooproll_8_activate: momentaryT, + beatloop_double: momentaryT, + beatloop_halve: momentaryT, + beatjump_4_forward: momentaryT, + beatjump_4_backward: momentaryT, + beatjump_1_forward: momentaryT, + beatjump_1_backward: momentaryT, + beats_translate_curpos: momentaryT, + beatsync: momentaryT, + beatsync_tempo: momentaryT, + crossfader: linearT(-1.0, 1.0), + cue_default: momentaryT, + eject: momentaryT, + enabled: binaryT, + filterHigh: centeredT(0.0, 1.0, 4.0), + filterHighKill: binaryT, + filterLow: centeredT(0.0, 1.0, 4.0), + filterLowKill: binaryT, + filterMid: centeredT(0.0, 1.0, 4.0), + filterMidKill: binaryT, + fwd: momentaryT, + headMix: centeredT(-1.0, 1.0), + headVolume: centeredT(0.0, 1.0, 5.0), + hotcue_1_activate: momentaryT, + hotcue_1_clear: momentaryT, + hotcue_2_activate: momentaryT, + hotcue_2_clear: momentaryT, + hotcue_3_activate: momentaryT, + hotcue_3_clear: momentaryT, + hotcue_4_activate: momentaryT, + hotcue_4_clear: momentaryT, + hotcue_5_activate: momentaryT, + hotcue_5_clear: momentaryT, + hotcue_6_activate: momentaryT, + hotcue_6_clear: momentaryT, + hotcue_7_activate: momentaryT, + hotcue_7_clear: momentaryT, + jog: identityT, + keylock: binaryT, + lfoDelay: linearT(50.0, 10000.0), + lfoDepth: defaultT, + lfoPeriod: linearT(50000.0, 2000000.0), + LoadSelectedTrack: momentaryT, + loop_double: momentaryT, + loop_enabled: binaryT, + loop_end_position: linearT, + loop_halve: momentaryT, + loop_in: momentaryT, + loop_out: momentaryT, + loop_start_position: linearT, + play: binaryT, + playposition: linearT(0.0, 1.0), + plf: binaryT, + pregain: centeredT(0.0, 1.0, 4.0), + pregain_toggle: binaryT, + rate: linearT(-1.0, 1.0), + rate_temp_down: momentaryT, + rate_temp_down_small: momentaryT, + rate_temp_up: momentaryT, + rate_temp_up_small: momentaryT, + reverse: binaryT, + scratch2: linearT(-3.0, 3.0), + scratch2_enable: binaryT, + SelectNextPlaylist: momentaryT, + SelectNextTrack: momentaryT, + SelectPrevPlaylist: momentaryT, + SelectPrevTrack: momentaryT, + SelectTrackKnob: identityT, + slip_enabled: binaryT, + super1: linearT(0.0, 10.0), + talkover: binaryT, + ToggleSelectedSidebarItem: momentaryT, + volume: defaultT, + VuMeter: defaultT, + VuMeterL: defaultT, + VuMeterR: defaultT, + wheel: linearT(-3.0, 3.0) +}; + + +},{}],22:[function(require,module,exports){ +Function.prototype.property = function(prop, desc) { + if (desc instanceof Function) { + desc = { + get: desc + }; + } + return Object.defineProperty(this.prototype, prop, desc); +}; + +Number.prototype.clamp = function(min, max) { + return Math.min(Math.max(this, min), max); +}; + +Number.prototype.sign = function() { + if (this < 0) { + return -1; + } else { + return 1; + } +}; + +Array.prototype.equals = function(other) { + return this.length === other.length && this.every(function(elem, i) { + return elem === other[i]; + }); +}; + +exports.copy = function(a, b) { + var k, v; + if (b == null) { + b = {}; + } + for (k in a) { + v = a[k]; + b[k] = v; + } + return b; +}; + +exports.catching = function(f) { + return function() { + var err, error1; + try { + return f.apply(this, arguments); + } catch (error1) { + err = error1; + return console.log("ERROR: " + err); + } + }; +}; + +exports.assert = function(value, error) { + if (error == null) { + error = void 0; + } + if (!value) { + throw new Error(error != null ? error : "Assertion failed"); + } +}; + +exports.xmlEscape = function(str) { + var ref; + return (ref = str != null ? str.replace('&', '&').replace('"', '"').replace('>', '>').replace('<', '<') : void 0) != null ? ref : ''; +}; + +exports.indent = function(depth) { + return Array(depth * 4).join(" "); +}; + +exports.hexStr = function(number) { + return "0x" + (number.toString(16)); +}; + +exports.xmlTag = function(str, value, indent) { + if (indent == null) { + indent = 0; + } + if (value != null) { + return (exports.indent(indent)) + "<" + str + ">" + value + ""; + } else { + return ""; + } +}; + +exports.joinLn = function(lines) { + return lines.filter(function(x) { + return x; + }).join('\n'); +}; + +exports.factory = function(Klass) { + return function() { + return (function(func, args, ctor) { + ctor.prototype = func.prototype; + var child = new ctor, result = func.apply(child, args); + return Object(result) === result ? result : child; + })(Klass, arguments, function(){}); + }; +}; + + +},{}],23:[function(require,module,exports){ +var events, factory, util, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty, + slice = [].slice; + +events = require('events'); + +util = require('./util'); + +factory = util.factory; + +exports.Value = (function(superClass) { + extend(Value, superClass); + + function Value(arg) { + var initial; + initial = (arg != null ? arg : {}).initial; + Value.__super__.constructor.apply(this, arguments); + this.setMaxListeners(0); + if (initial != null) { + this.value = initial; + } + } + + Value.property('value', { + get: function() { + return this._value; + }, + set: function(newValue) { + return this.setValue(newValue); + } + }); + + Value.prototype.setValue = function(newValue) { + if (this._value !== newValue) { + this._value = newValue; + this.emit('value', newValue); + } + return this._value; + }; + + return Value; + +})(events.EventEmitter); + +exports.value = factory(exports.Value); + +exports.Const = (function() { + Const.prototype.value = void 0; + + function Const(initial) { + if (initial == null) { + initial = void 0; + } + this.value = initial; + } + + Const.prototype.on = function() {}; + + Const.prototype.addListener = function() {}; + + Const.prototype.removeListener = function() {}; + + Const.prototype.listeners = function() { + return []; + }; + + return Const; + +})(); + +exports["const"] = factory(exports.Const); + +exports.Reduce = (function(superClass) { + extend(Reduce, superClass); + + function Reduce() { + var i, len, reduced, reducer, ref, v; + reducer = arguments[0], reduced = 2 <= arguments.length ? slice.call(arguments, 1) : []; + this.reducer = reducer; + this.reduced = reduced; + Reduce.__super__.constructor.call(this); + ref = this.reduced; + for (i = 0, len = ref.length; i < len; i++) { + v = ref[i]; + v.on('value', (function(_this) { + return function() { + return _this.update(); + }; + })(this)); + } + this.update(); + } + + Reduce.prototype.update = function() { + return this.value = this.reduced.reduce((function(_this) { + return function(a, b) { + return exports["const"](_this.reducer(a.value, b.value)); + }; + })(this)).value; + }; + + return Reduce; + +})(exports.Value); + +exports.reduce = factory(exports.Reduce); + +exports.and = function() { + return exports.reduce.apply(exports, [(function(a, b) { + return a && b; + })].concat(slice.call(arguments))); +}; + +exports.or = function() { + return exports.reduce.apply(exports, [(function(a, b) { + return a || b; + })].concat(slice.call(arguments))); +}; + +exports.Transform = (function(superClass) { + extend(Transform, superClass); + + function Transform(transformer, transformed) { + this.transformer = transformer; + this.transformed = transformed; + Transform.__super__.constructor.call(this); + this.transformed.on('value', (function(_this) { + return function() { + return _this.update(); + }; + })(this)); + this.update(); + } + + Transform.prototype.update = function() { + return this.value = this.transformer(this.transformed.value); + }; + + return Transform; + +})(exports.Value); + +exports.transform = factory(exports.Transform); + +exports.not = function() { + return exports.transform.apply(exports, [(function(a) { + return !a; + })].concat(slice.call(arguments))); +}; + + +},{"./util":22,"events":10}]},{},[1]); + +novation_twitch = require('/home/raskolnikov/dev/mixco/script/novation_twitch.mixco').novation_twitch; +/* End of Mixco generated script */ \ No newline at end of file diff --git a/res/controllers/novation_twitch.mixco.output.midi.xml b/res/controllers/novation_twitch.mixco.output.midi.xml new file mode 100644 index 000000000000..ed372f06afe6 --- /dev/null +++ b/res/controllers/novation_twitch.mixco.output.midi.xml @@ -0,0 +1,5159 @@ + + + + Novation Twitch + Juan Pedro Bolivar Puente <raskolnikov@gnu.org> + Controller mapping for Novation Twitch (in basic mode). + https://sinusoid.es/mixco/script/korg_nanokontrol2.mixco.html + https://github.com/arximboldi/mixco/issues + + + + + + + + [Master] + crossfader + 0xb7 + 0x8 + + + + + + [Microphone] + pregain + 0xbb + 0x3 + + + + + + [Microphone] + pregain + 0xbb + 0x7 + + + + + + [Microphone] + pregain + 0xbb + 0xb + + + + + + [Microphone] + pregain + 0xbb + 0xf + + + + + + [Microphone] + pregain + 0xbb + 0x13 + + + + + + [Microphone] + talkover + 0x9b + 0x23 + + + + + + [Microphone] + talkover + 0x8b + 0x23 + + + + + + [EffectRack1_EffectUnit1] + mix + 0xbb + 0x0 + + + + + + [EffectRack1_EffectUnit1] + mix + 0xbb + 0x4 + + + + + + [EffectRack1_EffectUnit1] + mix + 0xbb + 0x8 + + + + + + [EffectRack1_EffectUnit1] + mix + 0xbb + 0xc + + + + + + [EffectRack1_EffectUnit1] + mix + 0xbb + 0x10 + + + + + + [Master] + novation_twitch.__handle_xbb_x1 + 0xbb + 0x1 + + + + + + [Master] + novation_twitch.__handle_xbb_x1 + 0xbb + 0x5 + + + + + + [Master] + novation_twitch.__handle_xbb_x1 + 0xbb + 0x9 + + + + + + [Master] + novation_twitch.__handle_xbb_x1 + 0xbb + 0xd + + + + + + [Master] + novation_twitch.__handle_xbb_x1 + 0xbb + 0x11 + + + + + + [EffectRack1_EffectUnit1] + chain_selector + 0xbb + 0x2 + + + + + + [EffectRack1_EffectUnit1] + chain_selector + 0xbb + 0x6 + + + + + + [EffectRack1_EffectUnit1] + chain_selector + 0xbb + 0xa + + + + + + [EffectRack1_EffectUnit1] + chain_selector + 0xbb + 0xe + + + + + + [EffectRack1_EffectUnit1] + chain_selector + 0xbb + 0x12 + + + + + + [EffectRack1_EffectUnit1] + enabled + 0x9b + 0x22 + + + + + + [EffectRack1_EffectUnit1] + enabled + 0x8b + 0x22 + + + + + + [Playlist] + SelectPrevPlaylist + 0x97 + 0x54 + + + + + + [Playlist] + SelectPrevPlaylist + 0x87 + 0x54 + + + + + + [Playlist] + SelectNextPlaylist + 0x97 + 0x56 + + + + + + [Playlist] + SelectNextPlaylist + 0x87 + 0x56 + + + + + + [Master] + novation_twitch.__handle_x97_x55 + 0x97 + 0x55 + + + + + + [Master] + novation_twitch.__handle_x97_x55 + 0x87 + 0x55 + + + + + + [Master] + novation_twitch.__handle_xb7_x55 + 0xb7 + 0x55 + + + + + + [Master] + maximize_library + 0x97 + 0x50 + + + + + + [Master] + maximize_library + 0x87 + 0x50 + + + + + + [Master] + novation_twitch.__handle_x97_x51 + 0x97 + 0x51 + + + + + + [Master] + novation_twitch.__handle_x97_x51 + 0x87 + 0x51 + + + + + + [Master] + novation_twitch.__handle_x97_xa + 0x97 + 0xa + + + + + + [Master] + novation_twitch.__handle_x97_xa + 0x87 + 0xa + + + + + + [Master] + novation_twitch.__handle_x97_xa + 0x99 + 0xa + + + + + + [Master] + novation_twitch.__handle_x97_xa + 0x89 + 0xa + + + + + + [Channel1] + volume + 0xb7 + 0x7 + + + + + + [Channel1] + volume + 0xb9 + 0x7 + + + + + + [Channel1] + filterLow + 0xb7 + 0x46 + + + + + + [Channel1] + filterLow + 0xb9 + 0x46 + + + + + + [Channel1] + filterMid + 0xb7 + 0x47 + + + + + + [Channel1] + filterMid + 0xb9 + 0x47 + + + + + + [Channel1] + filterHigh + 0xb7 + 0x48 + + + + + + [Channel1] + filterHigh + 0xb9 + 0x48 + + + + + + [Channel1] + pregain + 0xb7 + 0x9 + + + + + + [Channel1] + pregain + 0xb9 + 0x9 + + + + + + [Master] + novation_twitch.__handle_xb7_x6 + 0xb7 + 0x6 + + + + + + [Master] + novation_twitch.__handle_xb7_x6 + 0xb9 + 0x6 + + + + + + [QuickEffectRack1_[Channel1]] + enabled + 0x97 + 0x6 + + + + + + [QuickEffectRack1_[Channel1]] + enabled + 0x87 + 0x6 + + + + + + [QuickEffectRack1_[Channel1]] + enabled + 0x99 + 0x6 + + + + + + [QuickEffectRack1_[Channel1]] + enabled + 0x89 + 0x6 + + + + + + [QuickEffectRack1_[Channel1]] + enabled + 0x97 + 0xd + + + + + + [QuickEffectRack1_[Channel1]] + enabled + 0x87 + 0xd + + + + + + [QuickEffectRack1_[Channel1]] + enabled + 0x99 + 0xd + + + + + + [QuickEffectRack1_[Channel1]] + enabled + 0x89 + 0xd + + + + + + [EffectRack1_EffectUnit1] + group_[Channel1]_enable + 0x9b + 0x20 + + + + + + [EffectRack1_EffectUnit1] + group_[Channel1]_enable + 0x8b + 0x20 + + + + + + [Channel1] + LoadSelectedTrack + 0x97 + 0x52 + + + + + + [Channel1] + LoadSelectedTrack + 0x87 + 0x52 + + + + + + [Channel1] + play + 0x97 + 0x17 + + + + + + [Channel1] + play + 0x87 + 0x17 + + + + + + [Channel1] + play + 0x99 + 0x17 + + + + + + [Channel1] + play + 0x89 + 0x17 + + + + + + [Channel1] + cue_default + 0x97 + 0x16 + + + + + + [Channel1] + cue_default + 0x87 + 0x16 + + + + + + [Channel1] + reverse + 0x99 + 0x16 + + + + + + [Channel1] + reverse + 0x89 + 0x16 + + + + + + [Channel1] + keylock + 0x97 + 0x12 + + + + + + [Channel1] + keylock + 0x87 + 0x12 + + + + + + [Master] + novation_twitch.__handle_x99_x12 + 0x99 + 0x12 + + + + + + [Master] + novation_twitch.__handle_x99_x12 + 0x89 + 0x12 + + + + + + [Channel1] + sync_enabled + 0x97 + 0x13 + + + + + + [Channel1] + sync_enabled + 0x87 + 0x13 + + + + + + [Channel1] + sync_enabled + 0x99 + 0x13 + + + + + + [Channel1] + sync_enabled + 0x89 + 0x13 + + + + + + [Channel1] + beats_translate_curpos + 0x97 + 0x11 + + + + + + [Channel1] + beats_translate_curpos + 0x87 + 0x11 + + + + + + [Channel1] + beats_translate_curpos + 0x99 + 0x11 + + + + + + [Channel1] + beats_translate_curpos + 0x89 + 0x11 + + + + + + [Channel1] + quantize + 0x97 + 0x10 + + + + + + [Channel1] + quantize + 0x87 + 0x10 + + + + + + [Channel1] + quantize + 0x99 + 0x10 + + + + + + [Channel1] + quantize + 0x89 + 0x10 + + + + + + [Master] + novation_twitch.__handle_x97_x3 + 0x97 + 0x3 + + + + + + [Master] + novation_twitch.__handle_x97_x3 + 0x87 + 0x3 + + + + + + [Master] + novation_twitch.__handle_x97_x3 + 0x99 + 0x3 + + + + + + [Master] + novation_twitch.__handle_x97_x3 + 0x89 + 0x3 + + + + + + [Master] + novation_twitch.__handle_xb7_x3 + 0xb7 + 0x3 + + + + + + [Master] + novation_twitch.__handle_xb7_x3 + 0xb9 + 0x3 + + + + + + [Channel1] + playposition + 0xb7 + 0x34 + + + + + + [Master] + novation_twitch.__handle_xb7_x35 + 0xb7 + 0x35 + + + + + + [Master] + novation_twitch.__handle_xb9_x35 + 0xb9 + 0x35 + + + + + + [Master] + novation_twitch.__handle_x99_x47 + 0x99 + 0x47 + + + + + + [Master] + novation_twitch.__handle_x99_x47 + 0x89 + 0x47 + + + + + + [Channel1] + hotcue_1_activate + 0x97 + 0x60 + + + + + + [Channel1] + hotcue_1_activate + 0x87 + 0x60 + + + + + + [Channel1] + hotcue_1_clear + 0x99 + 0x60 + + + + + + [Channel1] + hotcue_1_clear + 0x89 + 0x60 + + + + + + [Channel1] + hotcue_2_activate + 0x97 + 0x61 + + + + + + [Channel1] + hotcue_2_activate + 0x87 + 0x61 + + + + + + [Channel1] + hotcue_2_clear + 0x99 + 0x61 + + + + + + [Channel1] + hotcue_2_clear + 0x89 + 0x61 + + + + + + [Channel1] + hotcue_3_activate + 0x97 + 0x62 + + + + + + [Channel1] + hotcue_3_activate + 0x87 + 0x62 + + + + + + [Channel1] + hotcue_3_clear + 0x99 + 0x62 + + + + + + [Channel1] + hotcue_3_clear + 0x89 + 0x62 + + + + + + [Channel1] + hotcue_4_activate + 0x97 + 0x63 + + + + + + [Channel1] + hotcue_4_activate + 0x87 + 0x63 + + + + + + [Channel1] + hotcue_4_clear + 0x99 + 0x63 + + + + + + [Channel1] + hotcue_4_clear + 0x89 + 0x63 + + + + + + [Channel1] + hotcue_5_activate + 0x97 + 0x64 + + + + + + [Channel1] + hotcue_5_activate + 0x87 + 0x64 + + + + + + [Channel1] + hotcue_5_clear + 0x99 + 0x64 + + + + + + [Channel1] + hotcue_5_clear + 0x89 + 0x64 + + + + + + [Channel1] + hotcue_6_activate + 0x97 + 0x65 + + + + + + [Channel1] + hotcue_6_activate + 0x87 + 0x65 + + + + + + [Channel1] + hotcue_6_clear + 0x99 + 0x65 + + + + + + [Channel1] + hotcue_6_clear + 0x89 + 0x65 + + + + + + [Channel1] + hotcue_7_activate + 0x97 + 0x66 + + + + + + [Channel1] + hotcue_7_activate + 0x87 + 0x66 + + + + + + [Channel1] + hotcue_7_clear + 0x99 + 0x66 + + + + + + [Channel1] + hotcue_7_clear + 0x89 + 0x66 + + + + + + [Channel1] + hotcue_8_activate + 0x97 + 0x67 + + + + + + [Channel1] + hotcue_8_activate + 0x87 + 0x67 + + + + + + [Channel1] + hotcue_8_clear + 0x99 + 0x67 + + + + + + [Channel1] + hotcue_8_clear + 0x89 + 0x67 + + + + + + [Sampler1] + cue_preview + 0x97 + 0x68 + + + + + + [Sampler1] + cue_preview + 0x87 + 0x68 + + + + + + [Sampler1] + cue_preview + 0x99 + 0x68 + + + + + + [Sampler1] + cue_preview + 0x89 + 0x68 + + + + + + [Sampler2] + cue_preview + 0x97 + 0x69 + + + + + + [Sampler2] + cue_preview + 0x87 + 0x69 + + + + + + [Sampler2] + cue_preview + 0x99 + 0x69 + + + + + + [Sampler2] + cue_preview + 0x89 + 0x69 + + + + + + [Sampler3] + cue_preview + 0x97 + 0x6a + + + + + + [Sampler3] + cue_preview + 0x87 + 0x6a + + + + + + [Sampler3] + cue_preview + 0x99 + 0x6a + + + + + + [Sampler3] + cue_preview + 0x89 + 0x6a + + + + + + [Sampler4] + cue_preview + 0x97 + 0x6b + + + + + + [Sampler4] + cue_preview + 0x87 + 0x6b + + + + + + [Sampler4] + cue_preview + 0x99 + 0x6b + + + + + + [Sampler4] + cue_preview + 0x89 + 0x6b + + + + + + [Master] + novation_twitch.__handle_x97_x6c + 0x97 + 0x6c + + + + + + [Master] + novation_twitch.__handle_x97_x6c + 0x87 + 0x6c + + + + + + [Master] + novation_twitch.__handle_x97_x6c + 0x99 + 0x6c + + + + + + [Master] + novation_twitch.__handle_x97_x6c + 0x89 + 0x6c + + + + + + [Master] + novation_twitch.__handle_x97_x6d + 0x97 + 0x6d + + + + + + [Master] + novation_twitch.__handle_x97_x6d + 0x87 + 0x6d + + + + + + [Master] + novation_twitch.__handle_x97_x6d + 0x99 + 0x6d + + + + + + [Master] + novation_twitch.__handle_x97_x6d + 0x89 + 0x6d + + + + + + [Master] + novation_twitch.__handle_x97_x6e + 0x97 + 0x6e + + + + + + [Master] + novation_twitch.__handle_x97_x6e + 0x87 + 0x6e + + + + + + [Master] + novation_twitch.__handle_x97_x6e + 0x99 + 0x6e + + + + + + [Master] + novation_twitch.__handle_x97_x6e + 0x89 + 0x6e + + + + + + [Master] + novation_twitch.__handle_x97_x6f + 0x97 + 0x6f + + + + + + [Master] + novation_twitch.__handle_x97_x6f + 0x87 + 0x6f + + + + + + [Master] + novation_twitch.__handle_x97_x6f + 0x99 + 0x6f + + + + + + [Master] + novation_twitch.__handle_x97_x6f + 0x89 + 0x6f + + + + + + [Channel1] + beatloop_0.5_toggle + 0x97 + 0x70 + + + + + + [Channel1] + beatloop_0.5_toggle + 0x87 + 0x70 + + + + + + [Channel1] + beatloop_1_toggle + 0x97 + 0x71 + + + + + + [Channel1] + beatloop_1_toggle + 0x87 + 0x71 + + + + + + [Channel1] + beatloop_2_toggle + 0x97 + 0x72 + + + + + + [Channel1] + beatloop_2_toggle + 0x87 + 0x72 + + + + + + [Channel1] + beatloop_4_toggle + 0x97 + 0x73 + + + + + + [Channel1] + beatloop_4_toggle + 0x87 + 0x73 + + + + + + [Channel1] + beatloop_8_toggle + 0x97 + 0x74 + + + + + + [Channel1] + beatloop_8_toggle + 0x87 + 0x74 + + + + + + [Channel1] + beatloop_16_toggle + 0x97 + 0x75 + + + + + + [Channel1] + beatloop_16_toggle + 0x87 + 0x75 + + + + + + [Channel1] + beatloop_32_toggle + 0x97 + 0x76 + + + + + + [Channel1] + beatloop_32_toggle + 0x87 + 0x76 + + + + + + [Channel1] + beatloop_64_toggle + 0x97 + 0x77 + + + + + + [Channel1] + beatloop_64_toggle + 0x87 + 0x77 + + + + + + [Channel1] + beatloop_0.03125_toggle + 0x99 + 0x70 + + + + + + [Channel1] + beatloop_0.03125_toggle + 0x89 + 0x70 + + + + + + [Channel1] + beatloop_0.0625_toggle + 0x99 + 0x71 + + + + + + [Channel1] + beatloop_0.0625_toggle + 0x89 + 0x71 + + + + + + [Channel1] + beatloop_0.125_toggle + 0x99 + 0x72 + + + + + + [Channel1] + beatloop_0.125_toggle + 0x89 + 0x72 + + + + + + [Channel1] + beatloop_0.25_toggle + 0x99 + 0x73 + + + + + + [Channel1] + beatloop_0.25_toggle + 0x89 + 0x73 + + + + + + [Channel1] + beatloop_0.5_toggle + 0x99 + 0x74 + + + + + + [Channel1] + beatloop_0.5_toggle + 0x89 + 0x74 + + + + + + [Channel1] + beatloop_1_toggle + 0x99 + 0x75 + + + + + + [Channel1] + beatloop_1_toggle + 0x89 + 0x75 + + + + + + [Channel1] + beatloop_2_toggle + 0x99 + 0x76 + + + + + + [Channel1] + beatloop_2_toggle + 0x89 + 0x76 + + + + + + [Channel1] + beatloop_4_toggle + 0x99 + 0x77 + + + + + + [Channel1] + beatloop_4_toggle + 0x89 + 0x77 + + + + + + [Channel1] + beatlooproll_0.03125_activate + 0x97 + 0x78 + + + + + + [Channel1] + beatlooproll_0.03125_activate + 0x87 + 0x78 + + + + + + [Channel1] + beatlooproll_0.0625_activate + 0x97 + 0x79 + + + + + + [Channel1] + beatlooproll_0.0625_activate + 0x87 + 0x79 + + + + + + [Channel1] + beatlooproll_0.125_activate + 0x97 + 0x7a + + + + + + [Channel1] + beatlooproll_0.125_activate + 0x87 + 0x7a + + + + + + [Channel1] + beatlooproll_0.25_activate + 0x97 + 0x7b + + + + + + [Channel1] + beatlooproll_0.25_activate + 0x87 + 0x7b + + + + + + [Channel1] + beatlooproll_0.5_activate + 0x97 + 0x7c + + + + + + [Channel1] + beatlooproll_0.5_activate + 0x87 + 0x7c + + + + + + [Channel1] + beatlooproll_1_activate + 0x97 + 0x7d + + + + + + [Channel1] + beatlooproll_1_activate + 0x87 + 0x7d + + + + + + [Channel1] + beatlooproll_2_activate + 0x97 + 0x7e + + + + + + [Channel1] + beatlooproll_2_activate + 0x87 + 0x7e + + + + + + [Channel1] + beatlooproll_4_activate + 0x97 + 0x7f + + + + + + [Channel1] + beatlooproll_4_activate + 0x87 + 0x7f + + + + + + [Channel1] + beatlooproll_0.5_activate + 0x99 + 0x78 + + + + + + [Channel1] + beatlooproll_0.5_activate + 0x89 + 0x78 + + + + + + [Channel1] + beatlooproll_1_activate + 0x99 + 0x79 + + + + + + [Channel1] + beatlooproll_1_activate + 0x89 + 0x79 + + + + + + [Channel1] + beatlooproll_2_activate + 0x99 + 0x7a + + + + + + [Channel1] + beatlooproll_2_activate + 0x89 + 0x7a + + + + + + [Channel1] + beatlooproll_4_activate + 0x99 + 0x7b + + + + + + [Channel1] + beatlooproll_4_activate + 0x89 + 0x7b + + + + + + [Channel1] + beatlooproll_8_activate + 0x99 + 0x7c + + + + + + [Channel1] + beatlooproll_8_activate + 0x89 + 0x7c + + + + + + [Channel1] + beatlooproll_16_activate + 0x99 + 0x7d + + + + + + [Channel1] + beatlooproll_16_activate + 0x89 + 0x7d + + + + + + [Channel1] + beatlooproll_32_activate + 0x99 + 0x7e + + + + + + [Channel1] + beatlooproll_32_activate + 0x89 + 0x7e + + + + + + [Channel1] + beatlooproll_64_activate + 0x99 + 0x7f + + + + + + [Channel1] + beatlooproll_64_activate + 0x89 + 0x7f + + + + + + [Master] + novation_twitch.__handle_x98_xa + 0x98 + 0xa + + + + + + [Master] + novation_twitch.__handle_x98_xa + 0x88 + 0xa + + + + + + [Master] + novation_twitch.__handle_x98_xa + 0x9a + 0xa + + + + + + [Master] + novation_twitch.__handle_x98_xa + 0x8a + 0xa + + + + + + [Channel2] + volume + 0xb8 + 0x7 + + + + + + [Channel2] + volume + 0xba + 0x7 + + + + + + [Channel2] + filterLow + 0xb8 + 0x46 + + + + + + [Channel2] + filterLow + 0xba + 0x46 + + + + + + [Channel2] + filterMid + 0xb8 + 0x47 + + + + + + [Channel2] + filterMid + 0xba + 0x47 + + + + + + [Channel2] + filterHigh + 0xb8 + 0x48 + + + + + + [Channel2] + filterHigh + 0xba + 0x48 + + + + + + [Channel2] + pregain + 0xb8 + 0x9 + + + + + + [Channel2] + pregain + 0xba + 0x9 + + + + + + [Master] + novation_twitch.__handle_xb8_x6 + 0xb8 + 0x6 + + + + + + [Master] + novation_twitch.__handle_xb8_x6 + 0xba + 0x6 + + + + + + [QuickEffectRack1_[Channel2]] + enabled + 0x98 + 0x6 + + + + + + [QuickEffectRack1_[Channel2]] + enabled + 0x88 + 0x6 + + + + + + [QuickEffectRack1_[Channel2]] + enabled + 0x9a + 0x6 + + + + + + [QuickEffectRack1_[Channel2]] + enabled + 0x8a + 0x6 + + + + + + [QuickEffectRack1_[Channel2]] + enabled + 0x98 + 0xd + + + + + + [QuickEffectRack1_[Channel2]] + enabled + 0x88 + 0xd + + + + + + [QuickEffectRack1_[Channel2]] + enabled + 0x9a + 0xd + + + + + + [QuickEffectRack1_[Channel2]] + enabled + 0x8a + 0xd + + + + + + [EffectRack1_EffectUnit1] + group_[Channel2]_enable + 0x9b + 0x21 + + + + + + [EffectRack1_EffectUnit1] + group_[Channel2]_enable + 0x8b + 0x21 + + + + + + [Channel2] + LoadSelectedTrack + 0x97 + 0x53 + + + + + + [Channel2] + LoadSelectedTrack + 0x87 + 0x53 + + + + + + [Channel2] + play + 0x98 + 0x17 + + + + + + [Channel2] + play + 0x88 + 0x17 + + + + + + [Channel2] + play + 0x9a + 0x17 + + + + + + [Channel2] + play + 0x8a + 0x17 + + + + + + [Channel2] + cue_default + 0x98 + 0x16 + + + + + + [Channel2] + cue_default + 0x88 + 0x16 + + + + + + [Channel2] + reverse + 0x9a + 0x16 + + + + + + [Channel2] + reverse + 0x8a + 0x16 + + + + + + [Channel2] + keylock + 0x98 + 0x12 + + + + + + [Channel2] + keylock + 0x88 + 0x12 + + + + + + [Master] + novation_twitch.__handle_x9a_x12 + 0x9a + 0x12 + + + + + + [Master] + novation_twitch.__handle_x9a_x12 + 0x8a + 0x12 + + + + + + [Channel2] + sync_enabled + 0x98 + 0x13 + + + + + + [Channel2] + sync_enabled + 0x88 + 0x13 + + + + + + [Channel2] + sync_enabled + 0x9a + 0x13 + + + + + + [Channel2] + sync_enabled + 0x8a + 0x13 + + + + + + [Channel2] + beats_translate_curpos + 0x98 + 0x11 + + + + + + [Channel2] + beats_translate_curpos + 0x88 + 0x11 + + + + + + [Channel2] + beats_translate_curpos + 0x9a + 0x11 + + + + + + [Channel2] + beats_translate_curpos + 0x8a + 0x11 + + + + + + [Channel2] + quantize + 0x98 + 0x10 + + + + + + [Channel2] + quantize + 0x88 + 0x10 + + + + + + [Channel2] + quantize + 0x9a + 0x10 + + + + + + [Channel2] + quantize + 0x8a + 0x10 + + + + + + [Master] + novation_twitch.__handle_x98_x3 + 0x98 + 0x3 + + + + + + [Master] + novation_twitch.__handle_x98_x3 + 0x88 + 0x3 + + + + + + [Master] + novation_twitch.__handle_x98_x3 + 0x9a + 0x3 + + + + + + [Master] + novation_twitch.__handle_x98_x3 + 0x8a + 0x3 + + + + + + [Master] + novation_twitch.__handle_xb8_x3 + 0xb8 + 0x3 + + + + + + [Master] + novation_twitch.__handle_xb8_x3 + 0xba + 0x3 + + + + + + [Channel2] + playposition + 0xb8 + 0x34 + + + + + + [Master] + novation_twitch.__handle_xb8_x35 + 0xb8 + 0x35 + + + + + + [Master] + novation_twitch.__handle_xba_x35 + 0xba + 0x35 + + + + + + [Master] + novation_twitch.__handle_x9a_x47 + 0x9a + 0x47 + + + + + + [Master] + novation_twitch.__handle_x9a_x47 + 0x8a + 0x47 + + + + + + [Channel2] + hotcue_1_activate + 0x98 + 0x60 + + + + + + [Channel2] + hotcue_1_activate + 0x88 + 0x60 + + + + + + [Channel2] + hotcue_1_clear + 0x9a + 0x60 + + + + + + [Channel2] + hotcue_1_clear + 0x8a + 0x60 + + + + + + [Channel2] + hotcue_2_activate + 0x98 + 0x61 + + + + + + [Channel2] + hotcue_2_activate + 0x88 + 0x61 + + + + + + [Channel2] + hotcue_2_clear + 0x9a + 0x61 + + + + + + [Channel2] + hotcue_2_clear + 0x8a + 0x61 + + + + + + [Channel2] + hotcue_3_activate + 0x98 + 0x62 + + + + + + [Channel2] + hotcue_3_activate + 0x88 + 0x62 + + + + + + [Channel2] + hotcue_3_clear + 0x9a + 0x62 + + + + + + [Channel2] + hotcue_3_clear + 0x8a + 0x62 + + + + + + [Channel2] + hotcue_4_activate + 0x98 + 0x63 + + + + + + [Channel2] + hotcue_4_activate + 0x88 + 0x63 + + + + + + [Channel2] + hotcue_4_clear + 0x9a + 0x63 + + + + + + [Channel2] + hotcue_4_clear + 0x8a + 0x63 + + + + + + [Channel2] + hotcue_5_activate + 0x98 + 0x64 + + + + + + [Channel2] + hotcue_5_activate + 0x88 + 0x64 + + + + + + [Channel2] + hotcue_5_clear + 0x9a + 0x64 + + + + + + [Channel2] + hotcue_5_clear + 0x8a + 0x64 + + + + + + [Channel2] + hotcue_6_activate + 0x98 + 0x65 + + + + + + [Channel2] + hotcue_6_activate + 0x88 + 0x65 + + + + + + [Channel2] + hotcue_6_clear + 0x9a + 0x65 + + + + + + [Channel2] + hotcue_6_clear + 0x8a + 0x65 + + + + + + [Channel2] + hotcue_7_activate + 0x98 + 0x66 + + + + + + [Channel2] + hotcue_7_activate + 0x88 + 0x66 + + + + + + [Channel2] + hotcue_7_clear + 0x9a + 0x66 + + + + + + [Channel2] + hotcue_7_clear + 0x8a + 0x66 + + + + + + [Channel2] + hotcue_8_activate + 0x98 + 0x67 + + + + + + [Channel2] + hotcue_8_activate + 0x88 + 0x67 + + + + + + [Channel2] + hotcue_8_clear + 0x9a + 0x67 + + + + + + [Channel2] + hotcue_8_clear + 0x8a + 0x67 + + + + + + [Sampler1] + cue_preview + 0x98 + 0x68 + + + + + + [Sampler1] + cue_preview + 0x88 + 0x68 + + + + + + [Sampler1] + cue_preview + 0x9a + 0x68 + + + + + + [Sampler1] + cue_preview + 0x8a + 0x68 + + + + + + [Sampler2] + cue_preview + 0x98 + 0x69 + + + + + + [Sampler2] + cue_preview + 0x88 + 0x69 + + + + + + [Sampler2] + cue_preview + 0x9a + 0x69 + + + + + + [Sampler2] + cue_preview + 0x8a + 0x69 + + + + + + [Sampler3] + cue_preview + 0x98 + 0x6a + + + + + + [Sampler3] + cue_preview + 0x88 + 0x6a + + + + + + [Sampler3] + cue_preview + 0x9a + 0x6a + + + + + + [Sampler3] + cue_preview + 0x8a + 0x6a + + + + + + [Sampler4] + cue_preview + 0x98 + 0x6b + + + + + + [Sampler4] + cue_preview + 0x88 + 0x6b + + + + + + [Sampler4] + cue_preview + 0x9a + 0x6b + + + + + + [Sampler4] + cue_preview + 0x8a + 0x6b + + + + + + [Master] + novation_twitch.__handle_x98_x6c + 0x98 + 0x6c + + + + + + [Master] + novation_twitch.__handle_x98_x6c + 0x88 + 0x6c + + + + + + [Master] + novation_twitch.__handle_x98_x6c + 0x9a + 0x6c + + + + + + [Master] + novation_twitch.__handle_x98_x6c + 0x8a + 0x6c + + + + + + [Master] + novation_twitch.__handle_x98_x6d + 0x98 + 0x6d + + + + + + [Master] + novation_twitch.__handle_x98_x6d + 0x88 + 0x6d + + + + + + [Master] + novation_twitch.__handle_x98_x6d + 0x9a + 0x6d + + + + + + [Master] + novation_twitch.__handle_x98_x6d + 0x8a + 0x6d + + + + + + [Master] + novation_twitch.__handle_x98_x6e + 0x98 + 0x6e + + + + + + [Master] + novation_twitch.__handle_x98_x6e + 0x88 + 0x6e + + + + + + [Master] + novation_twitch.__handle_x98_x6e + 0x9a + 0x6e + + + + + + [Master] + novation_twitch.__handle_x98_x6e + 0x8a + 0x6e + + + + + + [Master] + novation_twitch.__handle_x98_x6f + 0x98 + 0x6f + + + + + + [Master] + novation_twitch.__handle_x98_x6f + 0x88 + 0x6f + + + + + + [Master] + novation_twitch.__handle_x98_x6f + 0x9a + 0x6f + + + + + + [Master] + novation_twitch.__handle_x98_x6f + 0x8a + 0x6f + + + + + + [Channel2] + beatloop_0.5_toggle + 0x98 + 0x70 + + + + + + [Channel2] + beatloop_0.5_toggle + 0x88 + 0x70 + + + + + + [Channel2] + beatloop_1_toggle + 0x98 + 0x71 + + + + + + [Channel2] + beatloop_1_toggle + 0x88 + 0x71 + + + + + + [Channel2] + beatloop_2_toggle + 0x98 + 0x72 + + + + + + [Channel2] + beatloop_2_toggle + 0x88 + 0x72 + + + + + + [Channel2] + beatloop_4_toggle + 0x98 + 0x73 + + + + + + [Channel2] + beatloop_4_toggle + 0x88 + 0x73 + + + + + + [Channel2] + beatloop_8_toggle + 0x98 + 0x74 + + + + + + [Channel2] + beatloop_8_toggle + 0x88 + 0x74 + + + + + + [Channel2] + beatloop_16_toggle + 0x98 + 0x75 + + + + + + [Channel2] + beatloop_16_toggle + 0x88 + 0x75 + + + + + + [Channel2] + beatloop_32_toggle + 0x98 + 0x76 + + + + + + [Channel2] + beatloop_32_toggle + 0x88 + 0x76 + + + + + + [Channel2] + beatloop_64_toggle + 0x98 + 0x77 + + + + + + [Channel2] + beatloop_64_toggle + 0x88 + 0x77 + + + + + + [Channel2] + beatloop_0.03125_toggle + 0x9a + 0x70 + + + + + + [Channel2] + beatloop_0.03125_toggle + 0x8a + 0x70 + + + + + + [Channel2] + beatloop_0.0625_toggle + 0x9a + 0x71 + + + + + + [Channel2] + beatloop_0.0625_toggle + 0x8a + 0x71 + + + + + + [Channel2] + beatloop_0.125_toggle + 0x9a + 0x72 + + + + + + [Channel2] + beatloop_0.125_toggle + 0x8a + 0x72 + + + + + + [Channel2] + beatloop_0.25_toggle + 0x9a + 0x73 + + + + + + [Channel2] + beatloop_0.25_toggle + 0x8a + 0x73 + + + + + + [Channel2] + beatloop_0.5_toggle + 0x9a + 0x74 + + + + + + [Channel2] + beatloop_0.5_toggle + 0x8a + 0x74 + + + + + + [Channel2] + beatloop_1_toggle + 0x9a + 0x75 + + + + + + [Channel2] + beatloop_1_toggle + 0x8a + 0x75 + + + + + + [Channel2] + beatloop_2_toggle + 0x9a + 0x76 + + + + + + [Channel2] + beatloop_2_toggle + 0x8a + 0x76 + + + + + + [Channel2] + beatloop_4_toggle + 0x9a + 0x77 + + + + + + [Channel2] + beatloop_4_toggle + 0x8a + 0x77 + + + + + + [Channel2] + beatlooproll_0.03125_activate + 0x98 + 0x78 + + + + + + [Channel2] + beatlooproll_0.03125_activate + 0x88 + 0x78 + + + + + + [Channel2] + beatlooproll_0.0625_activate + 0x98 + 0x79 + + + + + + [Channel2] + beatlooproll_0.0625_activate + 0x88 + 0x79 + + + + + + [Channel2] + beatlooproll_0.125_activate + 0x98 + 0x7a + + + + + + [Channel2] + beatlooproll_0.125_activate + 0x88 + 0x7a + + + + + + [Channel2] + beatlooproll_0.25_activate + 0x98 + 0x7b + + + + + + [Channel2] + beatlooproll_0.25_activate + 0x88 + 0x7b + + + + + + [Channel2] + beatlooproll_0.5_activate + 0x98 + 0x7c + + + + + + [Channel2] + beatlooproll_0.5_activate + 0x88 + 0x7c + + + + + + [Channel2] + beatlooproll_1_activate + 0x98 + 0x7d + + + + + + [Channel2] + beatlooproll_1_activate + 0x88 + 0x7d + + + + + + [Channel2] + beatlooproll_2_activate + 0x98 + 0x7e + + + + + + [Channel2] + beatlooproll_2_activate + 0x88 + 0x7e + + + + + + [Channel2] + beatlooproll_4_activate + 0x98 + 0x7f + + + + + + [Channel2] + beatlooproll_4_activate + 0x88 + 0x7f + + + + + + [Channel2] + beatlooproll_0.5_activate + 0x9a + 0x78 + + + + + + [Channel2] + beatlooproll_0.5_activate + 0x8a + 0x78 + + + + + + [Channel2] + beatlooproll_1_activate + 0x9a + 0x79 + + + + + + [Channel2] + beatlooproll_1_activate + 0x8a + 0x79 + + + + + + [Channel2] + beatlooproll_2_activate + 0x9a + 0x7a + + + + + + [Channel2] + beatlooproll_2_activate + 0x8a + 0x7a + + + + + + [Channel2] + beatlooproll_4_activate + 0x9a + 0x7b + + + + + + [Channel2] + beatlooproll_4_activate + 0x8a + 0x7b + + + + + + [Channel2] + beatlooproll_8_activate + 0x9a + 0x7c + + + + + + [Channel2] + beatlooproll_8_activate + 0x8a + 0x7c + + + + + + [Channel2] + beatlooproll_16_activate + 0x9a + 0x7d + + + + + + [Channel2] + beatlooproll_16_activate + 0x8a + 0x7d + + + + + + [Channel2] + beatlooproll_32_activate + 0x9a + 0x7e + + + + + + [Channel2] + beatlooproll_32_activate + 0x8a + 0x7e + + + + + + [Channel2] + beatlooproll_64_activate + 0x9a + 0x7f + + + + + + [Channel2] + beatlooproll_64_activate + 0x8a + 0x7f + + + + + + + + [Microphone] + talkover + 0x9b + 0x23 + 0x7f + 0x0 + 1 + + + [EffectRack1_EffectUnit1] + enabled + 0x9b + 0x22 + 0x7f + 0x0 + 1 + + + [Master] + maximize_library + 0x97 + 0x50 + 0x7f + 0x0 + 1 + + + [Channel1] + pfl + 0x97 + 0xa + 0x7f + 0x0 + 1 + + + [Channel1] + pfl + 0x99 + 0xa + 0x7f + 0x0 + 1 + + + [QuickEffectRack1_[Channel1]] + enabled + 0x97 + 0x6 + 0x7f + 0x0 + 1 + + + [QuickEffectRack1_[Channel1]] + enabled + 0x99 + 0x6 + 0x7f + 0x0 + 1 + + + [QuickEffectRack1_[Channel1]] + enabled + 0x97 + 0xd + 0x7f + 0x0 + 1 + + + [QuickEffectRack1_[Channel1]] + enabled + 0x99 + 0xd + 0x7f + 0x0 + 1 + + + [EffectRack1_EffectUnit1] + group_[Channel1]_enable + 0x9b + 0x20 + 0x7f + 0x0 + 1 + + + [Channel1] + LoadSelectedTrack + 0x97 + 0x52 + 0x7f + 0x0 + 1 + + + [Channel1] + play + 0x97 + 0x17 + 0x7f + 0x71 + 1 + + + [Channel1] + play + 0x99 + 0x17 + 0x7f + 0x71 + 1 + + + [Channel1] + cue_indicator + 0x97 + 0x16 + 0xf + 0x1 + 1 + + + [Channel1] + reverse + 0x99 + 0x16 + 0x4f + 0x41 + 1 + + + [Channel1] + keylock + 0x97 + 0x12 + 0x7f + 0x0 + 1 + + + [Channel1] + sync_enabled + 0x97 + 0x13 + 0x7f + 0x0 + 1 + + + [Channel1] + sync_enabled + 0x99 + 0x13 + 0x7f + 0x0 + 1 + + + [Channel1] + beats_translate_curpos + 0x97 + 0x11 + 0x7f + 0x0 + 1 + + + [Channel1] + beats_translate_curpos + 0x99 + 0x11 + 0x7f + 0x0 + 1 + + + [Channel1] + quantize + 0x97 + 0x10 + 0x7f + 0x0 + 1 + + + [Channel1] + quantize + 0x99 + 0x10 + 0x7f + 0x0 + 1 + + + [Channel1] + hotcue_1_enabled + 0x97 + 0x60 + 0x4f + 0x41 + 1 + + + [Channel1] + hotcue_1_enabled + 0x99 + 0x60 + 0x4f + 0x41 + 1 + + + [Channel1] + hotcue_2_enabled + 0x97 + 0x61 + 0x4f + 0x41 + 1 + + + [Channel1] + hotcue_2_enabled + 0x99 + 0x61 + 0x4f + 0x41 + 1 + + + [Channel1] + hotcue_3_enabled + 0x97 + 0x62 + 0x4f + 0x41 + 1 + + + [Channel1] + hotcue_3_enabled + 0x99 + 0x62 + 0x4f + 0x41 + 1 + + + [Channel1] + hotcue_4_enabled + 0x97 + 0x63 + 0x4f + 0x41 + 1 + + + [Channel1] + hotcue_4_enabled + 0x99 + 0x63 + 0x4f + 0x41 + 1 + + + [Channel1] + hotcue_5_enabled + 0x97 + 0x64 + 0x4f + 0x41 + 1 + + + [Channel1] + hotcue_5_enabled + 0x99 + 0x64 + 0x4f + 0x41 + 1 + + + [Channel1] + hotcue_6_enabled + 0x97 + 0x65 + 0x4f + 0x41 + 1 + + + [Channel1] + hotcue_6_enabled + 0x99 + 0x65 + 0x4f + 0x41 + 1 + + + [Channel1] + hotcue_7_enabled + 0x97 + 0x66 + 0x4f + 0x41 + 1 + + + [Channel1] + hotcue_7_enabled + 0x99 + 0x66 + 0x4f + 0x41 + 1 + + + [Channel1] + hotcue_8_enabled + 0x97 + 0x67 + 0x4f + 0x41 + 1 + + + [Channel1] + hotcue_8_enabled + 0x99 + 0x67 + 0x4f + 0x41 + 1 + + + [Sampler1] + cue_preview + 0x97 + 0x68 + 0xf + 0x1 + 1 + + + [Sampler1] + cue_preview + 0x99 + 0x68 + 0xf + 0x1 + 1 + + + [Sampler2] + cue_preview + 0x97 + 0x69 + 0xf + 0x1 + 1 + + + [Sampler2] + cue_preview + 0x99 + 0x69 + 0xf + 0x1 + 1 + + + [Sampler3] + cue_preview + 0x97 + 0x6a + 0xf + 0x1 + 1 + + + [Sampler3] + cue_preview + 0x99 + 0x6a + 0xf + 0x1 + 1 + + + [Sampler4] + cue_preview + 0x97 + 0x6b + 0xf + 0x1 + 1 + + + [Sampler4] + cue_preview + 0x99 + 0x6b + 0xf + 0x1 + 1 + + + [Channel1] + beatloop_0.5_enabled + 0x97 + 0x70 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_1_enabled + 0x97 + 0x71 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_2_enabled + 0x97 + 0x72 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_4_enabled + 0x97 + 0x73 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_8_enabled + 0x97 + 0x74 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_16_enabled + 0x97 + 0x75 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_32_enabled + 0x97 + 0x76 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_64_enabled + 0x97 + 0x77 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_0.03125_enabled + 0x99 + 0x70 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_0.0625_enabled + 0x99 + 0x71 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_0.125_enabled + 0x99 + 0x72 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_0.25_enabled + 0x99 + 0x73 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_0.5_enabled + 0x99 + 0x74 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_1_enabled + 0x99 + 0x75 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_2_enabled + 0x99 + 0x76 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_4_enabled + 0x99 + 0x77 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_0.03125_enabled + 0x97 + 0x78 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_0.0625_enabled + 0x97 + 0x79 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_0.125_enabled + 0x97 + 0x7a + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_0.25_enabled + 0x97 + 0x7b + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_0.5_enabled + 0x97 + 0x7c + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_1_enabled + 0x97 + 0x7d + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_2_enabled + 0x97 + 0x7e + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_4_enabled + 0x97 + 0x7f + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_0.5_enabled + 0x99 + 0x78 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_1_enabled + 0x99 + 0x79 + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_2_enabled + 0x99 + 0x7a + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_4_enabled + 0x99 + 0x7b + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_8_enabled + 0x99 + 0x7c + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_16_enabled + 0x99 + 0x7d + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_32_enabled + 0x99 + 0x7e + 0x7f + 0x71 + 1 + + + [Channel1] + beatloop_64_enabled + 0x99 + 0x7f + 0x7f + 0x71 + 1 + + + [Channel2] + pfl + 0x98 + 0xa + 0x7f + 0x0 + 1 + + + [Channel2] + pfl + 0x9a + 0xa + 0x7f + 0x0 + 1 + + + [QuickEffectRack1_[Channel2]] + enabled + 0x98 + 0x6 + 0x7f + 0x0 + 1 + + + [QuickEffectRack1_[Channel2]] + enabled + 0x9a + 0x6 + 0x7f + 0x0 + 1 + + + [QuickEffectRack1_[Channel2]] + enabled + 0x98 + 0xd + 0x7f + 0x0 + 1 + + + [QuickEffectRack1_[Channel2]] + enabled + 0x9a + 0xd + 0x7f + 0x0 + 1 + + + [EffectRack1_EffectUnit1] + group_[Channel2]_enable + 0x9b + 0x21 + 0x7f + 0x0 + 1 + + + [Channel2] + LoadSelectedTrack + 0x97 + 0x53 + 0x7f + 0x0 + 1 + + + [Channel2] + play + 0x98 + 0x17 + 0x7f + 0x71 + 1 + + + [Channel2] + play + 0x9a + 0x17 + 0x7f + 0x71 + 1 + + + [Channel2] + cue_indicator + 0x98 + 0x16 + 0xf + 0x1 + 1 + + + [Channel2] + reverse + 0x9a + 0x16 + 0x4f + 0x41 + 1 + + + [Channel2] + keylock + 0x98 + 0x12 + 0x7f + 0x0 + 1 + + + [Channel2] + sync_enabled + 0x98 + 0x13 + 0x7f + 0x0 + 1 + + + [Channel2] + sync_enabled + 0x9a + 0x13 + 0x7f + 0x0 + 1 + + + [Channel2] + beats_translate_curpos + 0x98 + 0x11 + 0x7f + 0x0 + 1 + + + [Channel2] + beats_translate_curpos + 0x9a + 0x11 + 0x7f + 0x0 + 1 + + + [Channel2] + quantize + 0x98 + 0x10 + 0x7f + 0x0 + 1 + + + [Channel2] + quantize + 0x9a + 0x10 + 0x7f + 0x0 + 1 + + + [Channel2] + hotcue_1_enabled + 0x98 + 0x60 + 0x4f + 0x41 + 1 + + + [Channel2] + hotcue_1_enabled + 0x9a + 0x60 + 0x4f + 0x41 + 1 + + + [Channel2] + hotcue_2_enabled + 0x98 + 0x61 + 0x4f + 0x41 + 1 + + + [Channel2] + hotcue_2_enabled + 0x9a + 0x61 + 0x4f + 0x41 + 1 + + + [Channel2] + hotcue_3_enabled + 0x98 + 0x62 + 0x4f + 0x41 + 1 + + + [Channel2] + hotcue_3_enabled + 0x9a + 0x62 + 0x4f + 0x41 + 1 + + + [Channel2] + hotcue_4_enabled + 0x98 + 0x63 + 0x4f + 0x41 + 1 + + + [Channel2] + hotcue_4_enabled + 0x9a + 0x63 + 0x4f + 0x41 + 1 + + + [Channel2] + hotcue_5_enabled + 0x98 + 0x64 + 0x4f + 0x41 + 1 + + + [Channel2] + hotcue_5_enabled + 0x9a + 0x64 + 0x4f + 0x41 + 1 + + + [Channel2] + hotcue_6_enabled + 0x98 + 0x65 + 0x4f + 0x41 + 1 + + + [Channel2] + hotcue_6_enabled + 0x9a + 0x65 + 0x4f + 0x41 + 1 + + + [Channel2] + hotcue_7_enabled + 0x98 + 0x66 + 0x4f + 0x41 + 1 + + + [Channel2] + hotcue_7_enabled + 0x9a + 0x66 + 0x4f + 0x41 + 1 + + + [Channel2] + hotcue_8_enabled + 0x98 + 0x67 + 0x4f + 0x41 + 1 + + + [Channel2] + hotcue_8_enabled + 0x9a + 0x67 + 0x4f + 0x41 + 1 + + + [Sampler1] + cue_preview + 0x98 + 0x68 + 0xf + 0x1 + 1 + + + [Sampler1] + cue_preview + 0x9a + 0x68 + 0xf + 0x1 + 1 + + + [Sampler2] + cue_preview + 0x98 + 0x69 + 0xf + 0x1 + 1 + + + [Sampler2] + cue_preview + 0x9a + 0x69 + 0xf + 0x1 + 1 + + + [Sampler3] + cue_preview + 0x98 + 0x6a + 0xf + 0x1 + 1 + + + [Sampler3] + cue_preview + 0x9a + 0x6a + 0xf + 0x1 + 1 + + + [Sampler4] + cue_preview + 0x98 + 0x6b + 0xf + 0x1 + 1 + + + [Sampler4] + cue_preview + 0x9a + 0x6b + 0xf + 0x1 + 1 + + + [Channel2] + beatloop_0.5_enabled + 0x98 + 0x70 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_1_enabled + 0x98 + 0x71 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_2_enabled + 0x98 + 0x72 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_4_enabled + 0x98 + 0x73 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_8_enabled + 0x98 + 0x74 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_16_enabled + 0x98 + 0x75 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_32_enabled + 0x98 + 0x76 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_64_enabled + 0x98 + 0x77 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_0.03125_enabled + 0x9a + 0x70 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_0.0625_enabled + 0x9a + 0x71 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_0.125_enabled + 0x9a + 0x72 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_0.25_enabled + 0x9a + 0x73 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_0.5_enabled + 0x9a + 0x74 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_1_enabled + 0x9a + 0x75 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_2_enabled + 0x9a + 0x76 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_4_enabled + 0x9a + 0x77 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_0.03125_enabled + 0x98 + 0x78 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_0.0625_enabled + 0x98 + 0x79 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_0.125_enabled + 0x98 + 0x7a + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_0.25_enabled + 0x98 + 0x7b + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_0.5_enabled + 0x98 + 0x7c + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_1_enabled + 0x98 + 0x7d + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_2_enabled + 0x98 + 0x7e + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_4_enabled + 0x98 + 0x7f + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_0.5_enabled + 0x9a + 0x78 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_1_enabled + 0x9a + 0x79 + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_2_enabled + 0x9a + 0x7a + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_4_enabled + 0x9a + 0x7b + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_8_enabled + 0x9a + 0x7c + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_16_enabled + 0x9a + 0x7d + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_32_enabled + 0x9a + 0x7e + 0x7f + 0x71 + 1 + + + [Channel2] + beatloop_64_enabled + 0x9a + 0x7f + 0x7f + 0x71 + 1 + + + +