UNPKG

wam-community

Version:

A collection of prebuilt Web Audio Modules ready for use

278 lines 157 kB
/*
 * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
 * This devtool is neither made for production nor for readable output files.
 * It uses "eval()" calls to create a separate source file in the browser devtools.
 * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
 * or disable the default devtool with "devtool: false".
 * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
 */
/******/ var __webpack_modules__ = ({

/***/ "../../../node_modules/preact/dist/preact.module.js":
/*!**********************************************************!*\
  !*** ../../../node_modules/preact/dist/preact.module.js ***!
  \**********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   Component: () => (/* binding */ _),\n/* harmony export */   Fragment: () => (/* binding */ d),\n/* harmony export */   cloneElement: () => (/* binding */ B),\n/* harmony export */   createContext: () => (/* binding */ D),\n/* harmony export */   createElement: () => (/* binding */ v),\n/* harmony export */   createRef: () => (/* binding */ p),\n/* harmony export */   h: () => (/* binding */ v),\n/* harmony export */   hydrate: () => (/* binding */ q),\n/* harmony export */   isValidElement: () => (/* binding */ i),\n/* harmony export */   options: () => (/* binding */ l),\n/* harmony export */   render: () => (/* binding */ S),\n/* harmony export */   toChildArray: () => (/* binding */ A)\n/* harmony export */ });\nvar n,l,u,i,t,o,r,f,e={},c=[],s=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function a(n,l){for(var u in l)n[u]=l[u];return n}function h(n){var l=n.parentNode;l&&l.removeChild(n)}function v(l,u,i){var t,o,r,f={};for(r in u)\"key\"==r?t=u[r]:\"ref\"==r?o=u[r]:f[r]=u[r];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):i),\"function\"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===f[r]&&(f[r]=l.defaultProps[r]);return y(l,f,t,o,null)}function y(n,i,t,o,r){var f={type:n,props:i,key:t,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==r?++u:r};return null!=l.vnode&&l.vnode(f),f}function p(){return{current:null}}function d(n){return n.children}function _(n,l){this.props=n,this.context=l}function k(n,l){if(null==l)return n.__?k(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return\"function\"==typeof n.type?k(n):null}function b(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return b(n)}}function m(n){(!n.__d&&(n.__d=!0)&&t.push(n)&&!g.__r++||r!==l.debounceRendering)&&((r=l.debounceRendering)||o)(g)}function g(){for(var n;g.__r=t.length;)n=t.sort(function(n,l){return n.__v.__b-l.__v.__b}),t=[],n.some(function(n){var l,u,i,t,o,r;n.__d&&(o=(t=(l=n).__v).__e,(r=l.__P)&&(u=[],(i=a({},t)).__v=t.__v+1,j(r,t,i,l.__n,void 0!==r.ownerSVGElement,null!=t.__h?[o]:null,u,null==o?k(t):o,t.__h),z(u,t),t.__e!=o&&b(t)))})}function w(n,l,u,i,t,o,r,f,s,a){var h,v,p,_,b,m,g,w=i&&i.__k||c,A=w.length;for(u.__k=[],h=0;h<l.length;h++)if(null!=(_=u.__k[h]=null==(_=l[h])||\"boolean\"==typeof _?null:\"string\"==typeof _||\"number\"==typeof _||\"bigint\"==typeof _?y(null,_,null,null,_):Array.isArray(_)?y(d,{children:_},null,null,null):_.__b>0?y(_.type,_.props,_.key,null,_.__v):_)){if(_.__=u,_.__b=u.__b+1,null===(p=w[h])||p&&_.key==p.key&&_.type===p.type)w[h]=void 0;else for(v=0;v<A;v++){if((p=w[v])&&_.key==p.key&&_.type===p.type){w[v]=void 0;break}p=null}j(n,_,p=p||e,t,o,r,f,s,a),b=_.__e,(v=_.ref)&&p.ref!=v&&(g||(g=[]),p.ref&&g.push(p.ref,null,_),g.push(v,_.__c||b,_)),null!=b?(null==m&&(m=b),\"function\"==typeof _.type&&null!=_.__k&&_.__k===p.__k?_.__d=s=x(_,s,n):s=P(n,_,p,w,b,s),a||\"option\"!==u.type?\"function\"==typeof u.type&&(u.__d=s):n.value=\"\"):s&&p.__e==s&&s.parentNode!=n&&(s=k(p))}for(u.__e=m,h=A;h--;)null!=w[h]&&(\"function\"==typeof u.type&&null!=w[h].__e&&w[h].__e==u.__d&&(u.__d=k(i,h+1)),N(w[h],w[h]));if(g)for(h=0;h<g.length;h++)M(g[h],g[++h],g[++h])}function x(n,l,u){var i,t;for(i=0;i<n.__k.length;i++)(t=n.__k[i])&&(t.__=n,l=\"function\"==typeof t.type?x(t,l,u):P(u,t,t,n.__k,t.__e,l));return l}function A(n,l){return l=l||[],null==n||\"boolean\"==typeof n||(Array.isArray(n)?n.some(function(n){A(n,l)}):l.push(n)),l}function P(n,l,u,i,t,o){var r,f,e;if(void 0!==l.__d)r=l.__d,l.__d=void 0;else if(null==u||t!=o||null==t.parentNode)n:if(null==o||o.parentNode!==n)n.appendChild(t),r=null;else{for(f=o,e=0;(f=f.nextSibling)&&e<i.length;e+=2)if(f==t)break n;n.insertBefore(t,o),r=o}return void 0!==r?r:t.nextSibling}function C(n,l,u,i,t){var o;for(o in u)\"children\"===o||\"key\"===o||o in l||H(n,o,null,u[o],i);for(o in l)t&&\"function\"!=typeof l[o]||\"children\"===o||\"key\"===o||\"value\"===o||\"checked\"===o||u[o]===l[o]||H(n,o,l[o],u[o],i)}function $(n,l,u){\"-\"===l[0]?n.setProperty(l,u):n[l]=null==u?\"\":\"number\"!=typeof u||s.test(l)?u:u+\"px\"}function H(n,l,u,i,t){var o;n:if(\"style\"===l)if(\"string\"==typeof u)n.style.cssText=u;else{if(\"string\"==typeof i&&(n.style.cssText=i=\"\"),i)for(l in i)u&&l in u||$(n.style,l,\"\");if(u)for(l in u)i&&u[l]===i[l]||$(n.style,l,u[l])}else if(\"o\"===l[0]&&\"n\"===l[1])o=l!==(l=l.replace(/Capture$/,\"\")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?i||n.addEventListener(l,o?T:I,o):n.removeEventListener(l,o?T:I,o);else if(\"dangerouslySetInnerHTML\"!==l){if(t)l=l.replace(/xlink[H:h]/,\"h\").replace(/sName$/,\"s\");else if(\"href\"!==l&&\"list\"!==l&&\"form\"!==l&&\"tabIndex\"!==l&&\"download\"!==l&&l in n)try{n[l]=null==u?\"\":u;break n}catch(n){}\"function\"==typeof u||(null!=u&&(!1!==u||\"a\"===l[0]&&\"r\"===l[1])?n.setAttribute(l,u):n.removeAttribute(l))}}function I(n){this.l[n.type+!1](l.event?l.event(n):n)}function T(n){this.l[n.type+!0](l.event?l.event(n):n)}function j(n,u,i,t,o,r,f,e,c){var s,h,v,y,p,k,b,m,g,x,A,P=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(c=i.__h,e=u.__e=i.__e,u.__h=null,r=[e]),(s=l.__b)&&s(u);try{n:if(\"function\"==typeof P){if(m=u.props,g=(s=P.contextType)&&t[s.__c],x=s?g?g.props.value:s.__:t,i.__c?b=(h=u.__c=i.__c).__=h.__E:(\"prototype\"in P&&P.prototype.render?u.__c=h=new P(m,x):(u.__c=h=new _(m,x),h.constructor=P,h.render=O),g&&g.sub(h),h.props=m,h.state||(h.state={}),h.context=x,h.__n=t,v=h.__d=!0,h.__h=[]),null==h.__s&&(h.__s=h.state),null!=P.getDerivedStateFromProps&&(h.__s==h.state&&(h.__s=a({},h.__s)),a(h.__s,P.getDerivedStateFromProps(m,h.__s))),y=h.props,p=h.state,v)null==P.getDerivedStateFromProps&&null!=h.componentWillMount&&h.componentWillMount(),null!=h.componentDidMount&&h.__h.push(h.componentDidMount);else{if(null==P.getDerivedStateFromProps&&m!==y&&null!=h.componentWillReceiveProps&&h.componentWillReceiveProps(m,x),!h.__e&&null!=h.shouldComponentUpdate&&!1===h.shouldComponentUpdate(m,h.__s,x)||u.__v===i.__v){h.props=m,h.state=h.__s,u.__v!==i.__v&&(h.__d=!1),h.__v=u,u.__e=i.__e,u.__k=i.__k,u.__k.forEach(function(n){n&&(n.__=u)}),h.__h.length&&f.push(h);break n}null!=h.componentWillUpdate&&h.componentWillUpdate(m,h.__s,x),null!=h.componentDidUpdate&&h.__h.push(function(){h.componentDidUpdate(y,p,k)})}h.context=x,h.props=m,h.state=h.__s,(s=l.__r)&&s(u),h.__d=!1,h.__v=u,h.__P=n,s=h.render(h.props,h.state,h.context),h.state=h.__s,null!=h.getChildContext&&(t=a(a({},t),h.getChildContext())),v||null==h.getSnapshotBeforeUpdate||(k=h.getSnapshotBeforeUpdate(y,p)),A=null!=s&&s.type===d&&null==s.key?s.props.children:s,w(n,Array.isArray(A)?A:[A],u,i,t,o,r,f,e,c),h.base=u.__e,u.__h=null,h.__h.length&&f.push(h),b&&(h.__E=h.__=null),h.__e=!1}else null==r&&u.__v===i.__v?(u.__k=i.__k,u.__e=i.__e):u.__e=L(i.__e,u,i,t,o,r,f,c);(s=l.diffed)&&s(u)}catch(n){u.__v=null,(c||null!=r)&&(u.__e=e,u.__h=!!c,r[r.indexOf(e)]=null),l.__e(n,u,i)}}function z(n,u){l.__c&&l.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u)})}catch(n){l.__e(n,u.__v)}})}function L(l,u,i,t,o,r,f,c){var s,a,v,y=i.props,p=u.props,d=u.type,_=0;if(\"svg\"===d&&(o=!0),null!=r)for(;_<r.length;_++)if((s=r[_])&&(s===l||(d?s.localName==d:3==s.nodeType))){l=s,r[_]=null;break}if(null==l){if(null===d)return document.createTextNode(p);l=o?document.createElementNS(\"http://www.w3.org/2000/svg\",d):document.createElement(d,p.is&&p),r=null,c=!1}if(null===d)y===p||c&&l.data===p||(l.data=p);else{if(r=r&&n.call(l.childNodes),a=(y=i.props||e).dangerouslySetInnerHTML,v=p.dangerouslySetInnerHTML,!c){if(null!=r)for(y={},_=0;_<l.attributes.length;_++)y[l.attributes[_].name]=l.attributes[_].value;(v||a)&&(v&&(a&&v.__html==a.__html||v.__html===l.innerHTML)||(l.innerHTML=v&&v.__html||\"\"))}if(C(l,p,y,o,c),v)u.__k=[];else if(_=u.props.children,w(l,Array.isArray(_)?_:[_],u,i,t,o&&\"foreignObject\"!==d,r,f,r?r[0]:i.__k&&k(i,0),c),null!=r)for(_=r.length;_--;)null!=r[_]&&h(r[_]);c||(\"value\"in p&&void 0!==(_=p.value)&&(_!==l.value||\"progress\"===d&&!_)&&H(l,\"value\",_,y.value,!1),\"checked\"in p&&void 0!==(_=p.checked)&&_!==l.checked&&H(l,\"checked\",_,y.checked,!1))}return l}function M(n,u,i){try{\"function\"==typeof n?n(u):n.current=u}catch(n){l.__e(n,i)}}function N(n,u,i){var t,o;if(l.unmount&&l.unmount(n),(t=n.ref)&&(t.current&&t.current!==n.__e||M(t,null,u)),null!=(t=n.__c)){if(t.componentWillUnmount)try{t.componentWillUnmount()}catch(n){l.__e(n,u)}t.base=t.__P=null}if(t=n.__k)for(o=0;o<t.length;o++)t[o]&&N(t[o],u,\"function\"!=typeof n.type);i||null==n.__e||h(n.__e),n.__e=n.__d=void 0}function O(n,l,u){return this.constructor(n,u)}function S(u,i,t){var o,r,f;l.__&&l.__(u,i),r=(o=\"function\"==typeof t)?null:t&&t.__k||i.__k,f=[],j(i,u=(!o&&t||i).__k=v(d,null,[u]),r||e,e,void 0!==i.ownerSVGElement,!o&&t?[t]:r?null:i.firstChild?n.call(i.childNodes):null,f,!o&&t?t:r?r.__e:i.firstChild,o),z(f,u)}function q(n,l){S(n,l,q)}function B(l,u,i){var t,o,r,f=a({},l.props);for(r in u)\"key\"==r?t=u[r]:\"ref\"==r?o=u[r]:f[r]=u[r];return arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):i),y(l.type,f,t||l.key,o||l.ref,null)}function D(n,l){var u={__c:l=\"__cC\"+f++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,i;return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(m)},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n)}}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n=c.slice,l={__e:function(n,l){for(var u,i,t;l=l.__;)if((u=l.__c)&&!u.__)try{if((i=u.constructor)&&null!=i.getDerivedStateFromError&&(u.setState(i.getDerivedStateFromError(n)),t=u.__d),null!=u.componentDidCatch&&(u.componentDidCatch(n),t=u.__d),t)return u.__E=u}catch(l){n=l}throw n}},u=0,i=function(n){return null!=n&&void 0===n.constructor},_.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=a({},this.state),\"function\"==typeof n&&(n=n(a({},u),this.props)),n&&a(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),m(this))},_.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),m(this))},_.prototype.render=d,t=[],o=\"function\"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,g.__r=0,f=0;\n//# sourceMappingURL=preact.module.js.map\n\n\n//# sourceURL=webpack://pianoroll/../../../node_modules/preact/dist/preact.module.js?");

/***/ }),

/***/ "./node_modules/css-loader/dist/runtime/api.js":
/*!*****************************************************!*\
  !*** ./node_modules/css-loader/dist/runtime/api.js ***!
  \*****************************************************/
/***/ ((module) => {

eval("\n\n/*\n  MIT License http://www.opensource.org/licenses/mit-license.php\n  Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n  var list = []; // return the list of modules as css string\n\n  list.toString = function toString() {\n    return this.map(function (item) {\n      var content = \"\";\n      var needLayer = typeof item[5] !== \"undefined\";\n\n      if (item[4]) {\n        content += \"@supports (\".concat(item[4], \") {\");\n      }\n\n      if (item[2]) {\n        content += \"@media \".concat(item[2], \" {\");\n      }\n\n      if (needLayer) {\n        content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n      }\n\n      content += cssWithMappingToString(item);\n\n      if (needLayer) {\n        content += \"}\";\n      }\n\n      if (item[2]) {\n        content += \"}\";\n      }\n\n      if (item[4]) {\n        content += \"}\";\n      }\n\n      return content;\n    }).join(\"\");\n  }; // import a list of modules into the list\n\n\n  list.i = function i(modules, media, dedupe, supports, layer) {\n    if (typeof modules === \"string\") {\n      modules = [[null, modules, undefined]];\n    }\n\n    var alreadyImportedModules = {};\n\n    if (dedupe) {\n      for (var k = 0; k < this.length; k++) {\n        var id = this[k][0];\n\n        if (id != null) {\n          alreadyImportedModules[id] = true;\n        }\n      }\n    }\n\n    for (var _k = 0; _k < modules.length; _k++) {\n      var item = [].concat(modules[_k]);\n\n      if (dedupe && alreadyImportedModules[item[0]]) {\n        continue;\n      }\n\n      if (typeof layer !== \"undefined\") {\n        if (typeof item[5] === \"undefined\") {\n          item[5] = layer;\n        } else {\n          item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n          item[5] = layer;\n        }\n      }\n\n      if (media) {\n        if (!item[2]) {\n          item[2] = media;\n        } else {\n          item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n          item[2] = media;\n        }\n      }\n\n      if (supports) {\n        if (!item[4]) {\n          item[4] = \"\".concat(supports);\n        } else {\n          item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n          item[4] = supports;\n        }\n      }\n\n      list.push(item);\n    }\n  };\n\n  return list;\n};\n\n//# sourceURL=webpack://pianoroll/./node_modules/css-loader/dist/runtime/api.js?");

/***/ }),

/***/ "./node_modules/css-loader/dist/runtime/noSourceMaps.js":
/*!**************************************************************!*\
  !*** ./node_modules/css-loader/dist/runtime/noSourceMaps.js ***!
  \**************************************************************/
/***/ ((module) => {

eval("\n\nmodule.exports = function (i) {\n  return i[1];\n};\n\n//# sourceURL=webpack://pianoroll/./node_modules/css-loader/dist/runtime/noSourceMaps.js?");

/***/ }),

/***/ "./src/PianoRollView.scss":
/*!********************************!*\
  !*** ./src/PianoRollView.scss ***!
  \********************************/
/***/ ((module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/noSourceMaps.js */ \"./node_modules/css-loader/dist/runtime/noSourceMaps.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".ComponentWrapper {\\n  display: flex;\\n  flex-direction: column;\\n  align-items: center;\\n  text-align: center;\\n  flex: 1;\\n  padding: 4px;\\n}\\n\\n.Fader {\\n  margin-top: auto;\\n  display: flex;\\n  flex-direction: column;\\n}\\n\\n.Knob {\\n  margin-top: auto;\\n  display: flex;\\n  flex-direction: column;\\n}\\n\\n.ComponentSelect {\\n  margin-bottom: auto;\\n  margin-top: auto;\\n  margin-bottom: auto;\\n  display: flex;\\n  flex-direction: column;\\n}\\n\\n.GlowModalBackdrop {\\n  position: fixed;\\n  top: 0;\\n  bottom: 0;\\n  left: 0;\\n  right: 0;\\n  background-color: rgba(0, 0, 0, 0.3);\\n  padding: 50px;\\n  z-index: 99999998;\\n}\\n\\n.GlowModalContainer {\\n  position: fixed;\\n  top: 50%;\\n  left: 50%;\\n  transform: translate(-50%, -50%);\\n  margin: 0 auto;\\n  z-index: 99999998;\\n}\\n\\n.maPwT5XDHb1pxRkZlJwa {\\n  flex: 1;\\n  overflow: hidden;\\n  display: flex;\\n  flex-direction: column;\\n  background-color: gray;\\n  z-index: 1;\\n}\\n\\n.PUE5SCvjje_qSRMUz2vG {\\n  flex-shrink: 1;\\n  overflow: scroll;\\n  overflow-x: hidden;\\n  position: relative;\\n}\\n\\n.jcjpSF9VBwQEAfvCl2GX {\\n  stroke: grey;\\n  fill: none;\\n  stroke-width: 1;\\n}\\n\\n.DB6NpFveoxz2Dl737toQ {\\n  position: absolute;\\n  top: 0;\\n  left: 0;\\n}\\n\\n.LFYyr5G3wPwBBqs6oeot {\\n  padding: 5px;\\n  border: 1px solid;\\n  border-radius: 5%;\\n  margin: 5px;\\n  font-weight: bold;\\n}\\n\\n.XzNvsFpiOBd7q9LNoKZc {\\n  z-index: 2;\\n  position: relative;\\n}\", \"\"]);\n// Exports\n___CSS_LOADER_EXPORT___.locals = {\n\t\"pianorollContainer\": \"maPwT5XDHb1pxRkZlJwa\",\n\t\"pianorollBody\": \"PUE5SCvjje_qSRMUz2vG\",\n\t\"pianoroll\": \"jcjpSF9VBwQEAfvCl2GX\",\n\t\"playhead\": \"DB6NpFveoxz2Dl737toQ\",\n\t\"menuButton\": \"LFYyr5G3wPwBBqs6oeot\",\n\t\"anchor\": \"XzNvsFpiOBd7q9LNoKZc\"\n};\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://pianoroll/./src/PianoRollView.scss?");

/***/ }),

/***/ "./node_modules/preact/dist/preact.module.js":
/*!***************************************************!*\
  !*** ./node_modules/preact/dist/preact.module.js ***!
  \***************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   Component: () => (/* binding */ _),\n/* harmony export */   Fragment: () => (/* binding */ d),\n/* harmony export */   cloneElement: () => (/* binding */ B),\n/* harmony export */   createContext: () => (/* binding */ D),\n/* harmony export */   createElement: () => (/* binding */ v),\n/* harmony export */   createRef: () => (/* binding */ p),\n/* harmony export */   h: () => (/* binding */ v),\n/* harmony export */   hydrate: () => (/* binding */ q),\n/* harmony export */   isValidElement: () => (/* binding */ i),\n/* harmony export */   options: () => (/* binding */ l),\n/* harmony export */   render: () => (/* binding */ S),\n/* harmony export */   toChildArray: () => (/* binding */ A)\n/* harmony export */ });\nvar n,l,u,i,t,o,r,f,e={},c=[],s=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function a(n,l){for(var u in l)n[u]=l[u];return n}function h(n){var l=n.parentNode;l&&l.removeChild(n)}function v(l,u,i){var t,o,r,f={};for(r in u)\"key\"==r?t=u[r]:\"ref\"==r?o=u[r]:f[r]=u[r];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):i),\"function\"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===f[r]&&(f[r]=l.defaultProps[r]);return y(l,f,t,o,null)}function y(n,i,t,o,r){var f={type:n,props:i,key:t,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==r?++u:r};return null!=l.vnode&&l.vnode(f),f}function p(){return{current:null}}function d(n){return n.children}function _(n,l){this.props=n,this.context=l}function k(n,l){if(null==l)return n.__?k(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return\"function\"==typeof n.type?k(n):null}function b(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return b(n)}}function m(n){(!n.__d&&(n.__d=!0)&&t.push(n)&&!g.__r++||r!==l.debounceRendering)&&((r=l.debounceRendering)||o)(g)}function g(){for(var n;g.__r=t.length;)n=t.sort(function(n,l){return n.__v.__b-l.__v.__b}),t=[],n.some(function(n){var l,u,i,t,o,r;n.__d&&(o=(t=(l=n).__v).__e,(r=l.__P)&&(u=[],(i=a({},t)).__v=t.__v+1,j(r,t,i,l.__n,void 0!==r.ownerSVGElement,null!=t.__h?[o]:null,u,null==o?k(t):o,t.__h),z(u,t),t.__e!=o&&b(t)))})}function w(n,l,u,i,t,o,r,f,s,a){var h,v,p,_,b,m,g,w=i&&i.__k||c,A=w.length;for(u.__k=[],h=0;h<l.length;h++)if(null!=(_=u.__k[h]=null==(_=l[h])||\"boolean\"==typeof _?null:\"string\"==typeof _||\"number\"==typeof _||\"bigint\"==typeof _?y(null,_,null,null,_):Array.isArray(_)?y(d,{children:_},null,null,null):_.__b>0?y(_.type,_.props,_.key,null,_.__v):_)){if(_.__=u,_.__b=u.__b+1,null===(p=w[h])||p&&_.key==p.key&&_.type===p.type)w[h]=void 0;else for(v=0;v<A;v++){if((p=w[v])&&_.key==p.key&&_.type===p.type){w[v]=void 0;break}p=null}j(n,_,p=p||e,t,o,r,f,s,a),b=_.__e,(v=_.ref)&&p.ref!=v&&(g||(g=[]),p.ref&&g.push(p.ref,null,_),g.push(v,_.__c||b,_)),null!=b?(null==m&&(m=b),\"function\"==typeof _.type&&null!=_.__k&&_.__k===p.__k?_.__d=s=x(_,s,n):s=P(n,_,p,w,b,s),a||\"option\"!==u.type?\"function\"==typeof u.type&&(u.__d=s):n.value=\"\"):s&&p.__e==s&&s.parentNode!=n&&(s=k(p))}for(u.__e=m,h=A;h--;)null!=w[h]&&(\"function\"==typeof u.type&&null!=w[h].__e&&w[h].__e==u.__d&&(u.__d=k(i,h+1)),N(w[h],w[h]));if(g)for(h=0;h<g.length;h++)M(g[h],g[++h],g[++h])}function x(n,l,u){var i,t;for(i=0;i<n.__k.length;i++)(t=n.__k[i])&&(t.__=n,l=\"function\"==typeof t.type?x(t,l,u):P(u,t,t,n.__k,t.__e,l));return l}function A(n,l){return l=l||[],null==n||\"boolean\"==typeof n||(Array.isArray(n)?n.some(function(n){A(n,l)}):l.push(n)),l}function P(n,l,u,i,t,o){var r,f,e;if(void 0!==l.__d)r=l.__d,l.__d=void 0;else if(null==u||t!=o||null==t.parentNode)n:if(null==o||o.parentNode!==n)n.appendChild(t),r=null;else{for(f=o,e=0;(f=f.nextSibling)&&e<i.length;e+=2)if(f==t)break n;n.insertBefore(t,o),r=o}return void 0!==r?r:t.nextSibling}function C(n,l,u,i,t){var o;for(o in u)\"children\"===o||\"key\"===o||o in l||H(n,o,null,u[o],i);for(o in l)t&&\"function\"!=typeof l[o]||\"children\"===o||\"key\"===o||\"value\"===o||\"checked\"===o||u[o]===l[o]||H(n,o,l[o],u[o],i)}function $(n,l,u){\"-\"===l[0]?n.setProperty(l,u):n[l]=null==u?\"\":\"number\"!=typeof u||s.test(l)?u:u+\"px\"}function H(n,l,u,i,t){var o;n:if(\"style\"===l)if(\"string\"==typeof u)n.style.cssText=u;else{if(\"string\"==typeof i&&(n.style.cssText=i=\"\"),i)for(l in i)u&&l in u||$(n.style,l,\"\");if(u)for(l in u)i&&u[l]===i[l]||$(n.style,l,u[l])}else if(\"o\"===l[0]&&\"n\"===l[1])o=l!==(l=l.replace(/Capture$/,\"\")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?i||n.addEventListener(l,o?T:I,o):n.removeEventListener(l,o?T:I,o);else if(\"dangerouslySetInnerHTML\"!==l){if(t)l=l.replace(/xlink[H:h]/,\"h\").replace(/sName$/,\"s\");else if(\"href\"!==l&&\"list\"!==l&&\"form\"!==l&&\"tabIndex\"!==l&&\"download\"!==l&&l in n)try{n[l]=null==u?\"\":u;break n}catch(n){}\"function\"==typeof u||(null!=u&&(!1!==u||\"a\"===l[0]&&\"r\"===l[1])?n.setAttribute(l,u):n.removeAttribute(l))}}function I(n){this.l[n.type+!1](l.event?l.event(n):n)}function T(n){this.l[n.type+!0](l.event?l.event(n):n)}function j(n,u,i,t,o,r,f,e,c){var s,h,v,y,p,k,b,m,g,x,A,P=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(c=i.__h,e=u.__e=i.__e,u.__h=null,r=[e]),(s=l.__b)&&s(u);try{n:if(\"function\"==typeof P){if(m=u.props,g=(s=P.contextType)&&t[s.__c],x=s?g?g.props.value:s.__:t,i.__c?b=(h=u.__c=i.__c).__=h.__E:(\"prototype\"in P&&P.prototype.render?u.__c=h=new P(m,x):(u.__c=h=new _(m,x),h.constructor=P,h.render=O),g&&g.sub(h),h.props=m,h.state||(h.state={}),h.context=x,h.__n=t,v=h.__d=!0,h.__h=[]),null==h.__s&&(h.__s=h.state),null!=P.getDerivedStateFromProps&&(h.__s==h.state&&(h.__s=a({},h.__s)),a(h.__s,P.getDerivedStateFromProps(m,h.__s))),y=h.props,p=h.state,v)null==P.getDerivedStateFromProps&&null!=h.componentWillMount&&h.componentWillMount(),null!=h.componentDidMount&&h.__h.push(h.componentDidMount);else{if(null==P.getDerivedStateFromProps&&m!==y&&null!=h.componentWillReceiveProps&&h.componentWillReceiveProps(m,x),!h.__e&&null!=h.shouldComponentUpdate&&!1===h.shouldComponentUpdate(m,h.__s,x)||u.__v===i.__v){h.props=m,h.state=h.__s,u.__v!==i.__v&&(h.__d=!1),h.__v=u,u.__e=i.__e,u.__k=i.__k,u.__k.forEach(function(n){n&&(n.__=u)}),h.__h.length&&f.push(h);break n}null!=h.componentWillUpdate&&h.componentWillUpdate(m,h.__s,x),null!=h.componentDidUpdate&&h.__h.push(function(){h.componentDidUpdate(y,p,k)})}h.context=x,h.props=m,h.state=h.__s,(s=l.__r)&&s(u),h.__d=!1,h.__v=u,h.__P=n,s=h.render(h.props,h.state,h.context),h.state=h.__s,null!=h.getChildContext&&(t=a(a({},t),h.getChildContext())),v||null==h.getSnapshotBeforeUpdate||(k=h.getSnapshotBeforeUpdate(y,p)),A=null!=s&&s.type===d&&null==s.key?s.props.children:s,w(n,Array.isArray(A)?A:[A],u,i,t,o,r,f,e,c),h.base=u.__e,u.__h=null,h.__h.length&&f.push(h),b&&(h.__E=h.__=null),h.__e=!1}else null==r&&u.__v===i.__v?(u.__k=i.__k,u.__e=i.__e):u.__e=L(i.__e,u,i,t,o,r,f,c);(s=l.diffed)&&s(u)}catch(n){u.__v=null,(c||null!=r)&&(u.__e=e,u.__h=!!c,r[r.indexOf(e)]=null),l.__e(n,u,i)}}function z(n,u){l.__c&&l.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u)})}catch(n){l.__e(n,u.__v)}})}function L(l,u,i,t,o,r,f,c){var s,a,v,y=i.props,p=u.props,d=u.type,_=0;if(\"svg\"===d&&(o=!0),null!=r)for(;_<r.length;_++)if((s=r[_])&&(s===l||(d?s.localName==d:3==s.nodeType))){l=s,r[_]=null;break}if(null==l){if(null===d)return document.createTextNode(p);l=o?document.createElementNS(\"http://www.w3.org/2000/svg\",d):document.createElement(d,p.is&&p),r=null,c=!1}if(null===d)y===p||c&&l.data===p||(l.data=p);else{if(r=r&&n.call(l.childNodes),a=(y=i.props||e).dangerouslySetInnerHTML,v=p.dangerouslySetInnerHTML,!c){if(null!=r)for(y={},_=0;_<l.attributes.length;_++)y[l.attributes[_].name]=l.attributes[_].value;(v||a)&&(v&&(a&&v.__html==a.__html||v.__html===l.innerHTML)||(l.innerHTML=v&&v.__html||\"\"))}if(C(l,p,y,o,c),v)u.__k=[];else if(_=u.props.children,w(l,Array.isArray(_)?_:[_],u,i,t,o&&\"foreignObject\"!==d,r,f,r?r[0]:i.__k&&k(i,0),c),null!=r)for(_=r.length;_--;)null!=r[_]&&h(r[_]);c||(\"value\"in p&&void 0!==(_=p.value)&&(_!==l.value||\"progress\"===d&&!_)&&H(l,\"value\",_,y.value,!1),\"checked\"in p&&void 0!==(_=p.checked)&&_!==l.checked&&H(l,\"checked\",_,y.checked,!1))}return l}function M(n,u,i){try{\"function\"==typeof n?n(u):n.current=u}catch(n){l.__e(n,i)}}function N(n,u,i){var t,o;if(l.unmount&&l.unmount(n),(t=n.ref)&&(t.current&&t.current!==n.__e||M(t,null,u)),null!=(t=n.__c)){if(t.componentWillUnmount)try{t.componentWillUnmount()}catch(n){l.__e(n,u)}t.base=t.__P=null}if(t=n.__k)for(o=0;o<t.length;o++)t[o]&&N(t[o],u,\"function\"!=typeof n.type);i||null==n.__e||h(n.__e),n.__e=n.__d=void 0}function O(n,l,u){return this.constructor(n,u)}function S(u,i,t){var o,r,f;l.__&&l.__(u,i),r=(o=\"function\"==typeof t)?null:t&&t.__k||i.__k,f=[],j(i,u=(!o&&t||i).__k=v(d,null,[u]),r||e,e,void 0!==i.ownerSVGElement,!o&&t?[t]:r?null:i.firstChild?n.call(i.childNodes):null,f,!o&&t?t:r?r.__e:i.firstChild,o),z(f,u)}function q(n,l){S(n,l,q)}function B(l,u,i){var t,o,r,f=a({},l.props);for(r in u)\"key\"==r?t=u[r]:\"ref\"==r?o=u[r]:f[r]=u[r];return arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):i),y(l.type,f,t||l.key,o||l.ref,null)}function D(n,l){var u={__c:l=\"__cC\"+f++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,i;return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(m)},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n)}}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n=c.slice,l={__e:function(n,l){for(var u,i,t;l=l.__;)if((u=l.__c)&&!u.__)try{if((i=u.constructor)&&null!=i.getDerivedStateFromError&&(u.setState(i.getDerivedStateFromError(n)),t=u.__d),null!=u.componentDidCatch&&(u.componentDidCatch(n),t=u.__d),t)return u.__E=u}catch(l){n=l}throw n}},u=0,i=function(n){return null!=n&&void 0===n.constructor},_.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=a({},this.state),\"function\"==typeof n&&(n=n(a({},u),this.props)),n&&a(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),m(this))},_.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),m(this))},_.prototype.render=d,t=[],o=\"function\"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,g.__r=0,f=0;\n//# sourceMappingURL=preact.module.js.map\n\n\n//# sourceURL=webpack://pianoroll/./node_modules/preact/dist/preact.module.js?");

/***/ }),

/***/ "./src/Clip.ts":
/*!*********************!*\
  !*** ./src/Clip.ts ***!
  \*********************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   Clip: () => (/* binding */ Clip),\n/* harmony export */   PP16: () => (/* binding */ PP16),\n/* harmony export */   PPQN: () => (/* binding */ PPQN)\n/* harmony export */ });\n/* harmony import */ var _shared_util__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../shared/util */ \"../shared/util.ts\");\n\nconst PPQN = 24;\nconst PP16 = (PPQN / 4);\nclass Clip {\n    constructor(id, state) {\n        if (state) {\n            this.state = {\n                id: id || state.id,\n                length: state.length,\n                notes: state.notes.map(n => {\n                    return { ...n };\n                })\n            };\n        }\n        else {\n            this.state = {\n                id: id || (0,_shared_util__WEBPACK_IMPORTED_MODULE_0__.token)(),\n                length: 16 * PP16,\n                notes: []\n            };\n        }\n        this.dirty = true;\n        this.quantize = PP16;\n    }\n    getState(removeId) {\n        let state = {\n            length: this.state.length,\n            notes: this.state.notes.map(n => {\n                return { ...n };\n            })\n        };\n        if (!removeId) {\n            state.id = this.state.id;\n        }\n        return state;\n    }\n    async setState(state, newId) {\n        if (!state.id && !newId) {\n            console.error(\"Need an id for clip!\");\n            return;\n        }\n        this.state.id = newId ? newId : state.id;\n        this.state.length = state.length;\n        this.state.notes = state.notes.map(n => {\n            return { ...n };\n        });\n        this.dirty = true;\n        if (this.updateProcessor)\n            this.updateProcessor(this);\n    }\n    hasNote(tick, number) {\n        return this.state.notes.some((n) => n.tick == tick && n.number == number);\n    }\n    addNote(tick, number, duration, velocity) {\n        this.dirty = true;\n        if (this.hasNote(tick, number)) {\n            return;\n        }\n        for (var insertIndex = 0; insertIndex < this.state.notes.length && this.state.notes[insertIndex].tick < tick; insertIndex++)\n            ;\n        this.state.notes = this.state.notes.slice(0, insertIndex).concat([{ tick, number, duration, velocity }].concat(this.state.notes.slice(insertIndex, this.state.notes.length)));\n        if (this.updateProcessor)\n            this.updateProcessor(this);\n    }\n    removeNote(tick, number) {\n        this.dirty = true;\n        this.state.notes = this.state.notes.filter((n) => n.tick != tick || n.number != number);\n        if (this.updateProcessor)\n            this.updateProcessor(this);\n    }\n    notesForTick(tick) {\n        return this.state.notes.filter((n) => n.tick == tick);\n    }\n    notesInTickRange(startTick, endTick, note) {\n        return this.state.notes.filter((n) => {\n            return n.number == note && n.tick + n.duration > startTick && n.tick < endTick;\n        });\n    }\n    setRenderFlag(dirty) {\n        this.dirty = dirty;\n    }\n    setQuantize(quantize) {\n        if (this.quantize != quantize) {\n            this.dirty = true;\n        }\n        this.quantize = quantize;\n    }\n    needsRender() {\n        return this.dirty;\n    }\n}\n\n\n//# sourceURL=webpack://pianoroll/./src/Clip.ts?");

/***/ }),

/***/ "./src/ClipSettingsView.tsx":
/*!**********************************!*\
  !*** ./src/ClipSettingsView.tsx ***!
  \**********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   ClipSettingsView: () => (/* binding */ ClipSettingsView)\n/* harmony export */ });\n/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! preact */ \"./node_modules/preact/dist/preact.module.js\");\n/* harmony import */ var _shared_ui_Select__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../shared/ui/Select */ \"../shared/ui/Select.tsx\");\n/* harmony import */ var _shared_ui_TextInput__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../shared/ui/TextInput */ \"../shared/ui/TextInput.tsx\");\n\n\n\nconst quantizeOptions = [\n    \"off\",\n    \"1/32\",\n    \"1/16\",\n    \"1/8\",\n    \"1/4\",\n    \"1 bar\"\n];\nconst quantizeValues = [\n    1,\n    3,\n    6,\n    12,\n    24,\n    96\n];\nconst outputChannelOptions = [\n    \"1\",\n    \"2\",\n    \"3\",\n    \"4\",\n    \"5\",\n    \"6\",\n    \"7\",\n    \"8\",\n    \"9\",\n    \"10\",\n    \"11\",\n    \"12\",\n    \"13\",\n    \"14\",\n    \"15\",\n    \"16\",\n];\nconst outputChannelValues = [\n    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15\n];\nconst inputChannelOptions = [\"OMNI\", ...outputChannelOptions];\nconst inputChannelValues = [-1, ...outputChannelValues];\nclass ClipSettingsView extends preact__WEBPACK_IMPORTED_MODULE_0__.Component {\n    constructor() {\n        super();\n    }\n    quantizeChanged(value) {\n        this.props.clip.setQuantize(parseInt(value));\n        this.props.onChange();\n    }\n    inputMidiChanged(value) {\n        this.props.pianoRoll.inputMidiChanged(parseInt(value));\n        this.props.onChange();\n    }\n    outputMidiChanged(value) {\n        this.props.pianoRoll.outputMidiChanged(parseInt(value));\n        this.props.onChange();\n    }\n    lengthChanged(e) {\n        var length = parseInt(e.target.value);\n        if (isNaN(length) || length < 1) {\n            length = 1;\n        }\n        let state = this.props.clip.getState();\n        state.length = (length * 96);\n        this.props.clip.setState(state);\n        this.props.onChange();\n    }\n    clearClip() {\n        let state = this.props.clip.getState();\n        state.notes = [];\n        this.props.clip.setState(state);\n        this.props.onChange();\n    }\n    render() {\n        (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", {});\n        let bars = this.props.clip.state.length / 96;\n        return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", { style: \"background-color: var(--var-SecondaryBackground); color: var(--var-SecondaryForeground); padding: 5px; z-index: 2;\" },\n            (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", { style: \"display: flex; align-items: center\" },\n                (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"label\", null, \"Quantize\"),\n                (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(_shared_ui_Select__WEBPACK_IMPORTED_MODULE_1__.Select, { style: \"flex-direction: row-reverse;\", options: quantizeOptions, values: quantizeValues, value: () => this.props.clip.quantize, onChange: (e) => this.quantizeChanged(e) })),\n            (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", { style: \"padding-top: 4px; padding-bottom: 4px;\" },\n                (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"label\", null, \"Clip Length (bars)\"),\n                (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(_shared_ui_TextInput__WEBPACK_IMPORTED_MODULE_2__.TextInput, { value: bars, onChange: (e) => this.lengthChanged(e) })),\n            (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", { style: \"display: flex; align-items: center\" },\n                (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"label\", null, \"Input MIDI Ch\"),\n                (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(_shared_ui_Select__WEBPACK_IMPORTED_MODULE_1__.Select, { style: \"flex-direction: row-reverse;\", options: inputChannelOptions, values: inputChannelValues, value: () => this.props.pianoRoll.midiConfig.inputMidiChannel, onChange: (e) => this.inputMidiChanged(e) })),\n            (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", { style: \"display: flex; align-items: center\" },\n                (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"label\", null, \"Output MIDI Ch\"),\n                (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(_shared_ui_Select__WEBPACK_IMPORTED_MODULE_1__.Select, { style: \"flex-direction: row-reverse;\", options: outputChannelOptions, values: outputChannelValues, value: () => this.props.pianoRoll.midiConfig.outputMidiChannel, onChange: (e) => this.outputMidiChanged(e) }))));\n    }\n}\n\n\n//# sourceURL=webpack://pianoroll/./src/ClipSettingsView.tsx?");

/***/ }),

/***/ "./src/NoteCanvasRenderer.tsx":
/*!************************************!*\
  !*** ./src/NoteCanvasRenderer.tsx ***!
  \************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   Design: () => (/* binding */ Design),\n/* harmony export */   NoteCanvasRenderer: () => (/* binding */ NoteCanvasRenderer)\n/* harmony export */ });\nconst logger = (...any) => { };\nconst ratio = window.devicePixelRatio || 1;\nclass Design {\n}\nDesign.cellHeight = 20;\nDesign.gutterWidth = 80;\nDesign.headerHeight = 40;\nDesign.cellWidth = 20;\nclass NoteCanvasRenderer {\n    constructor(doc) {\n        this.doc = doc;\n        this.cellWidth = 0;\n    }\n    calculateFacts(state) {\n        let visibleTicks = state.clip.state.length * state.horizontalZoom;\n        let tickWidth = (state.width - Design.gutterWidth) / visibleTicks;\n        return {\n            visibleTicks,\n            tickWidth,\n            visibleCells: visibleTicks / state.clip.quantize,\n            cellWidth: tickWidth * state.clip.quantize,\n            firstNoteRenderHeight: 0,\n        };\n    }\n    dimensionsChanged(newState) {\n        return !this.oldState || this.oldState.width != newState.width || this.oldState.height != newState.height;\n    }\n    visibleNotesChanged(newState) {\n        if (!this.oldState) {\n            return true;\n        }\n        if (newState.visibleNotes.length != this.oldState.visibleNotes.length) {\n            return true;\n        }\n        return newState.visibleNotes.some((element, i) => !sameNote(element, this.oldState.visibleNotes[i]));\n    }\n    render(state) {\n        const dimensionsChanged = this.dimensionsChanged(state);\n        const horizontalChanged = !this.oldState || this.oldState.horizontalZoom != state.horizontalZoom || this.oldState.position != state.position;\n        const visibleNotesChanged = this.visibleNotesChanged(state);\n        const mustRender = !this.canvas || dimensionsChanged || visibleNotesChanged || horizontalChanged || state.clip.needsRender() || state.layingNewNote;\n        if (!this.canvas) {\n            this.canvas = this.doc.createElement(\"canvas\");\n        }\n        if (!this.playhead) {\n            this.playhead = this.doc.createElement(\"canvas\");\n        }\n        const canvas = this.canvas;\n        const playhead = this.playhead;\n        if (dimensionsChanged) {\n            canvas.style.height = `${state.height}px`;\n            canvas.style.width = `${state.width}px`;\n            canvas.width = state.width * ratio;\n            canvas.height = state.height * ratio;\n            playhead.height = state.height;\n            playhead.width = 1;\n            this.renderPlayhead(state);\n        }\n        let facts = this.calculateFacts(state);\n        this.facts = facts;\n        let ctx = this.canvas.getContext(\"2d\");\n        if (mustRender) {\n            this.renderBackground(state);\n            let firstLine = Math.floor((state.position - (state.position % state.clip.quantize)));\n            for (var pos = firstLine; pos < state.position + facts.visibleTicks; pos += state.clip.quantize) {\n                if (pos >= state.position) {\n                    let x = Design.gutterWidth + ((pos - state.position) * facts.tickWidth);\n                    let style = (pos % 24 == 0) ? \"black\" : \"grey\";\n                    let lineWidth = 1;\n                    if (pos % 24 == 0) {\n                        lineWidth = 2;\n                    }\n                    if (pos % (24 * state.transportData.timeSigNumerator) == 0) {\n                        lineWidth = 3;\n                    }\n                    line(ctx, x, 0, x, state.height, lineWidth, style);\n                }\n            }\n            var firstNoteHeight = state.height;\n            state.clip.state.notes.forEach((note) => {\n                if (note.tick + note.duration < state.position || note.tick >= state.position + facts.visibleTicks) {\n                    return;\n                }\n                let index = state.visibleNotes.findIndex(n => n.number == note.number);\n                var x = Design.gutterWidth + ((note.tick - state.position) * facts.tickWidth);\n                var y = state.height - Design.cellHeight * (index + 1);\n                var width = facts.tickWidth * note.duration;\n                var height = Design.cellHeight;\n                if (y < firstNoteHeight) {\n                    firstNoteHeight = y;\n                }\n                if (x < Design.gutterWidth) {\n                    width = width - (Design.gutterWidth - x);\n                    x = Design.gutterWidth;\n                }\n                rect(ctx, x, y, width, height, \"red\");\n            });\n            facts.firstNoteRenderHeight = firstNoteHeight;\n        }\n        if (state.layingNewNote) {\n            let note = state.layingNewNote;\n            var x = Design.gutterWidth + ((note.tick - state.position) * facts.tickWidth);\n            var width = facts.tickWidth * note.duration;\n            var height = Design.cellHeight;\n            let index = state.visibleNotes.findIndex(n => n.number == note.number);\n            var y = state.height - Design.cellHeight * (index + 1);\n            rect(ctx, x, y, width, height, \"red\");\n        }\n        this.oldState = state;\n        return canvas;\n    }\n    renderPlayhead(state) {\n        let ctx = this.playhead.getContext(\"2d\");\n        rect(ctx, 0, 0, 2, state.height, \"red\");\n    }\n    renderBackground(state) {\n        let ctx = this.canvas.getContext(\"2d\");\n        state.visibleNotes.forEach((note, i) => {\n            let mainColor = note.blackKey ? \"#bbbbbb\" : \"white\";\n            ctx.strokeStyle = \"black\";\n            ctx.lineWidth = 1;\n            const y = state.height - Design.cellHeight * (i + 1);\n            rect(ctx, 0, y, state.width, Design.cellHeight, mainColor);\n            line(ctx, 0, y, state.width, y, 1, \"gray\");\n            let gutterColor = note.blackKey ? \"black\" : \"white\";\n            rect(ctx, 0, state.height - Design.cellHeight * (i + 1), Design.gutterWidth, Design.cellHeight, gutterColor);\n            if (note.name) {\n                fillText(ctx, note.name.substring(0, 9), 5, state.height - Design.cellHeight * (i) - 4, 14, note.blackKey ? \"#fff\" : \"#000\");\n            }\n        });\n    }\n}\nfunction rect(ctx, x, y, w, h, fillStyle) {\n    ctx.fillStyle = fillStyle;\n    ctx.fillRect(x * ratio, y * ratio, w * ratio, h * ratio);\n}\nfunction fillText(ctx, text, x, y, size, style) {\n    ctx.font = `${size * ratio}px sans-serif`;\n    ctx.strokeStyle = \"\";\n    ctx.fillStyle = style;\n    ctx.fillText(text, x * ratio, y * ratio);\n}\nfunction line(ctx, x1, y1, x2, y2, width, style) {\n    ctx.lineWidth = width;\n    ctx.strokeStyle = style;\n    ctx.beginPath();\n    ctx.moveTo(x1 * ratio, y1 * ratio);\n    ctx.lineTo(x2 * ratio, y2 * ratio);\n    ctx.stroke();\n}\nfunction sameNote(n1, n2) {\n    return n1.blackKey == n2.blackKey && n1.name == n2.name && n1.number == n2.number;\n}\n\n\n//# sourceURL=webpack://pianoroll/./src/NoteCanvasRenderer.tsx?");

/***/ }),

/***/ "./src/PianoRoll.tsx":
/*!***************************!*\
  !*** ./src/PianoRoll.tsx ***!
  \***************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   PianoRoll: () => (/* binding */ PianoRoll)\n/* harmony export */ });\n/* harmony import */ var _Clip__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Clip */ \"./src/Clip.ts\");\n\nclass PianoRoll {\n    constructor(instanceId) {\n        this.instanceId = instanceId;\n        this.futureEvents = [];\n        this.dirty = false;\n        this.clips = { \"default\": new _Clip__WEBPACK_IMPORTED_MODULE_0__.Clip(\"default\") };\n        this.playingClip = \"default\";\n        this.midiConfig = {\n            pluginRecordingArmed: false,\n            hostRecordingArmed: false,\n            inputMidiChannel: -1,\n            outputMidiChannel: 0\n        };\n        this.registerNoteListHandler();\n        Object.keys(this.clips).forEach(id => this.clips[id].updateProcessor = (c) => {\n            if (this.updateProcessor)\n                this.updateProcessor(c);\n        });\n    }\n    getClip(id) {\n        return this.clips[id];\n    }\n    addClip(id) {\n        let clip = this.getClip(id);\n        if (!clip) {\n            let clip = new _Clip__WEBPACK_IMPORTED_MODULE_0__.Clip(id);\n            clip.updateProcessor = (c) => {\n                if (this.updateProcessor)\n                    this.updateProcessor(c);\n            };\n            this.clips[id] = clip;\n        }\n    }\n    registerNoteListHandler() {\n        if (window.WAMExtensions && window.WAMExtensions.notes) {\n            window.WAMExtensions.notes.addListener(this.instanceId, (notes) => {\n                this.noteList = notes;\n                if (this.renderCallback) {\n                    this.renderCallback();\n                }\n            });\n        }\n    }\n    deregisterNoteListHandler() {\n        if (window.WAMExtensions && window.WAMExtensions.notes) {\n            window.WAMExtensions.notes.addListener(this.instanceId, undefined);\n        }\n    }\n    getState() {\n        var state = {\n            clips: {}\n        };\n        for (let id of Object.keys(this.clips)) {\n            state.clips[id] = this.clips[id].getState();\n        }\n        return state;\n    }\n    async setState(state) {\n        if (!state) {\n            return;\n        }\n        const oldClips = this.clips;\n        this.clips = {};\n        if (!state.clips) {\n            state.clips = {};\n        }\n        for (let id of Object.keys(state.clips)) {\n            this.clips[id] = new _Clip__WEBPACK_IMPORTED_MODULE_0__.Clip(id, state.clips[id]);\n            if (oldClips[id]) {\n                this.clips[id].quantize = oldClips[id].quantize;\n            }\n        }\n        console.log(\"PianoRoll setState: loading clips \", state.clips);\n        for (let id of Object.keys(this.clips)) {\n            this.clips[id].updateProcessor = (c) => {\n                if (this.updateProcessor)\n                    this.updateProcessor(c);\n            };\n            if (this.updateProcessor)\n                this.updateProcessor(this.clips[id]);\n        }\n        this.dirty = true;\n        if (this.renderCallback != undefined) {\n            this.renderCallback();\n        }\n    }\n    clearRenderFlag() {\n        this.dirty = false;\n    }\n    needsRender() {\n        return this.dirty;\n    }\n    armHostRecording(armed) {\n        this.midiConfig.hostRecordingArmed = armed;\n        if (this.updateProcessorMIDIConfig) {\n            this.updateProcessorMIDIConfig(this.midiConfig);\n        }\n    }\n    armPluginRecording(armed) {\n        this.midiConfig.pluginRecordingArmed = armed;\n        if (this.updateProcessorMIDIConfig) {\n            this.updateProcessorMIDIConfig(this.midiConfig);\n        }\n    }\n    inputMidiChanged(v) {\n        if (v < -1 || v > 15) {\n            throw `Invalid input midi value: ${v}`;\n        }\n        this.midiConfig.inputMidiChannel = v;\n        if (this.updateProcessorMIDIConfig) {\n            this.updateProcessorMIDIConfig(this.midiConfig);\n        }\n    }\n    outputMidiChanged(v) {\n        if (v < 0 || v > 15) {\n            throw `Invalid output midi value: ${v}`;\n        }\n        this.midiConfig.outputMidiChannel = v;\n        if (this.updateProcessorMIDIConfig) {\n            this.updateProcessorMIDIConfig(this.midiConfig);\n        }\n    }\n}\n\n\n//# sourceURL=webpack://pianoroll/./src/PianoRoll.tsx?");

/***/ }),

/***/ "./src/PianoRollView.tsx":
/*!*******************************!*\
  !*** ./src/PianoRollView.tsx ***!
  \*******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   PianoRollView: () => (/* binding */ PianoRollView)\n/* harmony export */ });\n/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! preact */ \"./node_modules/preact/dist/preact.module.js\");\n/* harmony import */ var _shared_ui_svg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../shared/ui/svg */ \"../shared/ui/svg.ts\");\n/* harmony import */ var _ClipSettingsView__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ClipSettingsView */ \"./src/ClipSettingsView.tsx\");\n/* harmony import */ var _Clip__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Clip */ \"./src/Clip.ts\");\n/* harmony import */ var _NoteCanvasRenderer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./NoteCanvasRenderer */ \"./src/NoteCanvasRenderer.tsx\");\n/* harmony import */ var _PianoRollView_scss__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./PianoRollView.scss */ \"./src/PianoRollView.scss\");\n\n\n\n\n\nconst logger = (...any) => { };\n\nlet styles = _PianoRollView_scss__WEBPACK_IMPORTED_MODULE_5__[\"default\"].locals;\nfunction positionFromEvent(e) {\n    var x = e.offsetX;\n    var y = e.offsetY;\n    if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {\n        x = e.layerX;\n        y = e.layerY;\n    }\n    return { x, y };\n}\nclass PianoRollView extends preact__WEBPACK_IMPORTED_MODULE_0__.Component {\n    constructor() {\n        super();\n        this.state = {\n            showSettingsModal: false,\n        };\n        this.initializeDefaultNotes();\n        this.zoom = 1.0;\n        this.position = 0;\n        this.totalHeight = 0;\n        this.totalWidth = 0;\n        this.scrubberMouseDown = this.scrubberMouseDown.bind(this);\n        this.scrubberMouseMove = this.scrubberMouseMove.bind(this);\n        this.scrubberMouseUp = this.scrubberMouseUp.bind(this);\n        this.gridMouseDown = this.gridMouseDown.bind(this);\n        this.gridMouseMove = this.gridMouseMove.bind(this);\n        this.gridMouseUp = this.gridMouseUp.bind(this);\n        this.scrubberPressed = false;\n        this.notes = [];\n        this.animate = this.animate.bind(this);\n        this.canvasRenderer = new _NoteCanvasRenderer__WEBPACK_IMPORTED_MODULE_4__.NoteCanvasRenderer(document);\n        this.firstRender = true;\n    }\n    componentDidMount() {\n        this.props.pianoRoll.renderCallback = () => {\n            this.forceUpdate();\n        };\n        this.animationHandler = window.requestAnimationFrame(this.animate);\n    }\n    componentWillUnmount() {\n        window.cancelAnimationFrame(this.animationHandler);\n        this.ref = undefined;\n        this.header = undefined;\n        window.removeEventListener('mousemove', this.scrubberMouseMove);\n        window.removeEventListener('mouseup', this.scrubberMouseUp);\n        window.removeEventListener(\"mousemove\", this.gridMouseMove);\n        window.removeEventListener(\"mouseup\", this.gridMouseUp);\n        if (this.resizeObserver) {\n            this.resizeObserver.disconnect();\n            this.resizeObserver = undefined;\n        }\n        this.props.pianoRoll.renderCallback = undefined;\n    }\n    addNote(tick, number, duration) {\n        let clip = this.props.pianoRoll.getClip(this.props.clipId);\n        let existingNotes = clip.notesInTickRange(tick, tick + duration, number);\n        existingNotes.forEach((n) => {\n            clip.removeNote(n.tick, n.number);\n        });\n        clip.addNote(tick, number, duration, 100);\n    }\n    gridMouseDown(e) {\n        let eventPosition = positionFromEvent(e);\n        let x = eventPosition.x;\n        let y = eventPosition.y;\n        let clip = this.props.pianoRoll.getClip(this.props.clipId);\n        var tick = this.position + ((x - _NoteCanvasRenderer__WEBPACK_IMPORTED_MODULE_4__.Design.gutterWidth) / this.canvasRenderer.facts.tickWidth);\n        tick = tick - (tick % clip.quantize);\n        let index = Math.floor((this.totalHeight - y) / _NoteCanvasRenderer__WEBPACK_IMPORTED_MODULE_4__.Design.cellHeight);\n        if (index >= this.notes.length) {\n            return;\n        }\n        let number = this.notes[index].number;\n        let duration = clip.quantize;\n        if (clip.hasNote(tick, number)) {\n            clip.removeNote(tick, number);\n            this.forceUpdate();\n        }\n        else {\n            window.addEventListener(\"mousemove\", this.gridMouseMove);\n            window.addEventListener(\"mouseup\", this.gridMouseUp);\n            this.setState({ layingNewNote: { tick, number, duration, velocity: 100 } });\n        }\n    }\n    gridMouseMove(e) {\n        let eventPosition = positionFromEvent(e);\n        let x = eventPosition.x;\n        let y = eventPosition.y;\n        let clip = this.props.pianoRoll.getClip(this.props.clipId);\n        let tick = Math.floor(this.position) + (Math.floor((x - _NoteCanvasRenderer__WEBPACK_IMPORTED_MODULE_4__.Design.gutterWidth) / this.canvasRenderer.facts.cellWidth) * clip.quantize);\n        if (tick > this.state.layingNewNote.tick) {\n            this.setState({ layingNewNote: {\n                    tick: this.state.layingNewNote.tick,\n                    number: this.state.layingNewNote.number,\n                    duration: tick - this.state.layingNewNote.tick + clip.quantize,\n                    velocity: 100\n                } });\n        }\n    }\n    gridMouseUp(e) {\n        let note = this.state.layingNewNote;\n        this.addNote(note.tick, note.number, note.duration);\n        this.setState({ layingNewNote: undefined });\n        window.removeEventListener('mousemove', this.gridMouseMove);\n        window.removeEventListener('mouseup', this.gridMouseUp);\n    }\n    async animate() {\n        var transport = this.props.plugin.transport;\n        let playhead = this.canvasRenderer.playhead;\n        if (transport && playhead) {\n            let x = -1000;\n            if (transport.playing) {\n                let clip = this.props.pianoRoll.getClip(this.props.clipId);\n                let timeElapsed = this.props.plugin.audioContext.currentTime - transport.currentBarStarted;\n                let beatPosition = (transport.currentBar * transport.timeSigNumerator) + ((transport.tempo / 60.0) * timeElapsed);\n                let tickPosition = Math.floor(beatPosition * _Clip__WEBPACK_IMPORTED_MODULE_3__.PPQN);\n                let clipPosition = tickPosition % clip.state.length;\n                if (clipPosition >= 0 && this.props.clipId == this.props.pianoRoll.playingClip) {\n                    if (clipPosition >= this.position && clipPosition < this.position + this.canvasRenderer.facts.visibleTicks) {\n                        x = _NoteCanvasRenderer__WEBPACK_IMPORTED_MODULE_4__.Design.gutterWidth + ((clipPosition - this.position) * this.canvasRenderer.facts.tickWidth);\n                    }\n                }\n            }\n            playhead.setAttribute(\"style\", `left: ${x}px`);\n        }\n        this.animationHandler = window.requestAnimationFrame(this.animate);\n    }\n    setup(ref) {\n        var _a;\n        logger(\"entering setup\");\n        let clip = this.props.pianoRoll.getClip(this.props.clipId);\n        if (ref == null || !clip) {\n            logger(\"Skipping rendering, ref=%o clipId=%o clip=%o\", ref, this.props.clipId, this.props.pianoRoll.getClip(this.props.clipId));\n            return;\n        }\n        if (this.props.pianoRoll.noteList) {\n            logger(`Have custom noteList length ${this.notes}`);\n            this.notes = this.props.pianoRoll.noteList;\n        }\n        else {\n            logger(`Using default noteList length ${this.defaultNotes.length}`);\n            this.notes = this.defaultNotes;\n        }\n        this.totalHeight = _NoteCanvasRenderer__WEBPACK_IMPORTED_MODULE_4__.Design.cellHeight * this.notes.length;\n        if (this.totalWidth == 0) {\n            logger(`totalWidth 0, starting at ${window.innerWidth * 0.9}`);\n            this.totalWidth = window.innerWidth * 0.9;\n        }\n        this.clipLength = clip.state.length;\n        let rendererState = {\n            width: this.totalWidth,\n            height: this.totalHeight,\n            position: this.position,\n            horizontalZoom: this.zoom,\n            clip: clip,\n            visibleNotes: this.notes,\n            layingNewNote: this.state.layingNewNote,\n            transportData: (_a = this.props.plugin.transport) !== null && _a !== void 0 ? _a : defaultTransport\n        };\n        let canvas = this.canvasRenderer.render(rendererState);\n        clip.setRenderFlag(false);\n        let header = this.renderHeader();\n        if (this.ref != ref) {\n            ref.innerHTML = \"\";\n            let body = document.createElement(\"div\");\n            body.setAttribute(\"class\", styles.pianorollBody);\n            this.body = body;\n            body.appendChild(canvas);\n            body.appendChild(this.canvasRenderer.playhead);\n            this.canvasRenderer.playhead.setAttribute(\"class\", styles.playhead);\n            ref.appendChild(header);\n            ref.appendChild(body);\n            if (this.resizeObserver) {\n                this.resizeObserver.disconnect();\n                this.resizeObserver = undefined;\n            }\n            this.resizeObserver = new ResizeObserver((entries) => {\n                logger(\"resize! totalWidth=%o entries %o\", this.totalWidth, entries);\n                if (this.totalWidth != entries[0].contentRect.width) {\n                    let delta = Math.abs(this.totalWidth - entries[0].contentRect.width);\n                    logger(`totalWidth=${this.totalWidth} contentRect=${entries[0].contentRect.width} delta=${delta}`);\n                    this.totalWidth = entries[0].contentRect.width;\n                    this.forceUpdate();\n                }\n            });\n            this.resizeObserver.observe(ref);\n            canvas.addEventListener('mousedown', this.gridMouseDown);\n            this.ref = ref;\n        }\n        else if (this.header) {\n            this.ref.replaceChild(header, this.header);\n        }\n        this.header = header;\n        if (this.firstRender) {\n            window.setTimeout(() => {\n                if (clip.state.notes.length > 0) {\n                    let firstNoteHeight = this.canvasRenderer.facts.firstNoteRenderHeight;\n                    var pos = (firstNoteHeight > 40) ? firstNoteHeight - 40 : firstNoteHeight;\n                    this.body.scrollTop = pos;\n                }\n                else {\n                    this.body.scrollTop = this.totalHeight / 2;\n                }\n            }, 10);\n            this.firstRender = false;\n            this.forceUpdate();\n        }\n    }\n    render() {\n        (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", {});\n        logger(\"entering render\");\n        var settingsPanel = null;\n        if (this.state.showSettingsModal) {\n            settingsPanel = (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(_ClipSettingsView__WEBPACK_IMPORTED_MODULE_2__.ClipSettingsView, { pianoRoll: this.props.pianoRoll, clip: this.props.pianoRoll.getClip(this.props.clipId), onChange: () => this.clipSettingsChanged() });\n        }\n        let settingsLabel = this.state.showSettingsModal ? \"Settings ▾\" : \"Settings ▸\";\n        let recordingLabel = this.props.pianoRoll.midiConfig.pluginRecordingArmed ? \"Rec armed 🔴\" : \"Press to record ⚫️\";\n        return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", { style: \"display: flex; flex-direction: column; height: 100%\" },\n            (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", { style: \"height: 40px; background-color: darkgray; display: flex; flex-direction: row; justify-content: space-between;\" },\n                (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", null,\n                    (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"button\", { class: styles.menuButton, onClick: () => this.recordingPressed() }, recordingLabel),\n                    (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"button\", { class: styles.menuButton, onClick: () => this.clearButtonPressed() }, \"Clear Pattern\")),\n                (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", { class: styles.anchor, style: \"text-align: right;\" },\n                    (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"button\", { class: `${styles.menuButton}`, onClick: () => this.settingsButtonPressed() }, settingsLabel),\n                    settingsPanel)),\n            (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", { ref: (ref) => this.setup(ref), class: styles.pianorollContainer })));\n    }\n    initializeDefaultNotes() {\n        this.defaultNotes = [];\n        for (var i = 0; i < 128; i++) {\n            let octave = Math.floor(i / 12) - 1;\n            let note = i % 12;\n            let name = (note == 0) ? `C${octave}` : undefined;\n            let blackKey = (note == 1 || note == 3 || note == 6 || note == 8 || note == 10);\n            this.defaultNotes.push({ number: i, name: name, blackKey: blackKey });\n        }\n    }\n    clearButtonPressed() {\n        const clip = this.props.pianoRoll.getClip(this.props.clipId);\n        let state = clip.getState();\n        state.notes = [];\n        clip.setState(state);\n        this.forceUpdate();\n    }\n    renderHeader() {\n        let container = document.createElement(\"div\");\n        container.setAttribute(\"style\", `height: ${_NoteCanvasRenderer__WEBPACK_IMPORTED_MODULE_4__.Design.headerHeight}px; display: flex; background-color: rgba(255, 255, 255, 0.4)`);\n        let span = document.createElement(\"div\");\n        span.setAttribute(\"style\", `width: ${_NoteCanvasRenderer__WEBPACK_IMPORTED_MODULE_4__.Design.gutterWidth}px; display: flex; margin: auto; `);\n        container.appendChild(span);\n        let scrubberLength = this.totalWidth - _NoteCanvasRenderer__WEBPACK_IMPORTED_MODULE_4__.Design.gutterWidth;\n        let clipHeader = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n        clipHeader.setAttribute(\"style\", `height: ${_NoteCanvasRenderer__WEBPACK_IMPORTED_MODULE_4__.Design.headerHeight}px; width: ${scrubberLength}px; background-color: rgba(255, 255, 255, 0.4)`);\n        container.appendChild(clipHeader);\n        let positionPercent = this.position / this.clipLength;\n        this.scrubber = (0,_shared_ui_svg__WEBPACK_IMPORTED_MODULE_1__.svg_rectangle)(scrubberLength * positionPercent, 0, scrubberLength * this.zoom, _NoteCanvasRenderer__WEBPACK_IMPORTED_MODULE_4__.Design.headerHeight, \"red\");\n        this.scrubber.addEventListener(\"mousedown\", this.scrubberMouseDown);\n        clipHeader.appendChild(this.scrubber);\n        return container;\n    }\n    settingsButtonPressed() {\n        this.setState({\n            showSettingsModal: !this.state.showSettingsModal\n        });\n    }\n    recordingPressed() {\n        this.props.pianoRoll.armPluginRecording(!this.props.pianoRoll.midiConfig.pluginRecordingArmed);\n        this.forceUpdate();\n    }\n    scrubberMouseDown(e) {\n        this.scrubberPressed = true;\n        this.scrubberMousePosition = { x: e.screenX, y: e.screenY };\n        window.addEventListener('mousemove', this.scrubberMouseMove);\n        window.addEventListener('mouseup', this.scrubberMouseUp);\n    }\n    scrubberMouseUp(e) {\n        this.scrubberPressed = false;\n        window.removeEventListener('mousemove', this.scrubberMouseMove);\n        window.removeEventListener('mouseup', this.scrubberMouseUp);\n    }\n    scrubberMouseMove(e) {\n        if (this.scrubberPressed) {\n            let distance = { x: e.screenX - this.scrubberMousePosition.x, y: e.screenY - this.scrubberMousePosition.y };\n            this.scrubberMousePosition = { x: e.screenX, y: e.screenY };\n            var zoom = this.zoom - (distance.y * 0.002);\n            if (zoom < 0.01) {\n                zoom = 0.01;\n            }\n            else if (zoom > 1.0) {\n                zoom = 1.0;\n            }\n            this.zoom = zoom;\n            var position = this.position + (distance.x / (this.totalWidth - _NoteCanvasRenderer__WEBPACK_IMPORTED_MODULE_4__.Design.gutterWidth) * this.clipLength);\n            if (position < 0) {\n                position = 0;\n            }\n            if (position + (this.zoom * this.clipLength) > this.clipLength) {\n                position = this.clipLength - (this.zoom * this.clipLength);\n            }\n            this.position = position;\n            this.forceUpdate();\n        }\n    }\n    clipSettingsChanged() {\n        this.forceUpdate();\n    }\n}\nconst defaultTransport = {\n    currentBar: 0,\n    currentBarStarted: 0,\n    tempo: 120,\n    timeSigNumerator: 4,\n    timeSigDenominator: 4,\n    playing: false,\n};\n\n\n//# sourceURL=webpack://pianoroll/./src/PianoRollView.tsx?");

/***/ }),

/***/ "./src/index.tsx":
/*!***********************!*\
  !*** ./src/index.tsx ***!
  \***********************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ PianoRollModule)\n/* harmony export */ });\n/* harmony import */ var _webaudiomodules_sdk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @webaudiomodules/sdk */ \"../../../node_modules/@webaudiomodules/sdk/dist/index.js\");\n/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! preact */ \"./node_modules/preact/dist/preact.module.js\");\n/* harmony import */ var _PianoRollView__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./PianoRollView */ \"./src/PianoRollView.tsx\");\n/* harmony import */ var _shared_getBaseUrl__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../shared/getBaseUrl */ \"../shared/getBaseUrl.tsx\");\n/* harmony import */ var _Clip__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Clip */ \"./src/Clip.ts\");\n/* harmony import */ var _PianoRoll__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./PianoRoll */ \"./src/PianoRoll.tsx\");\n/* harmony import */ var _PianoRollView_scss__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./PianoRollView.scss */ \"./src/PianoRollView.scss\");\n/* harmony import */ var _shared_insertStyle__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../shared/insertStyle */ \"../shared/insertStyle.ts\");\n\n\n\n\n\n\n\n\nconst logger = console.log;\nclass PianoRollNode extends _webaudiomodules_sdk__WEBPACK_IMPORTED_MODULE_0__.WamNode {\n    constructor(module, options) {\n        super(module, { ...options, processorOptions: {\n                numberOfInputs: 1,\n                numberOfOutputs: 1,\n                outputChannelCount: [2],\n            } });\n        this.destroyed = false;\n        this.pianoRoll = new _PianoRoll__WEBPACK_IMPORTED_MODULE_5__.PianoRoll(module.instanceId);\n        this._supportedEventTypes = new Set(['wam-automation', 'wam-midi', 'wam-transport']);\n    }\n    async getState() {\n        return this.pianoRoll.getState();\n    }\n    async setState(state) {\n        this.pianoRoll.setState(state);\n    }\n}\nclass PianoRollModule extends _webaudiomodules_sdk__WEBPACK_IMPORTED_MODULE_0__.WebAudioModule {\n    constructor() {\n        super(...arguments);\n        this._baseURL = (0,_shared_getBaseUrl__WEBPACK_IMPORTED_MODULE_3__.getBaseUrl)(new URL('.', __webpack_require__.p));\n        this._descriptorUrl = `${this._baseURL}/descriptor.json`;\n        this._pianoRollProcessorUrl = `${this._baseURL}/PianoRollProcessor.js`;\n    }\n    async _loadDescriptor() {\n        const url = this._descriptorUrl;\n        if (!url)\n            throw new TypeError('Descriptor not found');\n        const response = await fetch(url);\n        const descriptor = await response.json();\n        Object.assign(this._descriptor, descriptor);\n        return descriptor;\n    }\n    async initialize(state) {\n        await this._loadDescriptor();\n        return super.initialize(state);\n    }\n    async createAudioNode(initialState) {\n        await PianoRollNode.addModules(this.audioContext, this.moduleId);\n        await this.audioContext.audioWorklet.addModule(this._pianoRollProcessorUrl);\n        const node = new PianoRollNode(this, {});\n        await node._initialize();\n        node.setState(initialState);\n        this.sequencer = node;\n        this.sequencer.pianoRoll.updateProcessor = (c) => {\n            this.sequencer.port.postMessage({ action: \"clip\", id: c.state.id, state: c.getState() });\n        };\n        this.sequencer.pianoRoll.updateProcessorMIDIConfig = (config) => {\n            this.sequencer.port.postMessage({ action: \"midiConfig\", config });\n        };\n        this.sequencer.port.addEventListener(\"message\", ev => {\n            if (ev.data.event == \"transport\") {\n                this.transport = ev.data.transport;\n            }\n            else if (ev.data.event == \"addNote\") {\n                const clip = this.sequencer.pianoRoll.getClip(this.sequencer.pianoRoll.playingClip);\n                const note = ev.data.note;\n                const quantizedTick = Math.round(note.tick / clip.quantize) * clip.quantize;\n                clip === null || clip === void 0 ? void 0 : clip.addNote(quantizedTick, note.number, note.duration, note.velocity);\n                if (this.sequencer.pianoRoll.renderCallback) {\n                    this.sequencer.pianoRoll.renderCallback();\n                }\n            }\n        });\n        this.updateExtensions();\n        return node;\n    }\n    async createGui(clipId) {\n        const div = document.createElement('div');\n        (0,preact__WEBPACK_IMPORTED_MODULE_1__.h)(\"div\", {});\n        div.setAttribute(\"style\", \"display: flex; flex-direction: column; height: 100%; width: 100%; max-height: 100%; max-width: 100%;\");\n        div.setAttribute(\"width\", \"1024\");\n        div.setAttribute(\"height\", \"680\");\n        var shadow = div.attachShadow({ mode: 'open' });\n        const container = document.createElement('div');\n        container.setAttribute(\"style\", \"display: flex; flex-direction: column; height: 100%; width: 100%; max-height: 100%; max-width: 100%;\");\n        shadow.appendChild(container);\n        (0,_shared_insertStyle__WEBPACK_IMPORTED_MODULE_7__.insertStyle)(shadow, _PianoRollView_scss__WEBPACK_IMPORTED_MODULE_6__[\"default\"].toString());\n        if (!clipId) {\n            clipId = \"default\";\n        }\n        else {\n            this.sequencer.pianoRoll.addClip(clipId);\n        }\n        (0,preact__WEBPACK_IMPORTED_MODULE_1__.render)((0,preact__WEBPACK_IMPORTED_MODULE_1__.h)(_PianoRollView__WEBPACK_IMPORTED_MODULE_2__.PianoRollView, { plugin: this, pianoRoll: this.sequencer.pianoRoll, clipId: clipId }), shadow);\n        return div;\n    }\n    destroyGui(el) {\n        (0,preact__WEBPACK_IMPORTED_MODULE_1__.render)(null, el);\n    }\n    updateExtensions() {\n        if (window.WAMExtensions && window.WAMExtensions.recording) {\n            window.WAMExtensions.recording.register(this.instanceId, {\n                armRecording: (armed) => {\n                    this.sequencer.pianoRoll.armHostRecording(armed);\n                }\n            });\n        }\n        else {\n            this.sequencer.pianoRoll.armHostRecording(true);\n        }\n        if (!(window.WAMExtensions && window.WAMExtensions.patterns)) {\n            return;\n        }\n        let patternDelegate = {\n            getPatternList: () => {\n                return Object.keys(this.sequencer.pianoRoll.clips).map(id => {\n                    return { id: id, name: \"pattern\" };\n                });\n            },\n            createPattern: (id) => {\n                logger(\"createPattern(%s)\", id);\n                this.sequencer.pianoRoll.addClip(id);\n            },\n            deletePattern: (id) => {\n                logger(\"deletePattern(%s)\", id);\n                delete this.sequencer.pianoRoll.clips[id];\n            },\n            playPattern: (id) => {\n                logger(\"playPattern(%s)\", id);\n                let clip = this.sequencer.pianoRoll.getClip(id);\n                if (!clip && id != undefined) {\n                    console.log(\"PianoRoll index: adding clip \", id);\n                    this.sequencer.pianoRoll.addClip(id);\n                }\n                this.sequencer.pianoRoll.playingClip = id;\n                this.sequencer.port.postMessage({ action: \"play\", id });\n            },\n            getPatternState: (id) => {\n                logger(\"getPatternState(%s)\", id);\n                let clip = this.sequencer.pianoRoll.getClip(id);\n                if (clip) {\n                    return clip.getState(true);\n                }\n                else {\n                    return undefined;\n                }\n            },\n            setPatternState: (id, state) => {\n                logger(\"setPatternState(%s, %o)\", id, state);\n                let clip = this.sequencer.pianoRoll.getClip(id);\n                if (clip) {\n                    clip.setState(state, id);\n                }\n                else {\n                    let clip = new _Clip__WEBPACK_IMPORTED_MODULE_4__.Clip(id, state);\n                    this.sequencer.pianoRoll.clips[id] = clip;\n                }\n                if (this.sequencer.pianoRoll.renderCallback) {\n                    this.sequencer.pianoRoll.renderCallback();\n                }\n            }\n        };\n        window.WAMExtensions.patterns.setPatternDelegate(this.instanceId, patternDelegate);\n    }\n}\n\n\n//# sourceURL=webpack://pianoroll/./src/index.tsx?");

/***/ }),

/***/ "../shared/getBaseUrl.tsx":
/*!********************************!*\
  !*** ../shared/getBaseUrl.tsx ***!
  \********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   getBaseUrl: () => (/* binding */ getBaseUrl)\n/* harmony export */ });\nconst getBaseUrl = (relativeURL) => {\n    const baseURL = relativeURL.href.substring(0, relativeURL.href.lastIndexOf('/'));\n    return baseURL;\n};\n\n\n//# sourceURL=webpack://pianoroll/../shared/getBaseUrl.tsx?");

/***/ }),

/***/ "../shared/insertStyle.ts":
/*!********************************!*\
  !*** ../shared/insertStyle.ts ***!
  \********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   insertStyle: () => (/* binding */ insertStyle)\n/* harmony export */ });\nfunction insertStyle(shadow, style) {\n    const el = document.createElement('style');\n    el.textContent = style;\n    shadow.appendChild(el);\n}\n\n\n//# sourceURL=webpack://pianoroll/../shared/insertStyle.ts?");

/***/ }),

/***/ "../shared/ui/Select.tsx":
/*!*******************************!*\
  !*** ../shared/ui/Select.tsx ***!
  \*******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   Select: () => (/* binding */ Select)\n/* harmony export */ });\n/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! preact */ \"../../../node_modules/preact/dist/preact.module.js\");\n\nclass Select extends preact__WEBPACK_IMPORTED_MODULE_0__.Component {\n    constructor() {\n        super();\n        this.lastRenderedValue = \"-1\";\n        this.animationFrame = this.animationFrame.bind(this);\n        this.scheduleFrame = this.scheduleFrame.bind(this);\n        this.scheduleAnimation = this.scheduleAnimation.bind(this);\n    }\n    onChange(e) {\n        if (this.props.onChange) {\n            this.props.onChange(e.target.value);\n        }\n    }\n    cancelAnimation() {\n        if (this.animationTimeout != undefined) {\n            window.clearTimeout(this.animationTimeout);\n            this.animationTimeout = undefined;\n        }\n        if (this.animationRequest != undefined) {\n            window.cancelAnimationFrame(this.animationRequest);\n            this.animationRequest = undefined;\n        }\n    }\n    scheduleAnimation() {\n        this.animationTimeout = window.setTimeout(this.scheduleFrame, 100);\n    }\n    scheduleFrame() {\n        this.animationRequest = window.requestAnimationFrame(this.animationFrame);\n    }\n    componentWillUnmount() {\n        this.cancelAnimation();\n    }\n    animationFrame() {\n        let newValue = this.props.value();\n        if (this.lastRenderedValue == newValue) {\n            this.scheduleAnimation();\n            return;\n        }\n        this.lastRenderedValue = newValue;\n        for (let option of this.select.options) {\n            option.selected = (option.value == newValue);\n        }\n        this.scheduleAnimation();\n    }\n    setup(ref) {\n        if (ref == null) {\n            return;\n        }\n        if (ref == this.ref && this.sameArray(this.props.options, this.renderedOptions) && this.sameArray(this.props.values, this.renderedValues)) {\n            return;\n        }\n        this.ref = ref;\n        ref.innerHTML = \"\";\n        if (this.props.value === undefined || this.props.value === null) {\n            throw `Select with label ${this.props.label} values ${this.props.values} has null value`;\n        }\n        if (!this.select) {\n            this.select = document.createElement(\"select\");\n            this.select.addEventListener(\"change\", e => this.onChange(e));\n        }\n        else {\n            while (this.select.firstChild) {\n                this.select.removeChild(this.select.firstChild);\n            }\n            try {\n                this.ref.removeChild(this.select);\n            }\n            catch (e) {\n            }\n        }\n        this.ref.appendChild(this.select);\n        this.props.options.forEach((name, index) => {\n            let option = document.createElement(\"option\");\n            option.text = name;\n            option.value = (this.props.values) ? this.props.values[index].toString() : index.toString();\n            this.select.appendChild(option);\n        });\n        this.lastRenderedValue = \"-1\";\n        this.renderedOptions = this.props.options;\n        this.renderedValues = this.props.values;\n        this.cancelAnimation();\n        this.animationFrame();\n    }\n    render() {\n        (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", {});\n        let style = this.props.style ? this.props.style : \"\";\n        return (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", { class: \"ComponentWrapper\", style: style },\n            this.props.label && (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"label\", null, this.props.label),\n            (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", { ref: (e) => this.setup(e), style: \"color: black;\", class: \"ComponentSelect\" }));\n    }\n    sameArray(lhs, rhs) {\n        if (lhs === undefined && rhs === undefined) {\n            return true;\n        }\n        if (lhs === undefined || rhs === undefined) {\n            return false;\n        }\n        return (lhs.length == rhs.length && lhs.every((l, i) => l == rhs[i]));\n    }\n}\n\n\n//# sourceURL=webpack://pianoroll/../shared/ui/Select.tsx?");

/***/ }),

/***/ "../shared/ui/TextInput.tsx":
/*!**********************************!*\
  !*** ../shared/ui/TextInput.tsx ***!
  \**********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   TextInput: () => (/* binding */ TextInput)\n/* harmony export */ });\n/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! preact */ \"../../../node_modules/preact/dist/preact.module.js\");\n\nclass TextInput extends preact__WEBPACK_IMPORTED_MODULE_0__.Component {\n    constructor() {\n        super();\n        this.lastRenderedValue = \"blank\";\n        this.onChange = this.onChange.bind(this);\n        this.onKeyUp = this.onKeyUp.bind(this);\n    }\n    onChange(e) {\n        if (this.props.onChange) {\n            this.props.onChange(e);\n        }\n    }\n    onKeyUp(e) {\n        if (e.key === \"Enter\") {\n            alert(\"Enter pressed!\");\n        }\n    }\n    setup(ref) {\n        if (!ref) {\n            return;\n        }\n        if (this.ref != ref) {\n            ref.innerHTML = \"\";\n            let input = document.createElement(\"input\");\n            ref.appendChild(input);\n            this.ref = ref;\n        }\n        let input = ref.children[0];\n        input.setAttribute(\"type\", this.props.password ? \"password\" : \"text\");\n        input.setAttribute(\"class\", (this.props.className ? this.props.className : \"\") + \" p-0.5 border border-gray-500\");\n        if (this.lastRenderedValue != this.props.value) {\n            this.lastRenderedValue = this.props.value.toString();\n            input.value = this.lastRenderedValue;\n        }\n        input.removeEventListener(\"change\", this.onChange);\n        input.addEventListener(\"change\", this.onChange);\n    }\n    render() {\n        (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", {});\n        return (0,preact__WEBPACK_IMPORTED_MODULE_0__.h)(\"div\", { ref: (e) => this.setup(e) });\n    }\n}\n\n\n//# sourceURL=webpack://pianoroll/../shared/ui/TextInput.tsx?");

/***/ }),

/***/ "../shared/ui/svg.ts":
/*!***************************!*\
  !*** ../shared/ui/svg.ts ***!
  \***************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   svg_arc: () => (/* binding */ svg_arc),\n/* harmony export */   svg_create: () => (/* binding */ svg_create),\n/* harmony export */   svg_line: () => (/* binding */ svg_line),\n/* harmony export */   svg_rectangle: () => (/* binding */ svg_rectangle),\n/* harmony export */   svg_text: () => (/* binding */ svg_text),\n/* harmony export */   svg_update_arc: () => (/* binding */ svg_update_arc),\n/* harmony export */   svg_update_line: () => (/* binding */ svg_update_line),\n/* harmony export */   svg_update_rectangle: () => (/* binding */ svg_update_rectangle)\n/* harmony export */ });\n\nconst svgns = \"http://www.w3.org/2000/svg\";\nconst cos = Math.cos;\nconst sin = Math.sin;\nconst π = Math.PI;\nconst f_matrix_times = (([[a, b], [c, d]], [x, y]) => [a * x + b * y, c * x + d * y]);\nconst f_rotate_matrix = ((x) => {\n    const cosx = cos(x);\n    const sinx = sin(x);\n    return [[cosx, -sinx], [sinx, cosx]];\n});\nconst f_vec_add = (([a1, a2], [b1, b2]) => [a1 + b1, a2 + b2]);\nfunction svg_create(type) {\n    return document.createElementNS(svgns, type);\n}\nfunction svg_arc([cx, cy], [rx, ry], [t1, Δ], φ) {\n    const path = document.createElementNS(svgns, \"path\");\n    svg_update_arc(path, [cx, cy], [rx, ry], [t1, Δ], φ);\n    return path;\n}\n;\nfunction svg_update_arc(arc, [cx, cy], [rx, ry], [t1, Δ], φ) {\n    Δ = Δ / 180 * π;\n    Δ = Δ % (2 * π);\n    t1 = t1 / 180 * π;\n    const rotMatrix = f_rotate_matrix(φ);\n    const [sX, sY] = (f_vec_add(f_matrix_times(rotMatrix, [rx * cos(t1), ry * sin(t1)]), [cx, cy]));\n    const [eX, eY] = (f_vec_add(f_matrix_times(rotMatrix, [rx * cos(t1 + Δ), ry * sin(t1 + Δ)]), [cx, cy]));\n    const fA = ((Δ > π) ? 1 : 0);\n    const fS = ((Δ > 0) ? 1 : 0);\n    let cmd = [\" M \", sX, \" \", sY, \" A \", rx, ry, φ / π * 180, fA, fS, eX, eY].join(\" \");\n    arc.setAttribute(\"d\", cmd);\n}\nfunction svg_rectangle(x, y, width, height, fill) {\n    var rect = document.createElementNS(svgns, 'rect');\n    svg_update_rectangle(rect, x, y, width, height, fill);\n    return rect;\n}\nfunction svg_update_rectangle(rect, x, y, width, height, fill) {\n    rect.setAttributeNS(null, 'x', x.toString());\n    rect.setAttributeNS(null, 'y', y.toString());\n    rect.setAttributeNS(null, 'height', height.toString());\n    rect.setAttributeNS(null, 'width', width.toString());\n    rect.setAttributeNS(null, 'fill', fill);\n}\nfunction svg_text(x, y, size, content, fill) {\n    var element = document.createElementNS(svgns, 'text');\n    element.setAttribute('x', x.toString());\n    element.setAttribute('y', y.toString());\n    element.setAttribute('fill', fill);\n    element.setAttribute('font-size', size.toString());\n    var txt = document.createTextNode(content);\n    element.appendChild(txt);\n    return element;\n}\nfunction svg_line(x1, y1, x2, y2, stroke) {\n    var line = document.createElementNS(svgns, 'line');\n    svg_update_line(line, x1, y1, x2, y2, stroke);\n    return line;\n}\nfunction svg_update_line(line, x1, y1, x2, y2, stroke) {\n    line.setAttribute('x1', x1.toString());\n    line.setAttribute('y1', y1.toString());\n    line.setAttribute('x2', x2.toString());\n    line.setAttribute('y2', y2.toString());\n    line.setAttribute(\"stroke\", stroke);\n}\n\n\n//# sourceURL=webpack://pianoroll/../shared/ui/svg.ts?");

/***/ }),

/***/ "../shared/util.ts":
/*!*************************!*\
  !*** ../shared/util.ts ***!
  \*************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   constantSource: () => (/* binding */ constantSource),\n/* harmony export */   noiseSource: () => (/* binding */ noiseSource),\n/* harmony export */   token: () => (/* binding */ token)\n/* harmony export */ });\nfunction token() {\n    return Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 16);\n}\nfunction constantSource(audioContext) {\n    if (audioContext.createConstantSource) {\n        let source = audioContext.createConstantSource();\n        source.start();\n        return source;\n    }\n    else {\n        let length = audioContext.sampleRate;\n        var buffer = audioContext.createBuffer(1, length, audioContext.sampleRate);\n        var noise = buffer.getChannelData(0);\n        for (var i = 0; i < length; i++) {\n            noise[i] = 1.0;\n        }\n        var source = audioContext.createBufferSource();\n        source.buffer = buffer;\n        source.loop = true;\n        source.loopStart = 0.0;\n        source.loopEnd = 0.9;\n        source.start();\n        return source;\n    }\n}\nfunction noiseSource(audioContext) {\n    let length = audioContext.sampleRate;\n    var buffer = audioContext.createBuffer(1, length, audioContext.sampleRate);\n    var noise = buffer.getChannelData(0);\n    for (var i = 0; i < length; i++) {\n        noise[i] = (Math.random() * 2) - 1;\n    }\n    var source = audioContext.createBufferSource();\n    source.buffer = buffer;\n    source.loop = true;\n    source.loopStart = 0.0;\n    source.loopEnd = 0.9;\n    source.start();\n    return source;\n}\n\n\n//# sourceURL=webpack://pianoroll/../shared/util.ts?");

/***/ }),

/***/ "../../../node_modules/@webaudiomodules/sdk/dist/index.js":
/*!****************************************************************!*\
  !*** ../../../node_modules/@webaudiomodules/sdk/dist/index.js ***!
  \****************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   WamNode: () => (/* binding */ WamNode),\n/* harmony export */   WebAudioModule: () => (/* binding */ WebAudioModule_default),\n/* harmony export */   addFunctionModule: () => (/* binding */ addFunctionModule_default),\n/* harmony export */   apiVersion: () => (/* binding */ apiVersion_default),\n/* harmony export */   getRingBuffer: () => (/* binding */ RingBuffer_default),\n/* harmony export */   getWamArrayRingBuffer: () => (/* binding */ WamArrayRingBuffer_default),\n/* harmony export */   getWamEventRingBuffer: () => (/* binding */ WamEventRingBuffer_default),\n/* harmony export */   getWamParameter: () => (/* binding */ WamParameter_default),\n/* harmony export */   getWamParameterInfo: () => (/* binding */ WamParameterInfo_default),\n/* harmony export */   getWamParameterInterpolator: () => (/* binding */ WamParameterInterpolator_default),\n/* harmony export */   getWamProcessor: () => (/* binding */ WamProcessor_default),\n/* harmony export */   initializeWamEnv: () => (/* binding */ WamEnv_default),\n/* harmony export */   initializeWamGroup: () => (/* binding */ WamGroup_default),\n/* harmony export */   initializeWamHost: () => (/* binding */ initializeWamHost_default)\n/* harmony export */ });\n// src/WebAudioModule.js\nvar WebAudioModule = class {\n  static get isWebAudioModuleConstructor() {\n    return true;\n  }\n  static createInstance(groupId, audioContext, initialState) {\n    return new this(groupId, audioContext).initialize(initialState);\n  }\n  constructor(groupId, audioContext) {\n    this._groupId = groupId;\n    this._audioContext = audioContext;\n    this._initialized = false;\n    this._audioNode = void 0;\n    this._timestamp = performance.now();\n    this._guiModuleUrl = void 0;\n    this._descriptorUrl = \"./descriptor.json\";\n    this._descriptor = {\n      identifier: `com.webaudiomodule.default`,\n      name: `WebAudioModule_${this.constructor.name}`,\n      vendor: \"WebAudioModuleVendor\",\n      description: \"\",\n      version: \"0.0.0\",\n      apiVersion: \"2.0.0\",\n      thumbnail: \"\",\n      keywords: [],\n      isInstrument: false,\n      website: \"\",\n      hasAudioInput: true,\n      hasAudioOutput: true,\n      hasAutomationInput: true,\n      hasAutomationOutput: true,\n      hasMidiInput: true,\n      hasMidiOutput: true,\n      hasMpeInput: true,\n      hasMpeOutput: true,\n      hasOscInput: true,\n      hasOscOutput: true,\n      hasSysexInput: true,\n      hasSysexOutput: true\n    };\n  }\n  get isWebAudioModule() {\n    return true;\n  }\n  get groupId() {\n    return this._groupId;\n  }\n  get moduleId() {\n    return this.descriptor.identifier;\n  }\n  get instanceId() {\n    return this.moduleId + this._timestamp;\n  }\n  get descriptor() {\n    return this._descriptor;\n  }\n  get identifier() {\n    return this.descriptor.identifier;\n  }\n  get name() {\n    return this.descriptor.name;\n  }\n  get vendor() {\n    return this.descriptor.vendor;\n  }\n  get audioContext() {\n    return this._audioContext;\n  }\n  get audioNode() {\n    if (!this.initialized)\n      console.warn(\"WAM should be initialized before getting the audioNode\");\n    return this._audioNode;\n  }\n  set audioNode(node) {\n    this._audioNode = node;\n  }\n  get initialized() {\n    return this._initialized;\n  }\n  set initialized(value) {\n    this._initialized = value;\n  }\n  async createAudioNode(initialState) {\n    throw new TypeError(\"createAudioNode() not provided\");\n  }\n  async initialize(state) {\n    if (!this._audioNode)\n      this.audioNode = await this.createAudioNode();\n    this.initialized = true;\n    return this;\n  }\n  async _loadGui() {\n    const url = this._guiModuleUrl;\n    if (!url)\n      throw new TypeError(\"Gui module not found\");\n    return import(\n      /* webpackIgnore: true */\n      url\n    );\n  }\n  async _loadDescriptor() {\n    const url = this._descriptorUrl;\n    if (!url)\n      throw new TypeError(\"Descriptor not found\");\n    const response = await fetch(url);\n    const descriptor = await response.json();\n    Object.assign(this._descriptor, descriptor);\n    return this._descriptor;\n  }\n  async createGui() {\n    if (!this.initialized)\n      console.warn(\"Plugin should be initialized before getting the gui\");\n    if (!this._guiModuleUrl)\n      return void 0;\n    const { createElement } = await this._loadGui();\n    return createElement(this);\n  }\n  destroyGui() {\n  }\n};\nvar WebAudioModule_default = WebAudioModule;\n\n// src/RingBuffer.js\nvar getRingBuffer = (moduleId) => {\n  const audioWorkletGlobalScope = globalThis;\n  class RingBuffer2 {\n    static getStorageForCapacity(capacity, Type) {\n      if (!Type.BYTES_PER_ELEMENT) {\n        throw new Error(\"Pass in a ArrayBuffer subclass\");\n      }\n      const bytes = 8 + (capacity + 1) * Type.BYTES_PER_ELEMENT;\n      return new SharedArrayBuffer(bytes);\n    }\n    constructor(sab, Type) {\n      if (!Type.BYTES_PER_ELEMENT) {\n        throw new Error(\"Pass a concrete typed array class as second argument\");\n      }\n      this._Type = Type;\n      this._capacity = (sab.byteLength - 8) / Type.BYTES_PER_ELEMENT;\n      this.buf = sab;\n      this.write_ptr = new Uint32Array(this.buf, 0, 1);\n      this.read_ptr = new Uint32Array(this.buf, 4, 1);\n      this.storage = new Type(this.buf, 8, this._capacity);\n    }\n    get type() {\n      return this._Type.name;\n    }\n    push(elements) {\n      const rd = Atomics.load(this.read_ptr, 0);\n      const wr = Atomics.load(this.write_ptr, 0);\n      if ((wr + 1) % this._storageCapacity() === rd) {\n        return 0;\n      }\n      const toWrite = Math.min(this._availableWrite(rd, wr), elements.length);\n      const firstPart = Math.min(this._storageCapacity() - wr, toWrite);\n      const secondPart = toWrite - firstPart;\n      this._copy(elements, 0, this.storage, wr, firstPart);\n      this._copy(elements, firstPart, this.storage, 0, secondPart);\n      Atomics.store(this.write_ptr, 0, (wr + toWrite) % this._storageCapacity());\n      return toWrite;\n    }\n    pop(elements) {\n      const rd = Atomics.load(this.read_ptr, 0);\n      const wr = Atomics.load(this.write_ptr, 0);\n      if (wr === rd) {\n        return 0;\n      }\n      const isArray = !Number.isInteger(elements);\n      const toRead = Math.min(this._availableRead(rd, wr), isArray ? elements.length : elements);\n      if (isArray) {\n        const firstPart = Math.min(this._storageCapacity() - rd, toRead);\n        const secondPart = toRead - firstPart;\n        this._copy(this.storage, rd, elements, 0, firstPart);\n        this._copy(this.storage, 0, elements, firstPart, secondPart);\n      }\n      Atomics.store(this.read_ptr, 0, (rd + toRead) % this._storageCapacity());\n      return toRead;\n    }\n    get empty() {\n      const rd = Atomics.load(this.read_ptr, 0);\n      const wr = Atomics.load(this.write_ptr, 0);\n      return wr === rd;\n    }\n    get full() {\n      const rd = Atomics.load(this.read_ptr, 0);\n      const wr = Atomics.load(this.write_ptr, 0);\n      return (wr + 1) % this._capacity !== rd;\n    }\n    get capacity() {\n      return this._capacity - 1;\n    }\n    get availableRead() {\n      const rd = Atomics.load(this.read_ptr, 0);\n      const wr = Atomics.load(this.write_ptr, 0);\n      return this._availableRead(rd, wr);\n    }\n    get availableWrite() {\n      const rd = Atomics.load(this.read_ptr, 0);\n      const wr = Atomics.load(this.write_ptr, 0);\n      return this._availableWrite(rd, wr);\n    }\n    _availableRead(rd, wr) {\n      if (wr > rd) {\n        return wr - rd;\n      }\n      return wr + this._storageCapacity() - rd;\n    }\n    _availableWrite(rd, wr) {\n      let rv = rd - wr - 1;\n      if (wr >= rd) {\n        rv += this._storageCapacity();\n      }\n      return rv;\n    }\n    _storageCapacity() {\n      return this._capacity;\n    }\n    _copy(input, offsetInput, output, offsetOutput, size) {\n      for (let i = 0; i < size; i++) {\n        output[offsetOutput + i] = input[offsetInput + i];\n      }\n    }\n  }\n  if (audioWorkletGlobalScope.AudioWorkletProcessor) {\n    const ModuleScope = audioWorkletGlobalScope.webAudioModules.getModuleScope(moduleId);\n    if (!ModuleScope.RingBuffer)\n      ModuleScope.RingBuffer = RingBuffer2;\n  }\n  return RingBuffer2;\n};\nvar RingBuffer_default = getRingBuffer;\n\n// src/WamArrayRingBuffer.js\nvar getWamArrayRingBuffer = (moduleId) => {\n  const audioWorkletGlobalScope = globalThis;\n  class WamArrayRingBuffer {\n    static DefaultArrayCapacity = 2;\n    static getStorageForEventCapacity(RingBuffer2, arrayLength, arrayType, maxArrayCapacity = void 0) {\n      if (maxArrayCapacity === void 0)\n        maxArrayCapacity = WamArrayRingBuffer.DefaultArrayCapacity;\n      else\n        maxArrayCapacity = Math.max(maxArrayCapacity, WamArrayRingBuffer.DefaultArrayCapacity);\n      if (!arrayType.BYTES_PER_ELEMENT) {\n        throw new Error(\"Pass in a ArrayBuffer subclass\");\n      }\n      const capacity = arrayLength * maxArrayCapacity;\n      return RingBuffer2.getStorageForCapacity(capacity, arrayType);\n    }\n    constructor(RingBuffer2, sab, arrayLength, arrayType, maxArrayCapacity = void 0) {\n      if (!arrayType.BYTES_PER_ELEMENT) {\n        throw new Error(\"Pass in a ArrayBuffer subclass\");\n      }\n      this._arrayLength = arrayLength;\n      this._arrayType = arrayType;\n      this._arrayElementSizeBytes = arrayType.BYTES_PER_ELEMENT;\n      this._arraySizeBytes = this._arrayLength * this._arrayElementSizeBytes;\n      this._sab = sab;\n      if (maxArrayCapacity === void 0)\n        maxArrayCapacity = WamArrayRingBuffer.DefaultArrayCapacity;\n      else\n        maxArrayCapacity = Math.max(maxArrayCapacity, WamArrayRingBuffer.DefaultArrayCapacity);\n      this._arrayArray = new arrayType(this._arrayLength);\n      this._rb = new RingBuffer2(this._sab, arrayType);\n    }\n    write(array) {\n      if (array.length !== this._arrayLength)\n        return false;\n      const elementsAvailable = this._rb.availableWrite;\n      if (elementsAvailable < this._arrayLength)\n        return false;\n      let success = true;\n      const elementsWritten = this._rb.push(array);\n      if (elementsWritten != this._arrayLength)\n        success = false;\n      return success;\n    }\n    read(array, newest) {\n      if (array.length !== this._arrayLength)\n        return false;\n      const elementsAvailable = this._rb.availableRead;\n      if (elementsAvailable < this._arrayLength)\n        return false;\n      if (newest && elementsAvailable > this._arrayLength)\n        this._rb.pop(elementsAvailable - this._arrayLength);\n      let success = false;\n      const elementsRead = this._rb.pop(array);\n      if (elementsRead === this._arrayLength)\n        success = true;\n      return success;\n    }\n  }\n  if (audioWorkletGlobalScope.AudioWorkletProcessor) {\n    const ModuleScope = audioWorkletGlobalScope.webAudioModules.getModuleScope(moduleId);\n    if (!ModuleScope.WamArrayRingBuffer)\n      ModuleScope.WamArrayRingBuffer = WamArrayRingBuffer;\n  }\n  return WamArrayRingBuffer;\n};\nvar WamArrayRingBuffer_default = getWamArrayRingBuffer;\n\n// src/WamEnv.js\nvar initializeWamEnv = (apiVersion) => {\n  const audioWorkletGlobalScope = globalThis;\n  if (audioWorkletGlobalScope.AudioWorkletProcessor && audioWorkletGlobalScope.webAudioModules)\n    return;\n  const moduleScopes = /* @__PURE__ */ new Map();\n  const groups = /* @__PURE__ */ new Map();\n  class WamEnv {\n    constructor() {\n    }\n    get apiVersion() {\n      return apiVersion;\n    }\n    getModuleScope(moduleId) {\n      if (!moduleScopes.has(moduleId))\n        moduleScopes.set(moduleId, {});\n      return moduleScopes.get(moduleId);\n    }\n    getGroup(groupId, groupKey) {\n      const group = groups.get(groupId);\n      if (group.validate(groupKey))\n        return group;\n      else\n        throw \"Invalid key\";\n    }\n    addGroup(group) {\n      if (!groups.has(group.groupId))\n        groups.set(group.groupId, group);\n    }\n    removeGroup(group) {\n      groups.delete(group.groupId);\n    }\n    addWam(wam) {\n      const group = groups.get(wam.groupId);\n      group.addWam(wam);\n    }\n    removeWam(wam) {\n      const group = groups.get(wam.groupId);\n      group.removeWam(wam);\n    }\n    connectEvents(groupId, fromId, toId, output = 0) {\n      const group = groups.get(groupId);\n      group.connectEvents(fromId, toId, output);\n    }\n    disconnectEvents(groupId, fromId, toId, output) {\n      const group = groups.get(groupId);\n      group.disconnectEvents(fromId, toId, output);\n    }\n    emitEvents(from, ...events) {\n      const group = groups.get(from.groupId);\n      group.emitEvents(from, ...events);\n    }\n  }\n  if (audioWorkletGlobalScope.AudioWorkletProcessor) {\n    if (!audioWorkletGlobalScope.webAudioModules)\n      audioWorkletGlobalScope.webAudioModules = new WamEnv();\n  }\n};\nvar WamEnv_default = initializeWamEnv;\n\n// src/WamGroup.js\nvar initializeWamGroup = (groupId, groupKey) => {\n  const audioWorkletGlobalScope = globalThis;\n  class WamGroup {\n    constructor(groupId2, groupKey2) {\n      this._groupId = groupId2;\n      this._validate = (key) => {\n        return key == groupKey2;\n      };\n      this._processors = /* @__PURE__ */ new Map();\n      this._eventGraph = /* @__PURE__ */ new Map();\n    }\n    get groupId() {\n      return this._groupId;\n    }\n    get processors() {\n      return this._processors;\n    }\n    get eventGraph() {\n      return this._eventGraph;\n    }\n    validate(groupKey2) {\n      return this._validate(groupKey2);\n    }\n    addWam(wam) {\n      this._processors.set(wam.instanceId, wam);\n    }\n    removeWam(wam) {\n      if (this._eventGraph.has(wam))\n        this._eventGraph.delete(wam);\n      this._eventGraph.forEach((outputMap) => {\n        outputMap.forEach((set) => {\n          if (set && set.has(wam))\n            set.delete(wam);\n        });\n      });\n      this._processors.delete(wam.instanceId);\n    }\n    connectEvents(fromId, toId, output) {\n      const from = this._processors.get(fromId);\n      const to = this._processors.get(toId);\n      let outputMap;\n      if (this._eventGraph.has(from)) {\n        outputMap = this._eventGraph.get(from);\n      } else {\n        outputMap = [];\n        this._eventGraph.set(from, outputMap);\n      }\n      if (outputMap[output]) {\n        outputMap[output].add(to);\n      } else {\n        const set = /* @__PURE__ */ new Set();\n        set.add(to);\n        outputMap[output] = set;\n      }\n    }\n    disconnectEvents(fromId, toId, output) {\n      const from = this._processors.get(fromId);\n      if (!this._eventGraph.has(from))\n        return;\n      const outputMap = this._eventGraph.get(from);\n      if (typeof toId === \"undefined\") {\n        outputMap.forEach((set) => {\n          if (set)\n            set.clear();\n        });\n        return;\n      }\n      const to = this._processors.get(toId);\n      if (typeof output === \"undefined\") {\n        outputMap.forEach((set) => {\n          if (set)\n            set.delete(to);\n        });\n        return;\n      }\n      if (!outputMap[output])\n        return;\n      outputMap[output].delete(to);\n    }\n    emitEvents(from, ...events) {\n      if (!this._eventGraph.has(from))\n        return;\n      const downstream = this._eventGraph.get(from);\n      downstream.forEach((set) => {\n        if (set)\n          set.forEach((wam) => wam.scheduleEvents(...events));\n      });\n    }\n  }\n  if (audioWorkletGlobalScope.AudioWorkletProcessor) {\n    audioWorkletGlobalScope.webAudioModules.addGroup(new WamGroup(groupId, groupKey));\n  }\n};\nvar WamGroup_default = initializeWamGroup;\n\n// src/WamEventRingBuffer.js\nvar getWamEventRingBuffer = (moduleId) => {\n  const audioWorkletGlobalScope = globalThis;\n  class WamEventRingBuffer2 {\n    static DefaultExtraBytesPerEvent = 64;\n    static WamEventBaseBytes = 4 + 1 + 8;\n    static WamAutomationEventBytes = WamEventRingBuffer2.WamEventBaseBytes + 2 + 8 + 1;\n    static WamTransportEventBytes = WamEventRingBuffer2.WamEventBaseBytes + 4 + 8 + 8 + 1 + 1 + 1;\n    static WamMidiEventBytes = WamEventRingBuffer2.WamEventBaseBytes + 1 + 1 + 1;\n    static WamBinaryEventBytes = WamEventRingBuffer2.WamEventBaseBytes + 4;\n    static getStorageForEventCapacity(RingBuffer2, eventCapacity, maxBytesPerEvent = void 0) {\n      if (maxBytesPerEvent === void 0)\n        maxBytesPerEvent = WamEventRingBuffer2.DefaultExtraBytesPerEvent;\n      else\n        maxBytesPerEvent = Math.max(maxBytesPerEvent, WamEventRingBuffer2.DefaultExtraBytesPerEvent);\n      const capacity = (Math.max(WamEventRingBuffer2.WamAutomationEventBytes, WamEventRingBuffer2.WamTransportEventBytes, WamEventRingBuffer2.WamMidiEventBytes, WamEventRingBuffer2.WamBinaryEventBytes) + maxBytesPerEvent) * eventCapacity;\n      return RingBuffer2.getStorageForCapacity(capacity, Uint8Array);\n    }\n    constructor(RingBuffer2, sab, parameterIds, maxBytesPerEvent = void 0) {\n      this._eventSizeBytes = {};\n      this._encodeEventType = {};\n      this._decodeEventType = {};\n      const wamEventTypes = [\"wam-automation\", \"wam-transport\", \"wam-midi\", \"wam-sysex\", \"wam-mpe\", \"wam-osc\", \"wam-info\"];\n      wamEventTypes.forEach((type, encodedType) => {\n        let byteSize = 0;\n        switch (type) {\n          case \"wam-automation\":\n            byteSize = WamEventRingBuffer2.WamAutomationEventBytes;\n            break;\n          case \"wam-transport\":\n            byteSize = WamEventRingBuffer2.WamTransportEventBytes;\n            break;\n          case \"wam-mpe\":\n          case \"wam-midi\":\n            byteSize = WamEventRingBuffer2.WamMidiEventBytes;\n            break;\n          case \"wam-osc\":\n          case \"wam-sysex\":\n          case \"wam-info\":\n            byteSize = WamEventRingBuffer2.WamBinaryEventBytes;\n            break;\n          default:\n            break;\n        }\n        this._eventSizeBytes[type] = byteSize;\n        this._encodeEventType[type] = encodedType;\n        this._decodeEventType[encodedType] = type;\n      });\n      this._parameterCode = 0;\n      this._parameterCodes = {};\n      this._encodeParameterId = {};\n      this._decodeParameterId = {};\n      this.setParameterIds(parameterIds);\n      this._sab = sab;\n      if (maxBytesPerEvent === void 0)\n        maxBytesPerEvent = WamEventRingBuffer2.DefaultExtraBytesPerEvent;\n      else\n        maxBytesPerEvent = Math.max(maxBytesPerEvent, WamEventRingBuffer2.DefaultExtraBytesPerEvent);\n      this._eventBytesAvailable = Math.max(WamEventRingBuffer2.WamAutomationEventBytes, WamEventRingBuffer2.WamTransportEventBytes, WamEventRingBuffer2.WamMidiEventBytes, WamEventRingBuffer2.WamBinaryEventBytes) + maxBytesPerEvent;\n      this._eventBytes = new ArrayBuffer(this._eventBytesAvailable);\n      this._eventBytesView = new DataView(this._eventBytes);\n      this._rb = new RingBuffer2(this._sab, Uint8Array);\n      this._eventSizeArray = new Uint8Array(this._eventBytes, 0, 4);\n      this._eventSizeView = new DataView(this._eventBytes, 0, 4);\n    }\n    _writeHeader(byteSize, type, time) {\n      let byteOffset = 0;\n      this._eventBytesView.setUint32(byteOffset, byteSize);\n      byteOffset += 4;\n      this._eventBytesView.setUint8(byteOffset, this._encodeEventType[type]);\n      byteOffset += 1;\n      this._eventBytesView.setFloat64(byteOffset, Number.isFinite(time) ? time : -1);\n      byteOffset += 8;\n      return byteOffset;\n    }\n    _encode(event) {\n      let byteOffset = 0;\n      const { type, time } = event;\n      switch (event.type) {\n        case \"wam-automation\":\n          {\n            if (!(event.data.id in this._encodeParameterId))\n              break;\n            const byteSize = this._eventSizeBytes[type];\n            byteOffset = this._writeHeader(byteSize, type, time);\n            const { data } = event;\n            const encodedParameterId = this._encodeParameterId[data.id];\n            const { value, normalized } = data;\n            this._eventBytesView.setUint16(byteOffset, encodedParameterId);\n            byteOffset += 2;\n            this._eventBytesView.setFloat64(byteOffset, value);\n            byteOffset += 8;\n            this._eventBytesView.setUint8(byteOffset, normalized ? 1 : 0);\n            byteOffset += 1;\n          }\n          break;\n        case \"wam-transport\":\n          {\n            const byteSize = this._eventSizeBytes[type];\n            byteOffset = this._writeHeader(byteSize, type, time);\n            const { data } = event;\n            const {\n              currentBar,\n              currentBarStarted,\n              tempo,\n              timeSigNumerator,\n              timeSigDenominator,\n              playing\n            } = data;\n            this._eventBytesView.setUint32(byteOffset, currentBar);\n            byteOffset += 4;\n            this._eventBytesView.setFloat64(byteOffset, currentBarStarted);\n            byteOffset += 8;\n            this._eventBytesView.setFloat64(byteOffset, tempo);\n            byteOffset += 8;\n            this._eventBytesView.setUint8(byteOffset, timeSigNumerator);\n            byteOffset += 1;\n            this._eventBytesView.setUint8(byteOffset, timeSigDenominator);\n            byteOffset += 1;\n            this._eventBytesView.setUint8(byteOffset, playing ? 1 : 0);\n            byteOffset += 1;\n          }\n          break;\n        case \"wam-mpe\":\n        case \"wam-midi\":\n          {\n            const byteSize = this._eventSizeBytes[type];\n            byteOffset = this._writeHeader(byteSize, type, time);\n            const { data } = event;\n            const { bytes } = data;\n            let b = 0;\n            while (b < 3) {\n              this._eventBytesView.setUint8(byteOffset, bytes[b]);\n              byteOffset += 1;\n              b++;\n            }\n          }\n          break;\n        case \"wam-osc\":\n        case \"wam-sysex\":\n        case \"wam-info\":\n          {\n            let bytes = null;\n            if (event.type === \"wam-info\") {\n              const { data } = event;\n              bytes = new TextEncoder().encode(data.instanceId);\n            } else {\n              const { data } = event;\n              bytes = data.bytes;\n            }\n            const numBytes = bytes.length;\n            const byteSize = this._eventSizeBytes[type];\n            byteOffset = this._writeHeader(byteSize + numBytes, type, time);\n            this._eventBytesView.setUint32(byteOffset, numBytes);\n            byteOffset += 4;\n            const bytesRequired = byteOffset + numBytes;\n            if (bytesRequired > this._eventBytesAvailable)\n              console.error(`Event requires ${bytesRequired} bytes but only ${this._eventBytesAvailable} have been allocated!`);\n            const buffer = new Uint8Array(this._eventBytes, byteOffset, numBytes);\n            buffer.set(bytes);\n            byteOffset += numBytes;\n          }\n          break;\n        default:\n          break;\n      }\n      return new Uint8Array(this._eventBytes, 0, byteOffset);\n    }\n    _decode() {\n      let byteOffset = 0;\n      const type = this._decodeEventType[this._eventBytesView.getUint8(byteOffset)];\n      byteOffset += 1;\n      let time = this._eventBytesView.getFloat64(byteOffset);\n      if (time === -1)\n        time = void 0;\n      byteOffset += 8;\n      switch (type) {\n        case \"wam-automation\": {\n          const encodedParameterId = this._eventBytesView.getUint16(byteOffset);\n          byteOffset += 2;\n          const value = this._eventBytesView.getFloat64(byteOffset);\n          byteOffset += 8;\n          const normalized = !!this._eventBytesView.getUint8(byteOffset);\n          byteOffset += 1;\n          if (!(encodedParameterId in this._decodeParameterId))\n            break;\n          const id = this._decodeParameterId[encodedParameterId];\n          const event = {\n            type,\n            time,\n            data: {\n              id,\n              value,\n              normalized\n            }\n          };\n          return event;\n        }\n        case \"wam-transport\": {\n          const currentBar = this._eventBytesView.getUint32(byteOffset);\n          byteOffset += 4;\n          const currentBarStarted = this._eventBytesView.getFloat64(byteOffset);\n          byteOffset += 8;\n          const tempo = this._eventBytesView.getFloat64(byteOffset);\n          byteOffset += 8;\n          const timeSigNumerator = this._eventBytesView.getUint8(byteOffset);\n          byteOffset += 1;\n          const timeSigDenominator = this._eventBytesView.getUint8(byteOffset);\n          byteOffset += 1;\n          const playing = this._eventBytesView.getUint8(byteOffset) == 1;\n          byteOffset += 1;\n          const event = {\n            type,\n            time,\n            data: {\n              currentBar,\n              currentBarStarted,\n              tempo,\n              timeSigNumerator,\n              timeSigDenominator,\n              playing\n            }\n          };\n          return event;\n        }\n        case \"wam-mpe\":\n        case \"wam-midi\": {\n          const bytes = [0, 0, 0];\n          let b = 0;\n          while (b < 3) {\n            bytes[b] = this._eventBytesView.getUint8(byteOffset);\n            byteOffset += 1;\n            b++;\n          }\n          const event = {\n            type,\n            time,\n            data: { bytes }\n          };\n          return event;\n        }\n        case \"wam-osc\":\n        case \"wam-sysex\":\n        case \"wam-info\": {\n          const numBytes = this._eventBytesView.getUint32(byteOffset);\n          byteOffset += 4;\n          const bytes = new Uint8Array(numBytes);\n          bytes.set(new Uint8Array(this._eventBytes, byteOffset, numBytes));\n          byteOffset += numBytes;\n          if (type === \"wam-info\") {\n            const instanceId = new TextDecoder().decode(bytes);\n            const data = { instanceId };\n            return { type, time, data };\n          } else {\n            const data = { bytes };\n            return { type, time, data };\n          }\n        }\n        default:\n          break;\n      }\n      return false;\n    }\n    write(...events) {\n      const numEvents = events.length;\n      let bytesAvailable = this._rb.availableWrite;\n      let numSkipped = 0;\n      let i = 0;\n      while (i < numEvents) {\n        const event = events[i];\n        const bytes = this._encode(event);\n        const eventSizeBytes = bytes.byteLength;\n        let bytesWritten = 0;\n        if (bytesAvailable >= eventSizeBytes) {\n          if (eventSizeBytes === 0)\n            numSkipped++;\n          else\n            bytesWritten = this._rb.push(bytes);\n        } else\n          break;\n        bytesAvailable -= bytesWritten;\n        i++;\n      }\n      return i - numSkipped;\n    }\n    read() {\n      if (this._rb.empty)\n        return [];\n      const events = [];\n      let bytesAvailable = this._rb.availableRead;\n      let bytesRead = 0;\n      while (bytesAvailable > 0) {\n        bytesRead = this._rb.pop(this._eventSizeArray);\n        bytesAvailable -= bytesRead;\n        const eventSizeBytes = this._eventSizeView.getUint32(0);\n        const eventBytes = new Uint8Array(this._eventBytes, 0, eventSizeBytes - 4);\n        bytesRead = this._rb.pop(eventBytes);\n        bytesAvailable -= bytesRead;\n        const decodedEvent = this._decode();\n        if (decodedEvent)\n          events.push(decodedEvent);\n      }\n      return events;\n    }\n    setParameterIds(parameterIds) {\n      this._encodeParameterId = {};\n      this._decodeParameterId = {};\n      parameterIds.forEach((parameterId) => {\n        let parameterCode = -1;\n        if (parameterId in this._parameterCodes)\n          parameterCode = this._parameterCodes[parameterId];\n        else {\n          parameterCode = this._generateParameterCode();\n          this._parameterCodes[parameterId] = parameterCode;\n        }\n        this._encodeParameterId[parameterId] = parameterCode;\n        this._decodeParameterId[parameterCode] = parameterId;\n      });\n    }\n    _generateParameterCode() {\n      if (this._parameterCode > 65535)\n        throw Error(\"Too many parameters have been registered!\");\n      return this._parameterCode++;\n    }\n  }\n  if (audioWorkletGlobalScope.AudioWorkletProcessor) {\n    const ModuleScope = audioWorkletGlobalScope.webAudioModules.getModuleScope(moduleId);\n    if (!ModuleScope.WamEventRingBuffer)\n      ModuleScope.WamEventRingBuffer = WamEventRingBuffer2;\n  }\n  return WamEventRingBuffer2;\n};\nvar WamEventRingBuffer_default = getWamEventRingBuffer;\n\n// src/addFunctionModule.js\nvar addFunctionModule = (audioWorklet, processorFunction, ...injection) => {\n  const text = `(${processorFunction.toString()})(${injection.map((s) => JSON.stringify(s)).join(\", \")});`;\n  const url = URL.createObjectURL(new Blob([text], { type: \"text/javascript\" }));\n  return audioWorklet.addModule(url);\n};\nvar addFunctionModule_default = addFunctionModule;\n\n// src/WamParameter.js\nvar getWamParameter = (moduleId) => {\n  const audioWorkletGlobalScope = globalThis;\n  class WamParameter {\n    constructor(info) {\n      this.info = info;\n      this._value = info.defaultValue;\n    }\n    set value(value) {\n      this._value = value;\n    }\n    get value() {\n      return this._value;\n    }\n    set normalizedValue(valueNorm) {\n      this.value = this.info.denormalize(valueNorm);\n    }\n    get normalizedValue() {\n      return this.info.normalize(this.value);\n    }\n  }\n  if (audioWorkletGlobalScope.AudioWorkletProcessor) {\n    const ModuleScope = audioWorkletGlobalScope.webAudioModules.getModuleScope(moduleId);\n    if (!ModuleScope.WamParameter)\n      ModuleScope.WamParameter = WamParameter;\n  }\n  return WamParameter;\n};\nvar WamParameter_default = getWamParameter;\n\n// src/WamParameterInfo.js\nvar getWamParameterInfo = (moduleId) => {\n  const audioWorkletGlobalScope = globalThis;\n  const normExp = (x, e) => e === 0 ? x : x ** 1.5 ** -e;\n  const denormExp = (x, e) => e === 0 ? x : x ** 1.5 ** e;\n  const normalize = (x, min, max, e = 0) => min === 0 && max === 1 ? normExp(x, e) : normExp((x - min) / (max - min) || 0, e);\n  const denormalize = (x, min, max, e = 0) => min === 0 && max === 1 ? denormExp(x, e) : denormExp(x, e) * (max - min) + min;\n  const inRange = (x, min, max) => x >= min && x <= max;\n  class WamParameterInfo {\n    constructor(id, config = {}) {\n      let {\n        type,\n        label,\n        defaultValue,\n        minValue,\n        maxValue,\n        discreteStep,\n        exponent,\n        choices,\n        units\n      } = config;\n      if (type === void 0)\n        type = \"float\";\n      if (label === void 0)\n        label = \"\";\n      if (defaultValue === void 0)\n        defaultValue = 0;\n      if (choices === void 0)\n        choices = [];\n      if (type === \"boolean\" || type === \"choice\") {\n        discreteStep = 1;\n        minValue = 0;\n        if (choices.length)\n          maxValue = choices.length - 1;\n        else\n          maxValue = 1;\n      } else {\n        if (minValue === void 0)\n          minValue = 0;\n        if (maxValue === void 0)\n          maxValue = 1;\n        if (discreteStep === void 0)\n          discreteStep = 0;\n        if (exponent === void 0)\n          exponent = 0;\n        if (units === void 0)\n          units = \"\";\n      }\n      const errBase = `Param config error | ${id}: `;\n      if (minValue >= maxValue)\n        throw Error(errBase.concat(\"minValue must be less than maxValue\"));\n      if (!inRange(defaultValue, minValue, maxValue))\n        throw Error(errBase.concat(\"defaultValue out of range\"));\n      if (discreteStep % 1 || discreteStep < 0) {\n        throw Error(errBase.concat(\"discreteStep must be a non-negative integer\"));\n      } else if (discreteStep > 0 && (minValue % 1 || maxValue % 1 || defaultValue % 1)) {\n        throw Error(errBase.concat(\"non-zero discreteStep requires integer minValue, maxValue, and defaultValue\"));\n      }\n      if (type === \"choice\" && !choices.length) {\n        throw Error(errBase.concat(\"choice type parameter requires list of strings in choices\"));\n      }\n      this.id = id;\n      this.label = label;\n      this.type = type;\n      this.defaultValue = defaultValue;\n      this.minValue = minValue;\n      this.maxValue = maxValue;\n      this.discreteStep = discreteStep;\n      this.exponent = exponent;\n      this.choices = choices;\n      this.units = units;\n    }\n    normalize(value) {\n      return normalize(value, this.minValue, this.maxValue, this.exponent);\n    }\n    denormalize(valueNorm) {\n      return denormalize(valueNorm, this.minValue, this.maxValue, this.exponent);\n    }\n    valueString(value) {\n      if (this.choices)\n        return this.choices[value];\n      if (this.units !== \"\")\n        return `${value} ${this.units}`;\n      return `${value}`;\n    }\n  }\n  if (audioWorkletGlobalScope.AudioWorkletProcessor) {\n    const ModuleScope = audioWorkletGlobalScope.webAudioModules.getModuleScope(moduleId);\n    if (!ModuleScope.WamParameterInfo)\n      ModuleScope.WamParameterInfo = WamParameterInfo;\n  }\n  return WamParameterInfo;\n};\nvar WamParameterInfo_default = getWamParameterInfo;\n\n// src/WamParameterInterpolator.js\nvar getWamParameterInterpolator = (moduleId) => {\n  const audioWorkletGlobalScope = globalThis;\n  const samplesPerQuantum = 128;\n  const nullTableKey = \"0_0\";\n  class WamParameterInterpolator {\n    static _tables;\n    static _tableReferences;\n    constructor(info, samplesPerInterpolation, skew = 0) {\n      if (!WamParameterInterpolator._tables) {\n        WamParameterInterpolator._tables = { nullTableKey: new Float32Array(0) };\n        WamParameterInterpolator._tableReferences = { nullTableKey: [] };\n      }\n      this.info = info;\n      this.values = new Float32Array(samplesPerQuantum);\n      this._tableKey = nullTableKey;\n      this._table = WamParameterInterpolator._tables[this._tableKey];\n      this._skew = 2;\n      const { discreteStep } = info;\n      this._discrete = !!discreteStep;\n      this._N = this._discrete ? 0 : samplesPerInterpolation;\n      this._n = 0;\n      this._startValue = info.defaultValue;\n      this._endValue = info.defaultValue;\n      this._currentValue = info.defaultValue;\n      this._deltaValue = 0;\n      this._inverted = false;\n      this._changed = true;\n      this._filled = 0;\n      if (!this._discrete)\n        this.setSkew(skew);\n      else\n        this._skew = 0;\n      this.setStartValue(this._startValue);\n    }\n    _removeTableReference(oldKey) {\n      if (oldKey === nullTableKey)\n        return;\n      const { id } = this.info;\n      const references = WamParameterInterpolator._tableReferences[oldKey];\n      if (references) {\n        const index = references.indexOf(id);\n        if (index !== -1)\n          references.splice(index, 1);\n        if (references.length === 0) {\n          delete WamParameterInterpolator._tables[oldKey];\n          delete WamParameterInterpolator._tableReferences[oldKey];\n        }\n      }\n    }\n    setSkew(skew) {\n      if (this._skew === skew || this._discrete)\n        return;\n      if (skew < -1 || skew > 1)\n        throw Error(\"skew must be in range [-1.0, 1.0]\");\n      const newKey = [this._N, skew].join(\"_\");\n      const oldKey = this._tableKey;\n      const { id } = this.info;\n      if (newKey === oldKey)\n        return;\n      if (WamParameterInterpolator._tables[newKey]) {\n        const references = WamParameterInterpolator._tableReferences[newKey];\n        if (references)\n          references.push(id);\n        else\n          WamParameterInterpolator._tableReferences[newKey] = [id];\n      } else {\n        let e = Math.abs(skew);\n        e = Math.pow(3 - e, e * (e + 2));\n        const linear = e === 1;\n        const N = this._N;\n        const table = new Float32Array(N + 1);\n        if (linear)\n          for (let n = 0; n <= N; ++n)\n            table[n] = n / N;\n        else\n          for (let n = 0; n <= N; ++n)\n            table[n] = (n / N) ** e;\n        WamParameterInterpolator._tables[newKey] = table;\n        WamParameterInterpolator._tableReferences[newKey] = [id];\n      }\n      this._removeTableReference(oldKey);\n      this._skew = skew;\n      this._tableKey = newKey;\n      this._table = WamParameterInterpolator._tables[this._tableKey];\n    }\n    setStartValue(value, fill = true) {\n      this._n = this._N;\n      this._startValue = value;\n      this._endValue = value;\n      this._currentValue = value;\n      this._deltaValue = 0;\n      this._inverted = false;\n      if (fill) {\n        this.values.fill(value);\n        this._changed = true;\n        this._filled = this.values.length;\n      } else {\n        this._changed = false;\n        this._filled = 0;\n      }\n    }\n    setEndValue(value) {\n      if (value === this._endValue)\n        return;\n      this._n = 0;\n      this._startValue = this._currentValue;\n      this._endValue = value;\n      this._deltaValue = this._endValue - this._startValue;\n      this._inverted = this._deltaValue > 0 && this._skew >= 0 || this._deltaValue <= 0 && this._skew < 0;\n      this._changed = false;\n      this._filled = 0;\n    }\n    process(startSample, endSample) {\n      if (this.done)\n        return;\n      const length = endSample - startSample;\n      let fill = 0;\n      const change = this._N - this._n;\n      if (this._discrete || !change)\n        fill = length;\n      else {\n        if (change < length) {\n          fill = Math.min(length - change, samplesPerQuantum);\n          endSample -= fill;\n        }\n        if (endSample > startSample) {\n          if (this._inverted) {\n            for (let i = startSample; i < endSample; ++i) {\n              const tableValue = 1 - this._table[this._N - ++this._n];\n              this.values[i] = this._startValue + tableValue * this._deltaValue;\n            }\n          } else {\n            for (let i = startSample; i < endSample; ++i) {\n              const tableValue = this._table[++this._n];\n              this.values[i] = this._startValue + tableValue * this._deltaValue;\n            }\n          }\n        }\n        if (fill > 0) {\n          startSample = endSample;\n          endSample += fill;\n        }\n      }\n      if (fill > 0) {\n        this.values.fill(this._endValue, startSample, endSample);\n        this._filled += fill;\n      }\n      this._currentValue = this.values[endSample - 1];\n      if (this._n === this._N) {\n        if (!this._changed)\n          this._changed = true;\n        else if (this._filled >= this.values.length) {\n          this.setStartValue(this._endValue, false);\n          this._changed = true;\n          this._filled = this.values.length;\n        }\n      }\n    }\n    get done() {\n      return this._changed && this._filled === this.values.length;\n    }\n    is(value) {\n      return this._endValue === value && this.done;\n    }\n    destroy() {\n      this._removeTableReference(this._tableKey);\n    }\n  }\n  if (audioWorkletGlobalScope.AudioWorkletProcessor) {\n    const ModuleScope = audioWorkletGlobalScope.webAudioModules.getModuleScope(moduleId);\n    if (!ModuleScope.WamParameterInterpolator)\n      ModuleScope.WamParameterInterpolator = WamParameterInterpolator;\n  }\n  return WamParameterInterpolator;\n};\nvar WamParameterInterpolator_default = getWamParameterInterpolator;\n\n// src/WamProcessor.js\nvar getWamProcessor = (moduleId) => {\n  const audioWorkletGlobalScope = globalThis;\n  const {\n    AudioWorkletProcessor,\n    webAudioModules\n  } = audioWorkletGlobalScope;\n  const ModuleScope = audioWorkletGlobalScope.webAudioModules.getModuleScope(moduleId);\n  const {\n    RingBuffer: RingBuffer2,\n    WamEventRingBuffer: WamEventRingBuffer2,\n    WamParameter,\n    WamParameterInterpolator\n  } = ModuleScope;\n  class WamProcessor extends AudioWorkletProcessor {\n    constructor(options) {\n      super();\n      const {\n        groupId,\n        moduleId: moduleId2,\n        instanceId,\n        useSab\n      } = options.processorOptions;\n      if (!moduleId2)\n        throw Error(\"must provide moduleId argument in processorOptions!\");\n      if (!instanceId)\n        throw Error(\"must provide instanceId argument in processorOptions!\");\n      this.groupId = groupId;\n      this.moduleId = moduleId2;\n      this.instanceId = instanceId;\n      this._samplesPerQuantum = 128;\n      this._compensationDelay = 0;\n      this._parameterInfo = {};\n      this._parameterState = {};\n      this._parameterInterpolators = {};\n      this._eventQueue = [];\n      this._pendingResponses = {};\n      this._useSab = !!useSab && !!globalThis.SharedArrayBuffer;\n      this._eventSabReady = false;\n      this._audioToMainEventSab = null;\n      this._mainToAudioEventSab = null;\n      this._eventWriter = null;\n      this._eventReader = null;\n      this._initialized = false;\n      this._destroyed = false;\n      webAudioModules.addWam(this);\n      this.port.onmessage = this._onMessage.bind(this);\n      if (this._useSab)\n        this._configureSab();\n    }\n    getCompensationDelay() {\n      return this._compensationDelay;\n    }\n    scheduleEvents(...events) {\n      let i = 0;\n      while (i < events.length) {\n        this._eventQueue.push({ id: 0, event: events[i] });\n        i++;\n      }\n      this._eventQueue.sort((a, b) => a.event.time - b.event.time);\n    }\n    emitEvents(...events) {\n      webAudioModules.emitEvents(this, ...events);\n    }\n    clearEvents() {\n      this._eventQueue = [];\n    }\n    process(inputs, outputs, parameters) {\n      if (!this._initialized)\n        return true;\n      if (this._destroyed)\n        return false;\n      if (this._eventSabReady)\n        this.scheduleEvents(...this._eventReader.read());\n      const processingSlices = this._getProcessingSlices();\n      let i = 0;\n      while (i < processingSlices.length) {\n        const { range, events } = processingSlices[i];\n        const [startSample, endSample] = range;\n        let j = 0;\n        while (j < events.length) {\n          this._processEvent(events[j]);\n          j++;\n        }\n        this._interpolateParameterValues(startSample, endSample);\n        this._process(startSample, endSample, inputs, outputs, parameters);\n        i++;\n      }\n      return true;\n    }\n    destroy() {\n      this._destroyed = true;\n      this.port.close();\n      webAudioModules.removeWam(this);\n    }\n    _generateWamParameterInfo() {\n      return {};\n    }\n    _initialize() {\n      this._parameterState = {};\n      this._parameterInterpolators = {};\n      this._parameterInfo = this._generateWamParameterInfo();\n      Object.keys(this._parameterInfo).forEach((parameterId) => {\n        const info = this._parameterInfo[parameterId];\n        this._parameterState[parameterId] = new WamParameter(this._parameterInfo[parameterId]);\n        this._parameterInterpolators[parameterId] = new WamParameterInterpolator(info, 256);\n      });\n    }\n    _configureSab() {\n      const eventCapacity = 2 ** 10;\n      const parameterIds = Object.keys(this._parameterInfo);\n      if (this._eventSabReady) {\n        this._eventWriter.setParameterIds(parameterIds);\n        this._eventReader.setParameterIds(parameterIds);\n      }\n      this.port.postMessage({ eventSab: { eventCapacity, parameterIds } });\n    }\n    async _onMessage(message) {\n      if (message.data.request) {\n        const {\n          id,\n          request,\n          content\n        } = message.data;\n        const response = { id, response: request };\n        const requestComponents = request.split(\"/\");\n        const verb = requestComponents[0];\n        const noun = requestComponents[1];\n        response.content = \"error\";\n        if (verb === \"get\") {\n          if (noun === \"parameterInfo\") {\n            let { parameterIds } = content;\n            if (!parameterIds.length)\n              parameterIds = Object.keys(this._parameterInfo);\n            const parameterInfo = {};\n            let i = 0;\n            while (i < parameterIds.length) {\n              const parameterId = parameterIds[i];\n              parameterInfo[parameterId] = this._parameterInfo[parameterId];\n              i++;\n            }\n            response.content = parameterInfo;\n          } else if (noun === \"parameterValues\") {\n            let { normalized, parameterIds } = content;\n            response.content = this._getParameterValues(normalized, parameterIds);\n          } else if (noun === \"state\") {\n            response.content = this._getState();\n          } else if (noun === \"compensationDelay\") {\n            response.content = this.getCompensationDelay();\n          }\n        } else if (verb === \"set\") {\n          if (noun === \"parameterValues\") {\n            const { parameterValues } = content;\n            this._setParameterValues(parameterValues, true);\n            delete response.content;\n          } else if (noun === \"state\") {\n            const { state } = content;\n            this._setState(state);\n            delete response.content;\n          }\n        } else if (verb === \"add\") {\n          if (noun === \"event\") {\n            const { event } = content;\n            this._eventQueue.push({ id, event });\n            return;\n          }\n        } else if (verb === \"remove\") {\n          if (noun === \"events\") {\n            const ids = this._eventQueue.map((queued) => queued.id);\n            this.clearEvents();\n            response.content = ids;\n          }\n        } else if (verb === \"connect\") {\n          if (noun === \"events\") {\n            const { wamInstanceId, output } = content;\n            this._connectEvents(wamInstanceId, output);\n            delete response.content;\n          }\n        } else if (verb === \"disconnect\") {\n          if (noun === \"events\") {\n            const { wamInstanceId, output } = content;\n            this._disconnectEvents(wamInstanceId, output);\n            delete response.content;\n          }\n        } else if (verb === \"initialize\") {\n          if (noun === \"processor\") {\n            this._initialize();\n            this._initialized = true;\n            delete response.content;\n          } else if (noun === \"eventSab\") {\n            const { mainToAudioEventSab, audioToMainEventSab } = content;\n            this._audioToMainEventSab = audioToMainEventSab;\n            this._mainToAudioEventSab = mainToAudioEventSab;\n            const parameterIds = Object.keys(this._parameterInfo);\n            this._eventWriter = new WamEventRingBuffer2(RingBuffer2, this._audioToMainEventSab, parameterIds);\n            this._eventReader = new WamEventRingBuffer2(RingBuffer2, this._mainToAudioEventSab, parameterIds);\n            this._eventSabReady = true;\n            delete response.content;\n          }\n        }\n        this.port.postMessage(response);\n      } else if (message.data.destroy) {\n        this.destroy();\n      }\n    }\n    _onTransport(transportData) {\n      console.error(\"_onTransport not implemented!\");\n    }\n    _onMidi(midiData) {\n      console.error(\"_onMidi not implemented!\");\n    }\n    _onSysex(sysexData) {\n      console.error(\"_onMidi not implemented!\");\n    }\n    _onMpe(mpeData) {\n      console.error(\"_onMpe not implemented!\");\n    }\n    _onOsc(oscData) {\n      console.error(\"_onOsc not implemented!\");\n    }\n    _setState(state) {\n      if (state.parameterValues)\n        this._setParameterValues(state.parameterValues, false);\n    }\n    _getState() {\n      return { parameterValues: this._getParameterValues(false) };\n    }\n    _getParameterValues(normalized, parameterIds) {\n      const parameterValues = {};\n      if (!parameterIds || !parameterIds.length)\n        parameterIds = Object.keys(this._parameterState);\n      let i = 0;\n      while (i < parameterIds.length) {\n        const id = parameterIds[i];\n        const parameter = this._parameterState[id];\n        parameterValues[id] = {\n          id,\n          value: normalized ? parameter.normalizedValue : parameter.value,\n          normalized\n        };\n        i++;\n      }\n      return parameterValues;\n    }\n    _setParameterValues(parameterUpdates, interpolate) {\n      const parameterIds = Object.keys(parameterUpdates);\n      let i = 0;\n      while (i < parameterIds.length) {\n        this._setParameterValue(parameterUpdates[parameterIds[i]], interpolate);\n        i++;\n      }\n    }\n    _setParameterValue(parameterUpdate, interpolate) {\n      const { id, value, normalized } = parameterUpdate;\n      const parameter = this._parameterState[id];\n      if (!parameter)\n        return;\n      if (!normalized)\n        parameter.value = value;\n      else\n        parameter.normalizedValue = value;\n      const interpolator = this._parameterInterpolators[id];\n      if (interpolate)\n        interpolator.setEndValue(parameter.value);\n      else\n        interpolator.setStartValue(parameter.value);\n    }\n    _interpolateParameterValues(startIndex, endIndex) {\n      const parameterIds = Object.keys(this._parameterInterpolators);\n      let i = 0;\n      while (i < parameterIds.length) {\n        this._parameterInterpolators[parameterIds[i]].process(startIndex, endIndex);\n        i++;\n      }\n    }\n    _connectEvents(wamInstanceId, output) {\n      webAudioModules.connectEvents(this.groupId, this.instanceId, wamInstanceId, output);\n    }\n    _disconnectEvents(wamInstanceId, output) {\n      if (typeof wamInstanceId === \"undefined\") {\n        webAudioModules.disconnectEvents(this.groupId, this.instanceId);\n        return;\n      }\n      webAudioModules.disconnectEvents(this.groupId, this.instanceId, wamInstanceId, output);\n    }\n    _getProcessingSlices() {\n      const response = \"add/event\";\n      const { currentTime, sampleRate } = audioWorkletGlobalScope;\n      const eventsBySampleIndex = {};\n      let i = 0;\n      while (i < this._eventQueue.length) {\n        const { id, event } = this._eventQueue[i];\n        const offsetSec = event.time - currentTime;\n        const sampleIndex = offsetSec > 0 ? Math.round(offsetSec * sampleRate) : 0;\n        if (sampleIndex < this._samplesPerQuantum) {\n          if (eventsBySampleIndex[sampleIndex])\n            eventsBySampleIndex[sampleIndex].push(event);\n          else\n            eventsBySampleIndex[sampleIndex] = [event];\n          if (id)\n            this.port.postMessage({ id, response });\n          else if (this._eventSabReady)\n            this._eventWriter.write(event);\n          else\n            this.port.postMessage({ event });\n          this._eventQueue.shift();\n          i = -1;\n        } else\n          break;\n        i++;\n      }\n      const processingSlices = [];\n      const keys = Object.keys(eventsBySampleIndex);\n      if (keys[0] !== \"0\") {\n        keys.unshift(\"0\");\n        eventsBySampleIndex[\"0\"] = [];\n      }\n      const lastIndex = keys.length - 1;\n      i = 0;\n      while (i < keys.length) {\n        const key = keys[i];\n        const startSample = parseInt(key);\n        const endSample = i < lastIndex ? parseInt(keys[i + 1]) : this._samplesPerQuantum;\n        processingSlices.push({ range: [startSample, endSample], events: eventsBySampleIndex[key] });\n        i++;\n      }\n      return processingSlices;\n    }\n    _processEvent(event) {\n      switch (event.type) {\n        case \"wam-automation\":\n          this._setParameterValue(event.data, true);\n          break;\n        case \"wam-transport\":\n          this._onTransport(event.data);\n          break;\n        case \"wam-midi\":\n          this._onMidi(event.data);\n          break;\n        case \"wam-sysex\":\n          this._onSysex(event.data);\n          break;\n        case \"wam-mpe\":\n          this._onMpe(event.data);\n          break;\n        case \"wam-osc\":\n          this._onOsc(event.data);\n          break;\n        default:\n          break;\n      }\n    }\n    _process(startSample, endSample, inputs, outputs, parameters) {\n      console.error(\"_process not implemented!\");\n    }\n  }\n  if (audioWorkletGlobalScope.AudioWorkletProcessor) {\n    if (!ModuleScope.WamProcessor)\n      ModuleScope.WamProcessor = WamProcessor;\n  }\n  return WamProcessor;\n};\nvar WamProcessor_default = getWamProcessor;\n\n// src/WamNode.js\nvar RingBuffer = RingBuffer_default();\nvar WamEventRingBuffer = WamEventRingBuffer_default();\nvar WamNode = class extends AudioWorkletNode {\n  static async addModules(audioContext, moduleId) {\n    const { audioWorklet } = audioContext;\n    await addFunctionModule_default(audioWorklet, RingBuffer_default, moduleId);\n    await addFunctionModule_default(audioWorklet, WamEventRingBuffer_default, moduleId);\n    await addFunctionModule_default(audioWorklet, WamArrayRingBuffer_default, moduleId);\n    await addFunctionModule_default(audioWorklet, WamParameter_default, moduleId);\n    await addFunctionModule_default(audioWorklet, WamParameterInfo_default, moduleId);\n    await addFunctionModule_default(audioWorklet, WamParameterInterpolator_default, moduleId);\n    await addFunctionModule_default(audioWorklet, WamProcessor_default, moduleId);\n  }\n  constructor(module, options) {\n    const { audioContext, groupId, moduleId, instanceId } = module;\n    options.processorOptions = {\n      groupId,\n      moduleId,\n      instanceId,\n      ...options.processorOptions\n    };\n    super(audioContext, moduleId, options);\n    this.module = module;\n    this._supportedEventTypes = /* @__PURE__ */ new Set([\"wam-automation\", \"wam-transport\", \"wam-midi\", \"wam-sysex\", \"wam-mpe\", \"wam-osc\"]);\n    this._messageId = 1;\n    this._pendingResponses = {};\n    this._pendingEvents = {};\n    this._useSab = false;\n    this._eventSabReady = false;\n    this._destroyed = false;\n    this.port.onmessage = this._onMessage.bind(this);\n  }\n  get groupId() {\n    return this.module.groupId;\n  }\n  get moduleId() {\n    return this.module.moduleId;\n  }\n  get instanceId() {\n    return this.module.instanceId;\n  }\n  async getParameterInfo(...parameterIds) {\n    const request = \"get/parameterInfo\";\n    const id = this._generateMessageId();\n    return new Promise((resolve) => {\n      this._pendingResponses[id] = resolve;\n      this.port.postMessage({\n        id,\n        request,\n        content: { parameterIds }\n      });\n    });\n  }\n  async getParameterValues(normalized, ...parameterIds) {\n    const request = \"get/parameterValues\";\n    const id = this._generateMessageId();\n    return new Promise((resolve) => {\n      this._pendingResponses[id] = resolve;\n      this.port.postMessage({\n        id,\n        request,\n        content: { normalized, parameterIds }\n      });\n    });\n  }\n  async setParameterValues(parameterValues) {\n    const request = \"set/parameterValues\";\n    const id = this._generateMessageId();\n    return new Promise((resolve) => {\n      this._pendingResponses[id] = resolve;\n      this.port.postMessage({\n        id,\n        request,\n        content: { parameterValues }\n      });\n    });\n  }\n  async getState() {\n    const request = \"get/state\";\n    const id = this._generateMessageId();\n    return new Promise((resolve) => {\n      this._pendingResponses[id] = resolve;\n      this.port.postMessage({ id, request });\n    });\n  }\n  async setState(state) {\n    const request = \"set/state\";\n    const id = this._generateMessageId();\n    return new Promise((resolve) => {\n      this._pendingResponses[id] = resolve;\n      this.port.postMessage({\n        id,\n        request,\n        content: { state }\n      });\n    });\n  }\n  async getCompensationDelay() {\n    const request = \"get/compensationDelay\";\n    const id = this._generateMessageId();\n    return new Promise((resolve) => {\n      this._pendingResponses[id] = resolve;\n      this.port.postMessage({ id, request });\n    });\n  }\n  addEventListener(type, callback, options) {\n    if (this._supportedEventTypes.has(type))\n      super.addEventListener(type, callback, options);\n  }\n  removeEventListener(type, callback, options) {\n    if (this._supportedEventTypes.has(type))\n      super.removeEventListener(type, callback, options);\n  }\n  scheduleEvents(...events) {\n    let i = 0;\n    const numEvents = events.length;\n    if (this._eventSabReady) {\n      i = this._eventWriter.write(...events);\n    }\n    while (i < numEvents) {\n      const event = events[i];\n      const request = \"add/event\";\n      const id = this._generateMessageId();\n      let processed = false;\n      new Promise((resolve, reject) => {\n        this._pendingResponses[id] = resolve;\n        this._pendingEvents[id] = () => {\n          if (!processed)\n            reject();\n        };\n        this.port.postMessage({\n          id,\n          request,\n          content: { event }\n        });\n      }).then((resolved) => {\n        processed = true;\n        delete this._pendingEvents[id];\n        this._onEvent(event);\n      }).catch((rejected) => {\n        delete this._pendingResponses[id];\n      });\n      i++;\n    }\n  }\n  async clearEvents() {\n    const request = \"remove/events\";\n    const id = this._generateMessageId();\n    const ids = Object.keys(this._pendingEvents);\n    if (ids.length) {\n      return new Promise((resolve) => {\n        this._pendingResponses[id] = resolve;\n        this.port.postMessage({ id, request });\n      }).then((clearedIds) => {\n        clearedIds.forEach((clearedId) => {\n          this._pendingEvents[clearedId]();\n          delete this._pendingEvents[clearedId];\n        });\n      });\n    }\n  }\n  connectEvents(toId, output) {\n    const request = \"connect/events\";\n    const id = this._generateMessageId();\n    new Promise((resolve, reject) => {\n      this._pendingResponses[id] = resolve;\n      this.port.postMessage({\n        id,\n        request,\n        content: { wamInstanceId: toId, output }\n      });\n    });\n  }\n  disconnectEvents(toId, output) {\n    const request = \"disconnect/events\";\n    const id = this._generateMessageId();\n    new Promise((resolve, reject) => {\n      this._pendingResponses[id] = resolve;\n      this.port.postMessage({\n        id,\n        request,\n        content: { wamInstanceId: toId, output }\n      });\n    });\n  }\n  destroy() {\n    if (this._audioToMainInterval)\n      clearInterval(this._audioToMainInterval);\n    this.port.postMessage({ destroy: true });\n    this.port.close();\n    this.disconnect();\n    this._destroyed = true;\n  }\n  _generateMessageId() {\n    return this._messageId++;\n  }\n  async _initialize() {\n    const request = \"initialize/processor\";\n    const id = this._generateMessageId();\n    return new Promise((resolve) => {\n      this._pendingResponses[id] = resolve;\n      this.port.postMessage({ id, request });\n    });\n  }\n  _onMessage(message) {\n    const { data } = message;\n    const { response, event, eventSab } = data;\n    if (response) {\n      const { id, content } = data;\n      const resolvePendingResponse = this._pendingResponses[id];\n      if (resolvePendingResponse) {\n        delete this._pendingResponses[id];\n        resolvePendingResponse(content);\n      }\n    } else if (eventSab) {\n      this._useSab = true;\n      const { eventCapacity, parameterIds } = eventSab;\n      if (this._eventSabReady) {\n        this._eventWriter.setParameterIds(parameterIds);\n        this._eventReader.setParameterIds(parameterIds);\n        return;\n      }\n      this._mainToAudioEventSab = WamEventRingBuffer.getStorageForEventCapacity(RingBuffer, eventCapacity);\n      this._audioToMainEventSab = WamEventRingBuffer.getStorageForEventCapacity(RingBuffer, eventCapacity);\n      this._eventWriter = new WamEventRingBuffer(RingBuffer, this._mainToAudioEventSab, parameterIds);\n      this._eventReader = new WamEventRingBuffer(RingBuffer, this._audioToMainEventSab, parameterIds);\n      const request = \"initialize/eventSab\";\n      const id = this._generateMessageId();\n      new Promise((resolve, reject) => {\n        this._pendingResponses[id] = resolve;\n        this.port.postMessage({\n          id,\n          request,\n          content: {\n            mainToAudioEventSab: this._mainToAudioEventSab,\n            audioToMainEventSab: this._audioToMainEventSab\n          }\n        });\n      }).then((resolved) => {\n        this._eventSabReady = true;\n        this._audioToMainInterval = setInterval(() => {\n          const events = this._eventReader.read();\n          events.forEach((e) => {\n            this._onEvent(e);\n          });\n        }, 100);\n      });\n    } else if (event)\n      this._onEvent(event);\n  }\n  _onEvent(event) {\n    const { type } = event;\n    this.dispatchEvent(new CustomEvent(type, {\n      bubbles: true,\n      detail: event\n    }));\n  }\n};\n\n// src/apiVersion.js\nvar apiVersion_default = \"2.0.0-alpha.4\";\n\n// src/initializeWamHost.js\nvar initializeWamHost = async (audioContext, hostGroupId = `wam-host-${performance.now().toString()}`, hostGroupKey = performance.now().toString()) => {\n  await addFunctionModule_default(audioContext.audioWorklet, WamEnv_default, apiVersion_default);\n  await addFunctionModule_default(audioContext.audioWorklet, WamGroup_default, hostGroupId, hostGroupKey);\n  return [hostGroupId, hostGroupKey];\n};\nvar initializeWamHost_default = initializeWamHost;\n\n//# sourceMappingURL=index.js.map\n\n\n//# sourceURL=webpack://pianoroll/../../../node_modules/@webaudiomodules/sdk/dist/index.js?");

/***/ })

/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/ 
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ 	// Check if module is in cache
/******/ 	var cachedModule = __webpack_module_cache__[moduleId];
/******/ 	if (cachedModule !== undefined) {
/******/ 		return cachedModule.exports;
/******/ 	}
/******/ 	// Create a new module (and put it into the cache)
/******/ 	var module = __webpack_module_cache__[moduleId] = {
/******/ 		id: moduleId,
/******/ 		// no module.loaded needed
/******/ 		exports: {}
/******/ 	};
/******/ 
/******/ 	// Execute the module function
/******/ 	__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 
/******/ 	// Return the exports of the module
/******/ 	return module.exports;
/******/ }
/******/ 
/************************************************************************/
/******/ /* webpack/runtime/compat get default export */
/******/ (() => {
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = (module) => {
/******/ 		var getter = module && module.__esModule ?
/******/ 			() => (module['default']) :
/******/ 			() => (module);
/******/ 		__webpack_require__.d(getter, { a: getter });
/******/ 		return getter;
/******/ 	};
/******/ })();
/******/ 
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ 	// define getter functions for harmony exports
/******/ 	__webpack_require__.d = (exports, definition) => {
/******/ 		for(var key in definition) {
/******/ 			if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ 				Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ 			}
/******/ 		}
/******/ 	};
/******/ })();
/******/ 
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ 	__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/ 
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = (exports) => {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/ })();
/******/ 
/******/ /* webpack/runtime/publicPath */
/******/ (() => {
/******/ 	var scriptUrl;
/******/ 	if (typeof import.meta.url === "string") scriptUrl = import.meta.url
/******/ 	// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration
/******/ 	// or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic.
/******/ 	if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");
/******/ 	scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/");
/******/ 	__webpack_require__.p = scriptUrl;
/******/ })();
/******/ 
/************************************************************************/
/******/ 
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module can't be inlined because the eval devtool is used.
/******/ var __webpack_exports__ = __webpack_require__("./src/index.tsx");
/******/ var __webpack_exports__default = __webpack_exports__["default"];
/******/ export { __webpack_exports__default as default };
/******/