UNPKG

gibberwocky

Version:

music sequencing for Live and Max/MSP

1,612 lines (1,300 loc) 2.78 MB
<html> <head> <meta charset="utf-8"> <title>Gibberwocky</title> <!-- css_insert_start --> <style> /* BASICS */ .CodeMirror { /* Set height, width, borders, and global font properties here */ font-family: monospace; height: 300px; color: black; } /* PADDING */ .CodeMirror-lines { padding: 4px 0; /* Vertical padding around content */ } .CodeMirror pre { padding: 2px 4px; /* Horizontal padding of content */ } .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { background-color: white; /* The little square between H and V scrollbars */ } /* GUTTER */ .CodeMirror-gutters { border-right: 1px solid #ddd; background-color: #f7f7f7; white-space: nowrap; } .CodeMirror-linenumbers {} .CodeMirror-linenumber { padding: 0 3px 0 5px; min-width: 20px; text-align: right; color: #999; white-space: nowrap; } .CodeMirror-guttermarker { color: black; } .CodeMirror-guttermarker-subtle { color: #999; } /* CURSOR */ .CodeMirror-cursor { border-left: 1px solid black; border-right: none; width: 0; } /* Shown when moving in bi-directional text */ .CodeMirror div.CodeMirror-secondarycursor { border-left: 1px solid silver; } .cm-fat-cursor .CodeMirror-cursor { width: auto; border: 0; background: #7e7; } .cm-fat-cursor div.CodeMirror-cursors { z-index: 1; } .cm-animate-fat-cursor { width: auto; border: 0; -webkit-animation: blink 1.06s steps(1) infinite; -moz-animation: blink 1.06s steps(1) infinite; animation: blink 1.06s steps(1) infinite; background-color: #7e7; } @-moz-keyframes blink { 0% {} 50% { background-color: transparent; } 100% {} } @-webkit-keyframes blink { 0% {} 50% { background-color: transparent; } 100% {} } @keyframes blink { 0% {} 50% { background-color: transparent; } 100% {} } /* Can style cursor different in overwrite (non-insert) mode */ .CodeMirror-overwrite .CodeMirror-cursor {} .cm-tab { display: inline-block; text-decoration: inherit; } .CodeMirror-ruler { border-left: 1px solid #ccc; position: absolute; } /* DEFAULT THEME */ .cm-s-default .cm-header {color: blue;} .cm-s-default .cm-quote {color: #090;} .cm-negative {color: #d44;} .cm-positive {color: #292;} .cm-header, .cm-strong {font-weight: bold;} .cm-em {font-style: italic;} .cm-link {text-decoration: underline;} .cm-strikethrough {text-decoration: line-through;} .cm-s-default .cm-keyword {color: #708;} .cm-s-default .cm-atom {color: #219;} .cm-s-default .cm-number {color: #164;} .cm-s-default .cm-def {color: #00f;} .cm-s-default .cm-variable, .cm-s-default .cm-punctuation, .cm-s-default .cm-property, .cm-s-default .cm-operator {} .cm-s-default .cm-variable-2 {color: #05a;} .cm-s-default .cm-variable-3 {color: #085;} .cm-s-default .cm-comment {color: #a50;} .cm-s-default .cm-string {color: #a11;} .cm-s-default .cm-string-2 {color: #f50;} .cm-s-default .cm-meta {color: #555;} .cm-s-default .cm-qualifier {color: #555;} .cm-s-default .cm-builtin {color: #30a;} .cm-s-default .cm-bracket {color: #997;} .cm-s-default .cm-tag {color: #170;} .cm-s-default .cm-attribute {color: #00c;} .cm-s-default .cm-hr {color: #999;} .cm-s-default .cm-link {color: #00c;} .cm-s-default .cm-error {color: #f00;} .cm-invalidchar {color: #f00;} .CodeMirror-composing { border-bottom: 2px solid; } /* Default styles for common addons */ div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} .CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); } .CodeMirror-activeline-background {background: #e8f2ff;} /* STOP */ /* The rest of this file contains styles related to the mechanics of the editor. You probably shouldn't touch them. */ .CodeMirror { position: relative; overflow: hidden; background: white; } .CodeMirror-scroll { overflow: scroll !important; /* Things will break if this is overridden */ /* 30px is the magic margin used to hide the element's real scrollbars */ /* See overflow: hidden in .CodeMirror */ margin-bottom: -30px; margin-right: -30px; padding-bottom: 30px; height: 100%; outline: none; /* Prevent dragging from highlighting the element */ position: relative; } .CodeMirror-sizer { position: relative; border-right: 30px solid transparent; } /* The fake, visible scrollbars. Used to force redraw during scrolling before actual scrolling happens, thus preventing shaking and flickering artifacts. */ .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { position: absolute; z-index: 6; display: none; } .CodeMirror-vscrollbar { right: 0; top: 0; overflow-x: hidden; overflow-y: scroll; } .CodeMirror-hscrollbar { bottom: 0; left: 0; overflow-y: hidden; overflow-x: scroll; } .CodeMirror-scrollbar-filler { right: 0; bottom: 0; } .CodeMirror-gutter-filler { left: 0; bottom: 0; } .CodeMirror-gutters { position: absolute; left: 0; top: 0; z-index: 3; } .CodeMirror-gutter { white-space: normal; height: 100%; display: inline-block; vertical-align: top; margin-bottom: -30px; /* Hack to make IE7 behave */ *zoom:1; *display:inline; } .CodeMirror-gutter-wrapper { position: absolute; z-index: 4; background: none !important; border: none !important; } .CodeMirror-gutter-background { position: absolute; top: 0; bottom: 0; z-index: 4; } .CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; } .CodeMirror-gutter-wrapper { -webkit-user-select: none; -moz-user-select: none; user-select: none; } .CodeMirror-lines { cursor: text; min-height: 1px; /* prevents collapsing before first draw */ } .CodeMirror pre { /* Reset some styles that the rest of the page might have set */ -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; border-width: 0; background: transparent; font-family: inherit; font-size: inherit; margin: 0; white-space: pre; word-wrap: normal; line-height: inherit; color: inherit; z-index: 2; position: relative; overflow: visible; -webkit-tap-highlight-color: transparent; } .CodeMirror-wrap pre { word-wrap: break-word; white-space: pre-wrap; word-break: normal; } .CodeMirror-linebackground { position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: 0; } .CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; } .CodeMirror-widget {} .CodeMirror-code { outline: none; } /* Force content-box sizing for the elements where we expect it */ .CodeMirror-scroll, .CodeMirror-sizer, .CodeMirror-gutter, .CodeMirror-gutters, .CodeMirror-linenumber { -moz-box-sizing: content-box; box-sizing: content-box; } .CodeMirror-measure { position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden; } .CodeMirror-cursor { position: absolute; } .CodeMirror-measure pre { position: static; } div.CodeMirror-cursors { visibility: hidden; position: relative; z-index: 3; } div.CodeMirror-dragcursors { visibility: visible; } .CodeMirror-focused div.CodeMirror-cursors { visibility: visible; } .CodeMirror-selected { background: #d9d9d9; } .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } .CodeMirror-crosshair { cursor: crosshair; } .CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; } .CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; } .cm-searching { background: #ffa; background: rgba(255, 255, 0, .4); } /* IE7 hack to prevent it from returning funny offsetTops on the spans */ .CodeMirror span { *vertical-align: text-bottom; } /* Used to force a border model for a node */ .cm-force-border { padding-right: .1px; } @media print { /* Hide the cursor when printing */ .CodeMirror div.CodeMirror-cursors { visibility: hidden; } } /* See issue #2901 */ .cm-tab-wrap-hack:after { content: ''; } /* Help users use markselection to safely style text background */ span.CodeMirror-selectedtext { background: none; } .CodeMirror-hints { position: absolute; z-index: 10; overflow: hidden; list-style: none; margin: 0; padding: 2px; -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); box-shadow: 2px 3px 5px rgba(0,0,0,.2); border-radius: 3px; border: 1px solid silver; background: white; font-size: 90%; font-family: monospace; max-height: 20em; overflow-y: auto; } .CodeMirror-hint { margin: 0; padding: 0 4px; border-radius: 2px; max-width: 19em; overflow: hidden; white-space: pre; color: black; cursor: pointer; } li.CodeMirror-hint-active { background: #08f; color: white; } .vtree ul.vtree-subtree, .vtree li.vtree-leaf { margin: 0; padding: 0; list-style-type: none; position: relative; } .vtree li.vtree-leaf { background-position: -90px 0; background-repeat: repeat-y; min-height: 18px; line-height: 18px; } .vtree li.vtree-leaf::before { content: ''; width: 18px; height: 18px; position: absolute; background-position: -36px 0; } .vtree li.vtree-leaf li.vtree-leaf { margin-left: 18px; } .vtree li.vtree-leaf:last-child { background-image: none; } .vtree li.vtree-leaf.closed ul.vtree-subtree { display: none; } .vtree li.vtree-leaf.vtree-has-children > span.vtree-toggle { display: block; width: 18px; height: 18px; background-position: -72px 0; position: absolute; left: 0; top: 0; } .vtree li.vtree-leaf.vtree-has-children.closed > span.vtree-toggle { background-position: -54px 0; } .vtree a.vtree-leaf-label { line-height: 18px; display: inline-block; vertical-align: top; cursor: pointer; max-width: 100%; margin-left: 18px; padding: 0 2px; } .vtree li.vtree-leaf a.vtree-leaf-label:hover { background-color: #e7f4f9; outline: 1px solid #d8f0fa; } .vtree li.vtree-leaf.vtree-selected > a.vtree-leaf-label { background-color: #beebff; outline: 1px solid #99defd; } .vtree-contextmenu { position: absolute; z-index: 9999999; border: solid 1px #ccc; background: #eee; padding: 0px; margin: 0px; display: none; } .vtree-contextmenu li { list-style: none; padding: 1px 5px; margin: 0px; color: #333; line-height: 20px; height: 20px; cursor: default; } .vtree-contextmenu li:hover { color: #fff; background-color: #3399ff; } .vtree li.vtree-leaf, .vtree li.vtree-leaf::before, .vtree li.vtree-leaf.vtree-has-children > span.vtree-toggle { background-image: url(data:image/png;base64,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); } .microlib_tabs_nav { width: 100%; height: 26px; } .microlib_tabs_nav_item { float: left; height: 26px; padding: 0 10px; line-height: 26px; border-right: 1px solid #000; border-bottom: 1px solid #000; } .microlib_tabs_nav_item:hover, .microlib_tabs_nav_item.microlib_active { background: #000; color:white; cursor: pointer; } .microlib_tabs_tab { padding: 5px; display: none; } .microlib_tabs_tab.microlib_active { display: block; } .CodeMirror-highlight { background:red !important } body { font-family:Menlo, monospace; font-size:1em; background:rgba(46,50,53,1); margin:0; padding:0; color:rgb( 153 ) !important; } #editor { width:63%; height:100%; display:inline-block; } /* TODO: fix in max and change width to 30% before publishing. */ #sidebar { display:inline-block; width:35%; float:right; height:100%; border-left:1px black solid; box-sizing:border-box; overflow:scroll; font-family:sans-serif; font-weight:lighter; font-size:1em } .CodeMirror { font-family: 'Menlo','Source Code Pro', monospace; font-size: .7em; background-color:#bbb; color:#000; font-weight:500; } .CodeMirror { font-family:Menlo, monospace; font-size:.8em; background:rgba(46,50,53,1); color:rgb( 153 ) !important } span.cm-comment { color:rgb(121,121,121) !important } span.cm-property, span.cm-attribute, span.cm-variable, span.cm-variable-2, .cm-def, .cm-s-default { color: rgba(173,173,173,1) !important } span.cm-keyword, span.cm-number, span.cm-atom { color:rgba(89, 151, 198, 1) !important } span.cm-string {color: rgb(225, 225, 225) !important } .CodeMirror-cursor { background: rgba(255,255,255,.5); border: none !important; width: .5em !important; display: block; } .CodeMirror-selected { background:rgba(84,84,84,.5) !important; } .CodeMirror-highlight { background:rgba(255,255,255,.5) } /* *#console .CodeMirror { background-color:#444 } *#editor .CodeMirror { * background-color:#bbb; * color:#4a4a4a; *} */ .CodeMirror-matchingbracket{ color: #b00 !important } .annotation { /*padding:0px 1px;*/ border:1px solid transparent; padding:0px; box-sizing:border-box !important; } .annotation-full { border-color: #999; } .annotation-highlight { background-color: #ffffff } .annotation-border { /* border-color:#999 !important; */ border-color:#999; border-width:1px; border-style:solid } .annotation-right-border { border-right-color:#999 } .annotation-left-border { border-left-color:#999 } .annotation-top-border { border-top-color:#999 } .annotation-bottom-border { border-bottom-color:#999 } .annotation-right-border-cycle { border-right-color:#ddd !important } .annotation-left-border-cycle { border-left-color:#ddd !important } .annotation-top-border-cycle { border-top-color:#ddd !important } .annotation-bottom-border-cycle { border-bottom-color:#ddd !important } .annotation-no-left-border { border-left-color:transparent !important } .annotation-no-right-border { border-right-color:transparent !important } .annotation-border-left { border-left-color:#999; } .annotation-border-right { border-right-color: #999; } .annotation-no-horizontal-border { /* padding-left:1; */ /* padding-right:1; */ } .annotation-binop-border { /*border-color:transparent;*/ border-left-color:transparent !important; border-right-color:transparent !important; } .annotation-array { border-top-color:#999; border-bottom-color:#999; } .annotation-binop { border-left-color: transparent !important; border-right-color: transparent !important; border-style: solid; } .scoreCurrentIndex { /*border: #700 1px solid */ /*font-weight:bold !important*/ background: rgba(66,70,73,1) } .euclid1 { background:#ddd !important; color:rgba(46,50,53,1) !important; } .euclid0 { background:rgba(96,100,103,1) } .pattern-update-range-outside { color:#888; } .pattern-update-range-inside { /*color:#0f0 !important; */ text-decoration:underline; } .vtree-leaf-label { -webkit-touch-callout: none; /* iOS Safari */ -webkit-user-select: none; /* Chrome/Safari/Opera */ -khtml-user-select: none; /* Konqueror */ -moz-user-select: none; /* Firefox */ -ms-user-select: none; /* Internet Explorer/Edge */ user-select: none; /* Non-prefixed version, currently not supported by any browser */ } .vtree { font-family:sans-serif; font-size:.8em; } #console { width:100%; overflow:scroll; height: calc( 100% - 4.5em ); color:rgb( 153,153,153 ) !important; } #sidebar { color:rgb( 173,173,173 ) !important; } #lomView ul { padding: 0 } #liveDemosView ul, #maxDemosView ul, #midiDemosView ul { margin:0; padding: 0; list-style:none; cursor:pointer } #liveDemosView ul li, #maxDemosView ul li, #midiDemosView ul li { margin-bottom: 5px } #liveDemosView ul li:hover, #maxDemosView ul li:hover, #midiDemosView ul li:hover { background: rgba( 255,255,255, .15) } #splitbar { display:inline-block; top:0; position:absolute; height:100%; width:5px; background:#666; cursor: ew-resize } #tabs { display:inline-block; top:0; position:relative; left:5px; font-size: .8em; padding-top:0; box-sizing:border } #console_list { width: 100%; height:100%; margin:0; display: block; font-family: 'Menlo', 'Source Code Pro', monospace; list-style: none; box-sizing:border; padding:0; } #console_list li { font-size: 1em; } .console_error { color:red; } .microlib_tabs_tab { padding:1em; padding-top:1.5em; } .microlib_tabs_nav_item { height:26px; padding:.5em 5px 0px 5px; line-height:26px; color:white; background:black } .microlib_tabs_nav_item.microlib_active { background:rgba(89, 151, 198, .6) !important } .vtree{ padding-left: 0 } .demos .microlib_tabs_nav_item, .demos .microlib_tabs_nav_item.microlib_active { background:transparent !important; color:#ccc; text-decoration:underline; border:none; } .demos .microlib_tabs_nav_item.microlib_active { color:rgba(109, 171, 238, 1) !important; } .schemas .microlib_tabs_nav_item, .schemas .microlib_tabs_nav_item.microlib_active { background:transparent !important; color:#ccc; text-decoration:underline; border:none; } .schemas .microlib_tabs_nav_item.microlib_active { color:rgba(109, 171, 238, 1) !important; } #sidebar select, #sidebar input { background:#aaa; margin-bottom:10px; } label { margin-bottom:5px; } #help a { color: #ddd } #help p { max-width: 24em; margin-top:0 } .demos { padding-left:0 } </style> <!-- css_insert_end --> </head> <body> <div id='editor'></div> <div id='sidebar'> <div id='splitbar'></div> <div id='tabs' class='microlib_tabs'> <div class="microlib_tabs_tab" data-title="console" > <div id='console'></div> </div> <div class="microlib_tabs_tab schemas" data-title="schemas"> <div id='schemaTabs' class='microlib_tabs'> <div class="microlib_tabs_tab" data-title="lom"> <div id='lomView'></div> </div> <div class="microlib_tabs_tab" data-title="mom"> <div id='momView'></div> </div> </div> </div> <div class="microlib_tabs_tab demos" data-title="demos"> <div id='demoTabs' class='microlib_tabs'> <div class="microlib_tabs_tab" data-title="live demos"> <div id='liveDemosView'></div> </div> <div class="microlib_tabs_tab" data-title="max demos"> <div id='maxDemosView'></div> </div> <div class="microlib_tabs_tab" data-title="midi demos"> <div id='midiDemosView'></div> </div> </div> </div> <div class="microlib_tabs_tab" data-title="config"> <div id='configView'> <!--<label>cc modulation output rate (in Hz):</label><br>--> <!--<input id='modulationRate' value=60></input><br>--> <h4>Clock sync:</h4> <input type='radio' id='liveSyncRadio' name='sync' checked>Live</input><br> <input type='radio' id='maxSyncRadio' name='sync'>Max/MSP</input><br> <input type='radio' id='clockSyncRadio' name='sync'>MIDI Clock</input><br> <input type='radio' id='internalSyncRadio' name='sync'>Internal</input> <h4>MIDI I/O</h4> <label>MIDI input (clock):</label><br><select id='midiInputSelect'></select><br> <label>MIDI output:</label><br><select id='midiOutputSelect'></select><br> </div> </div> <div class="microlib_tabs_tab" data-title="help" > <div id="help"> <p>For a complete description of the gibberwocky API, see the <a href='http://gibberwocky.cc/reference'>gibberwocky reference</a>. Otherwise the various tutorial are the best place to get started. </p> <p>For questions, answers, and announcements try the <a href="http://lurk.org/groups/gibber/">mailing list</a> or the <a href="https://livecode.slack.com/messages/gibber/">gibber Slack channel</a> for more informal discussion. If you aren't already a member of the Live Coding Slack group there's a <a href="http://live-code-slack.herokuapp.com">site that generates automatic invites</a>. </p> </div> </div> </div> <!-- js_insert_start --> <script> (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ const Queue = require( './priorityqueue.js' ) let Gibber = null let Scheduler = { currentTime : performance.now(), queue: new Queue( ( a, b ) => a.time - b.time ), visualizationTime: { init:true, base:0, phase:0, }, init( __Gibber ) { Gibber = __Gibber window.requestAnimationFrame( this.onAnimationFrame ) }, clear() { this.queue.data.length = 0 }, add( func, offset, idx ) { let time = this.currentTime + offset this.queue.push({ func, time }) return time }, runSoon( evt ) { try{ evt.func() }catch(e) { console.log( 'annotation error:', e.toString() ) } }, run( timestamp, dt ) { let nextEvent = this.queue.peek() //if( nextEvent === undefined ) return if( nextEvent !== undefined && this.queue.length > 0 && nextEvent.time <= timestamp ) { // remove event this.queue.pop() setTimeout( ()=> this.runSoon( nextEvent ) ) //try{ // nextEvent.func() //}catch( e ) { // console.log( e ) // Gibber.Environment.error( 'annotation error:', e.toString() ) //} // call recursively this.run( timestamp ) } if( Gibber.Environment.codeMarkup.waveform.widgets.dirty === true ) { Gibber.Environment.codeMarkup.waveform.drawWidgets() } }, onAnimationFrame( timestamp ) { window.requestAnimationFrame( this.onAnimationFrame ) const diff = timestamp - this.currentTime this.currentTime = timestamp this.visualizationTime.phase += diff this.run( timestamp, diff ) }, updateVisualizationTime( ms ) { if( this.visualizationTime.init === true ) { this.visualizationTime.base += ms this.visualizationTime.phase = 0 }else{ this.visualizationTime.init = true } }, } Scheduler.onAnimationFrame = Scheduler.onAnimationFrame.bind( Scheduler ) module.exports = Scheduler },{"./priorityqueue.js":42}],2:[function(require,module,exports){ const Utility = require( '../../utility.js' ) const $ = Utility.create module.exports = function( Marker ) { 'use strict' const ArrayExpression = function( patternNode, state, seq, patternType, container=null, index=0, isLookup=false ) { if( patternNode.processed === true ) return const cm = state.cm const track = seq.object const patternObject = seq[ patternType ] const [ patternName, start, end ] = Marker._getNamesAndPosition( patternNode, state, patternType, index ) const cssName = patternName patternObject.markers = [] if( track.markup === undefined ) Marker.prepareObject( track ) let count = 0 for( let element of patternNode.elements ) { let cssClassName = patternName + '_' + count, elementStart = Object.assign( {}, start ), elementEnd = Object.assign( {}, end ), marker elementStart.ch = element.loc.start.column// + Marker.offset.horizontal elementEnd.ch = element.loc.end.column // + Marker.offset.horizontal if( element.type === 'BinaryExpression' ) { marker = cm.markText( elementStart, elementEnd, { 'className': cssClassName + ' annotation', startStyle: 'annotation-no-right-border', endStyle: 'annotation-no-left-border', //inclusiveLeft:true, inclusiveRight:true }) // create specific border for operator: top, bottom, no sides const divStart = Object.assign( {}, elementStart ) const divEnd = Object.assign( {}, elementEnd ) divStart.ch += 1 divEnd.ch -= 1 const marker2 = cm.markText( divStart, divEnd, { className:cssClassName + '_binop annotation-binop' }) patternObject.markers.push( marker, marker2 ) }else if (element.type === 'UnaryExpression' ) { marker = cm.markText( elementStart, elementEnd, { 'className': cssClassName + ' annotation', //inclusiveLeft: true, //inclusiveRight: true }) let start2 = Object.assign( {}, elementStart ) start2.ch += 1 let marker2 = cm.markText( elementStart, start2, { 'className': cssClassName + ' annotation-no-right-border', //inclusiveLeft: true, //inclusiveRight: true }) let marker3 = cm.markText( start2, elementEnd, { 'className': cssClassName + ' annotation-no-left-border', //inclusiveLeft: true, //inclusiveRight: true }) patternObject.markers.push( marker, marker2, marker3 ) }else if( element.type === 'ArrayExpression' ) { marker = cm.markText( elementStart, elementEnd, { 'className': cssClassName + ' annotation', //inclusiveLeft:true, inclusiveRight:true, startStyle:'annotation-left-border-start', endStyle: 'annotation-right-border-end', }) // mark opening array bracket const arrayStart_start = Object.assign( {}, elementStart ) const arrayStart_end = Object.assign( {}, elementStart ) arrayStart_end.ch += 1 cm.markText( arrayStart_start, arrayStart_end, { className:cssClassName + '_start' }) // mark closing array bracket const arrayEnd_start = Object.assign( {}, elementEnd ) const arrayEnd_end = Object.assign( {}, elementEnd ) arrayEnd_start.ch -=1 const marker2 = cm.markText( arrayEnd_start, arrayEnd_end, { className:cssClassName + '_end' }) patternObject.markers.push( marker, marker2 ) }else{ marker = cm.markText( elementStart, elementEnd, { 'className': cssClassName + ' annotation', //inclusiveLeft:true, inclusiveRight:true }) patternObject.markers.push( marker ) } if( track.markup.textMarkers[ patternName ] === undefined ) track.markup.textMarkers[ patternName ] = [] track.markup.textMarkers[ patternName ][ count ] = marker if( track.markup.cssClasses[ patternName ] === undefined ) track.markup.cssClasses[ patternName ] = [] track.markup.cssClasses[ patternName ][ count ] = cssClassName count++ } let highlighted = { className:null, isArray:false }, cycle = Marker._createBorderCycleFunction( patternName, patternObject ) patternObject.patternType = patternType patternObject.patternName = patternName patternObject.update = () => { let className = '.' + patternName className += '_' + patternObject.update.currentIndex if( highlighted.className !== className ) { // remove any previous annotations for this pattern if( highlighted.className !== null ) { if( highlighted.isArray === false && highlighted.className ) { $( highlighted.className ).remove( 'annotation-border' ) }else{ $( highlighted.className ).remove( 'annotation-array' ) $( highlighted.className + '_start' ).remove( 'annotation-border-left' ) $( highlighted.className + '_end' ).remove( 'annotation-border-right' ) if( $( highlighted.className + '_binop' ).length > 0 ) { $( highlighted.className + '_binop' ).remove( 'annotation-binop-border' ) } } } // add annotation for current pattern element const values = isLookup === false ? patternObject.values : patternObject._values if( Array.isArray( values[ patternObject.update.currentIndex ] ) ) { $( className ).add( 'annotation-array' ) $( className + '_start' ).add( 'annotation-border-left' ) $( className + '_end' ).add( 'annotation-border-right' ) highlighted.isArray = true }else{ $( className ).add( 'annotation-border' ) if( $( className + '_binop' ).length > 0 ) { $( className + '_binop' ).add( 'annotation-binop-border' ) } highlighted.isArray = false } highlighted.className = className cycle.clear() }else{ cycle() } } // check to see if a clear function already exists and save reference // XXX should clear be saved somewhere else... on the update function? let __clear = null if( patternObject.clear !== undefined ) __clear = patternObject.clear patternObject.clear = () => { if( highlighted.className !== null ) { $( highlighted.className ).remove( 'annotation-border' ) } cycle.clear() patternObject.markers.forEach( marker => marker.clear() ) if( __clear !== null ) __clear() } Marker._addPatternFilter( patternObject ) patternObject._onchange = () => { Marker._updatePatternContents( patternObject, patternName, track ) } } return ArrayExpression } },{"../../utility.js":49}],3:[function(require,module,exports){ module.exports = function( Marker ) { 'use strict' // 1/4, 1/8 etc. const BinaryExpression = function( patternNode, state, seq, patternType,container=null, index=0 ) { if( patternNode.processed === true ) return const cm = state.cm const seqTarget = seq.object const patternObject = seq[ patternType ] const [ className, start, end ] = Marker._getNamesAndPosition( patternNode, state, patternType, index ) const cssName = className const marker = cm.markText( start, end, { 'className': cssName + ' annotation annotation-border' , startStyle: 'annotation-no-right-border', endStyle: 'annotation-no-left-border', //inclusiveLeft:true, //inclusiveRight:true } ) if( seqTarget.markup === undefined ) Marker.prepareObject( seqTarget ) seqTarget.markup.textMarkers[ className ] = marker const divStart = Object.assign( {}, start ) const divEnd = Object.assign( {}, end ) divStart.ch += 1 divEnd.ch -= 1 const marker2 = cm.markText( divStart, divEnd, { className:'annotation-binop-border' }) if( seqTarget.markup.cssClasses[ className ] === undefined ) seqTarget.markup.cssClasses[ className ] = [] seqTarget.markup.cssClasses[ className ][ index ] = cssName patternObject.marker = marker Marker.finalizePatternAnnotation( patternObject, className, seqTarget, marker ) } return BinaryExpression } },{}],4:[function(require,module,exports){ module.exports = function( Marker ) { 'use strict' // CallExpression denotes an array (or other object) that calls a method, like .rnd() // could also represent an anonymous function call, like Rndi(19,40) const CallExpression = function( patternNode, state, seq, patternType, index=0 ) { if( patternNode.processed === true ) return var args = Array.prototype.slice.call( arguments, 0 ) if( patternNode.callee.type === 'MemberExpression' && patternNode.callee.object.type === 'ArrayExpression' ) { args[ 0 ] = patternNode.callee.object args[ 0 ].offset = Marker.offset Marker.patternMarkupFunctions.ArrayExpression( ...args ) } else if (patternNode.callee.type === 'Identifier' ) { // function like Euclid or gen~d Marker.patternMarkupFunctions.Identifier( ...args ) } } return CallExpression } },{}],5:[function(require,module,exports){ const __Identifier = function( Marker ) { const mark = function( node, state, patternType, seqNumber ) { const [ className, start, end ] = Marker._getNamesAndPosition( node, state, patternType, seqNumber ) const cssName = className + '_' + seqNumber const commentStart = end // we define the comment range as being one character, this // only defines the range of characters that will be replaced // by the eventual longer comment string. const commentEnd = Object.assign( {}, commentStart ) commentEnd.ch += 1 const line = end.line const lineTxt = state.cm.getLine( line ) let ch = end.ch // for whatever reason, sometimes the ch value leads to // an undefined final character in the string. In that case, // work back until we find the actual final character. let lastChar = lineTxt[ ch ] while( lastChar === undefined ) { ch-- lastChar = lineTxt[ ch ] } // different replacements are used for use in sequencers, when a callexpression // creating a wavepattern is often followed by a comma, vs when a wavepattern is // assigned to a variable, when no comma is present if( lastChar === ',' ) { state.cm.replaceRange( ' ,', { line, ch:ch }, { line, ch:ch + 1 } ) }else if( lastChar === ')' ){ state.cm.replaceRange( ') ', { line, ch:ch }, { line, ch:ch + 1 } ) }else{ state.cm.replaceRange( lastChar + ' ', { line, ch:ch }, { line, ch:ch + 1 } ) } const marker = state.cm.markText( commentStart, commentEnd, { className }) return [ marker, className ] } // Typically this is used with named functions. For example, if you store an // Arp in the variable 'a' and pass 'a' into a sequence, 'a' is the Identifier // and this function will be called to mark up the associated pattern. const Identifier = function( patternNode, state, seq, patternType, containerNode, seqNumber ) { if( patternNode.processed === true ) return const cm = state.cm const track = seq.object const patternObject = seq[ patternType ] const [ marker, className ] = mark( patternNode, state, patternType, seqNumber ) // WavePatterns can also be passed as named functions; make sure we forward // these to the appropriate markup functions if( patternObject.type === 'WavePattern' || patternObject.isGen ) { //|| patternObject.type === 'Lookup' ) { if( patternObject.widget === undefined ) { // if wavepattern is inlined to .seq Marker.processGen( containerNode, cm, track, patternObject, seq ) }else{ patternObject.update = Marker.patternUpdates.anonymousFunction( patternObject, marker, className, cm, track ) } }else{ let updateName = typeof patternNode.callee !== 'undefined' ? patternNode.callee.name : patternNode.name // this doesn't work for variables storing lookups, as there's no array to highlight // if( patternObject.type === 'Lookup' ) updateName = 'Lookup' if( Marker.patternUpdates[ updateName ] ) { if( updateName !== 'Lookup' ) { patternObject.update = Marker.patternUpdates[ updateName ]( patternObject, marker, className, cm, track, patternNode ) }else{ Marker.patternUpdates[ updateName ]( patternObject, marker, className, cm, track, patternNode, patternType, seqNumber ) } } else { patternObject.update = Marker.patternUpdates.anonymousFunction( patternObject, marker, className, cm, track ) } patternObject.patternName = className // store value changes in array and then pop them every time the annotation is updated patternObject.update.value = [] if( updateName !== 'Lookup' ) Marker._addPatternFilter( patternObject ) } patternObject.marker = marker } return Identifier } module.exports = __Identifier },{}],6:[function(require,module,exports){ module.exports = function( Marker ) { // Marker.patternMarkupFunctions[ valuesNode.type ]( valuesNode, state, seq, 'values', container, seqNumber ) const Literal = function( patternNode, state, seq, patternType, container=null, index=0 ) { if( patternNode.processed === true ) return const cm = state.cm const seqTarget = seq.object const patternObject = seq[ patternType ] const [ className, start, end ] = Marker._getNamesAndPosition( patternNode, state, patternType, index ) const cssName = className const marker = cm.markText( start, end, { 'className': cssName + ' annotation-border', //inclusiveLeft: true, //inclusiveRight: true }) if( seqTarget.markup === undefined ) Marker.prepareObject( seqTarget ) seqTarget.markup.textMarkers[ className ] = marker if( seqTarget.markup.cssClasses[ className ] === undefined ) seqTarget.markup.cssClasses[ className ] = [] seqTarget.markup.cssClasses[ className ][ index ] = cssName patternObject.marker = marker Marker.finalizePatternAnnotation( patternObject, className, seqTarget, marker ) } return Literal } },{}],7:[function(require,module,exports){ module.exports = function( Marker ) { // for negative literals e.g. -10 const UnaryExpression = function( patternNode, state, seq, patternType, container=null, index=0 ) { if( patternNode.processed === true ) return const cm = state.cm const seqTarget = seq.object const patternObject = seq[ patternType ] const [ className, start, end ] = Marker._getNamesAndPosition( patternNode, state, patternType, index ) const cssName = className marker = cm.markText( start, end, { 'className': cssName + ' annotation', //inclusiveLeft: true, //inclusiveRight: true }) if( seqTarget.markup === undefined ) Marker.prepareObject( seqTarget ) seqTarget.markup.textMarkers[ className ] = marker if( seqTarget.markup.cssClasses[ className ] === undefined ) seqTarget.markup.cssClasses[ className ] = [] seqTarget.markup.cssClasses[ className ][ index ] = cssName let start2 = Object.assign( {}, start ) start2.ch += 1 let marker2 = cm.markText( start, start2, { 'className': cssName + ' annotation-no-right-border', //inclusiveLeft: true, //inclusiveRight: true }) let marker3 = cm.markText( start2, end, { 'className': cssName + ' annotation-no-left-border', //inclusiveLeft: true, //inclusiveRight: true }) patternObject.marker = marker Marker.finalizePatternAnnotation( patternObject, className ) } return UnaryExpression } },{}],8:[function(require,module,exports){ const Utility = require( '../../utility.js' ) const $ = Utility.create const EuclidAnnotation = require( '../update/euclidAnnotation.js' ) module.exports = function( node, cm, track, objectName, state, cb ) { const Marker = Gibber.Environment.codeMarkup const steps = node.arguments[ 0 ].properties const Identifier = Marker.patternMarkupFunctions.Identifier track.markup.textMarkers[ 'step' ] = [] track.markup.textMarkers[ 'step' ].children = [] const hexSteps = window[ objectName ] const objectClassName = objectName + '_steps' let count = 0 for( let key in steps ) { let step = steps[ key ].value if( step && step.value ) { // ensure it is a correctly formed step step.loc.start.line += Marker.offset.vertical - 1 step.loc.end.line += Marker.offset.vertical - 1 step.loc.start.ch = step.loc.end.column - 1 step.loc.end.ch = step.loc.end.column const pattern = hexSteps.seqs[ steps[ key ].key.value ].timings // we estimate whether or not a comma was used to separate between // key / value pairs. If there's more than one pattern and this // isn't the last time through the for loop, we assume there is a // comma (otherwise an error would occur). const useComma = count++ != steps.length - 1 && steps.length > 1 if( useComma === true ) { // move off of end quote to comma step.loc.start.ch += 1 step.loc.end.ch += 1 // replace comma with a comma and a space cm.replaceRange( ", ", step.loc.start, step.loc.end ) step.loc.start.ch += 1 step.loc.end.ch += 1 }else{ // replace end quote with a quote and a space cm.replaceRange( "' ", step.loc.start, step.loc.end ) step.loc.start.ch += 1 step.loc.end.ch += 1 } let className = objectClassName + '_' + key let marker = cm.markText( step.loc.start, step.loc.end, { className } ) pattern.update = EuclidAnnotation( pattern, marker, className, cm, track ) pattern.patternName = className // store value changes in array and then pop them every time the annotation is updated pattern.update.value = [] Marker._addPatternFilter( pattern ) pattern.marker = marker /* patternObject._onchange = () => { let delay = Utility.beatsToMs( 1, Gibber.Scheduler.bpm ) Gibber.Environment.animationScheduler.add( () => { marker.doc.replaceRange( patternObject.values.join(''), step.loc.start, step.loc.end ) mark( step, key, cm, track ) }, delay ) } */ } } } },{"../../utility.js":49,"../update/euclidAnnotation.js":13}],9:[function(require,module,exports){ const Utility = require( '../../utility.js' ) const $ = Utility.create module.exports = function( node, cm, track, objectName, vOffset=0 ) { let timelineNodes = node.arguments[ 0 ].elements //console.log( timelineNodes ) track.markup.textMarkers[ 'score' ] = [] for( let i = 0; i < timelineNodes.length; i+=2 ) { let timeNode = timelineNodes[ i ], functionNode = timelineNodes[ i + 1 ] functionNode.loc.start.line += vOffset - 1 functionNode.loc.end.line += vOffset - 1 functionNode.loc.start.ch = functionNode.loc.start.column functionNode.loc.end.ch = functionNode.loc.end.column let marker = cm.markText( functionNode.loc.start, functionNode.loc.end, { className:`score${i/2}` } ) track.markup.textMarkers[ 'score' ][ i/2 ] = marker } let lastClass = 'score0' $( '.' + lastClass ).add( 'scoreCurrentIndex' ) // TODO: global object usage is baaaad methinks? window[ objectName ].onadvance = ( idx ) => { $( '.' + lastClass ).remove( 'scoreCurrentIndex' ) lastClass = `score${idx}` $( '.' + lastClass ).add( 'scoreCurrentIndex' ) } } },{"../../utility.js":49}],10:[function(require,module,exports){ const Utility = require( '../../utility.js' ) const $ = Utility.create module.exports = function( node, cm, track, objectName, state, cb ) { const Marker = Gibber.Environment.codeMarkup // tsk tsk tsk global... const steps = node.arguments[ 0 ].properties track.markup.textMarkers[ 'step' ] = [] track.markup.textMarkers[ 'step' ].children = [] const mark = ( _step, _key, _cm, _track ) => { for( let i = 0; i < _step.value.length; i++ ) { let pos = { loc:{ start:{}, end:{}} } Object.assign( pos.loc.start, _step.loc.start ) Object.assign( pos.loc.end , _step.loc.end ) pos.loc.start.ch += i pos.loc.end.ch = pos.loc.start.ch + 1 let posMark = _cm.markText( pos.loc.start, pos.loc.end, { className:`step_${_key}_${i}` }) _track.markup.textMarkers.step[ _key ].pattern[ i ] = posMark } } for( let key in steps ) { let step = steps[ key ].value if( step && step.value ) { // ensure it is a correctly formed step step.loc.start.line += Marker.offset.vertical - 1 step.loc.end.line += Marker.offset.vertical - 1 step.loc.start.ch = step.loc.start.column + 1 step.loc.end.ch = step.loc.end.column - 1 let marker = cm.markText( step.loc.start, step.loc.end, { className:`step${key}` } ) track.markup.textMarkers.step[ key ] = marker track.markup.textMarkers.step[ key ].pattern = [] mark( step, key, cm, track ) let count = 0, span, update, _key = steps[ key ].key.value, patternObject = window[ objectName ].seqs[ _key ].values update = () => { let currentIdx = update.currentIndex // count++ % step.value.length if( span !== undefined ) { span.remove( 'euclid0' ) span.remove( 'euclid1' ) } let spanName = `.step_${key}_${currentIdx}`, currentValue = patternObject.update.value.pop() //step.value[ currentIdx ] span = $( spanName ) if( currentValue !== Gibber.Seq.DO_NOT_OUTPUT ) { span.add( 'euclid1' ) setTimeout( ()=> { span.remove( 'euclid1' ) }, 50 ) } span.add( 'euclid0' ) } patternObject._onchange = () => { let delay = Utility.beatsToMs( 1, Gibber.Scheduler.bpm ) Gibber.Environment.animationScheduler.add( () => { marker.doc.replaceRange( patternObject.values.join(''), step.loc.start, step.loc.end ) mark( step, key, cm, track ) }, delay ) } patternObject.update = update patternObject.update.value = [] Marker._addPatternFilter( patternObject ) } } } },{"../../utility.js":49}],11:[function(require,module,exports){ module.exports = ( patternObject, marker, className, cm ) => { patternObject.commentMarker = marker let update = () => { if( !patternObject.commentMarker ) return let patternValue = '' + patternObject.update.value.pop() if( patternValue.length > 8 ) patternValue = patternValue.slice(0,8) let val ='/* ' + patternValue + ' */', pos = patternObject.commentMarker.find(), end = Object.assign( {}, pos.to ) //pos.from.ch += 1 end.ch = pos.from.ch + val.length //pos.from.ch += 1 cm.replace