diff --git a/assets/example_patches/808/cmaj_808.js b/assets/example_patches/808/cmaj_808.js index 78d3df94..b4a59443 100644 --- a/assets/example_patches/808/cmaj_808.js +++ b/assets/example_patches/808/cmaj_808.js @@ -3,7 +3,7 @@ // This file contains a Javascript/Webassembly/WebAudio export of the Cmajor // patch '808.cmajorpatch'. // -// This file was auto-generated by the Cmajor toolkit v1.0.2632 +// This file was auto-generated by the Cmajor toolkit v1.0.2633 // // To use it, import this module into your HTML/Javascript code and call // `createAudioWorkletNodePatchConnection()`. The AudioWorkletPatchConnection diff --git a/assets/example_patches/CompuFart/cmaj_CompuFart.js b/assets/example_patches/CompuFart/cmaj_CompuFart.js index 5fd43ffb..e1c68881 100644 --- a/assets/example_patches/CompuFart/cmaj_CompuFart.js +++ b/assets/example_patches/CompuFart/cmaj_CompuFart.js @@ -3,7 +3,7 @@ // This file contains a Javascript/Webassembly/WebAudio export of the Cmajor // patch 'CompuFartSynth.cmajorpatch'. // -// This file was auto-generated by the Cmajor toolkit v1.0.2632 +// This file was auto-generated by the Cmajor toolkit v1.0.2633 // // To use it, import this module into your HTML/Javascript code and call // `createAudioWorkletNodePatchConnection()`. The AudioWorkletPatchConnection diff --git a/assets/example_patches/ElectricPiano/cmaj_Electric_Piano.js b/assets/example_patches/ElectricPiano/cmaj_Electric_Piano.js index ad7b61dd..e66d01ed 100644 --- a/assets/example_patches/ElectricPiano/cmaj_Electric_Piano.js +++ b/assets/example_patches/ElectricPiano/cmaj_Electric_Piano.js @@ -3,7 +3,7 @@ // This file contains a Javascript/Webassembly/WebAudio export of the Cmajor // patch 'ElectricPiano.cmajorpatch'. // -// This file was auto-generated by the Cmajor toolkit v1.0.2632 +// This file was auto-generated by the Cmajor toolkit v1.0.2633 // // To use it, import this module into your HTML/Javascript code and call // `createAudioWorkletNodePatchConnection()`. The AudioWorkletPatchConnection diff --git a/assets/example_patches/GuitarLSTM/cmaj_GuitarLSTM.js b/assets/example_patches/GuitarLSTM/cmaj_GuitarLSTM.js index d8fb0238..39960cfd 100644 --- a/assets/example_patches/GuitarLSTM/cmaj_GuitarLSTM.js +++ b/assets/example_patches/GuitarLSTM/cmaj_GuitarLSTM.js @@ -3,7 +3,7 @@ // This file contains a Javascript/Webassembly/WebAudio export of the Cmajor // patch 'GuitarLSTM.cmajorpatch'. // -// This file was auto-generated by the Cmajor toolkit v1.0.2632 +// This file was auto-generated by the Cmajor toolkit v1.0.2633 // // To use it, import this module into your HTML/Javascript code and call // `createAudioWorkletNodePatchConnection()`. The AudioWorkletPatchConnection diff --git a/assets/example_patches/HelloWorld/cmaj_Hello_World.js b/assets/example_patches/HelloWorld/cmaj_Hello_World.js index 40029e1f..fa1cffcf 100644 --- a/assets/example_patches/HelloWorld/cmaj_Hello_World.js +++ b/assets/example_patches/HelloWorld/cmaj_Hello_World.js @@ -3,7 +3,7 @@ // This file contains a Javascript/Webassembly/WebAudio export of the Cmajor // patch 'HelloWorld.cmajorpatch'. // -// This file was auto-generated by the Cmajor toolkit v1.0.2632 +// This file was auto-generated by the Cmajor toolkit v1.0.2633 // // To use it, import this module into your HTML/Javascript code and call // `createAudioWorkletNodePatchConnection()`. The AudioWorkletPatchConnection diff --git a/assets/example_patches/Piano/cmaj_Piano.js b/assets/example_patches/Piano/cmaj_Piano.js index c0cbadd2..d6eabf7d 100644 --- a/assets/example_patches/Piano/cmaj_Piano.js +++ b/assets/example_patches/Piano/cmaj_Piano.js @@ -3,7 +3,7 @@ // This file contains a Javascript/Webassembly/WebAudio export of the Cmajor // patch 'Piano.cmajorpatch'. // -// This file was auto-generated by the Cmajor toolkit v1.0.2632 +// This file was auto-generated by the Cmajor toolkit v1.0.2633 // // To use it, import this module into your HTML/Javascript code and call // `createAudioWorkletNodePatchConnection()`. The AudioWorkletPatchConnection diff --git a/assets/example_patches/PirkleFilters/cmaj_vafilters.js b/assets/example_patches/PirkleFilters/cmaj_vafilters.js index 8eb13941..ea417d66 100644 --- a/assets/example_patches/PirkleFilters/cmaj_vafilters.js +++ b/assets/example_patches/PirkleFilters/cmaj_vafilters.js @@ -3,7 +3,7 @@ // This file contains a Javascript/Webassembly/WebAudio export of the Cmajor // patch 'vafilters.cmajorpatch'. // -// This file was auto-generated by the Cmajor toolkit v1.0.2632 +// This file was auto-generated by the Cmajor toolkit v1.0.2633 // // To use it, import this module into your HTML/Javascript code and call // `createAudioWorkletNodePatchConnection()`. The AudioWorkletPatchConnection diff --git a/assets/example_patches/Pro54/cmaj_Pro54.js b/assets/example_patches/Pro54/cmaj_Pro54.js index baeea885..69f61a09 100644 --- a/assets/example_patches/Pro54/cmaj_Pro54.js +++ b/assets/example_patches/Pro54/cmaj_Pro54.js @@ -3,7 +3,7 @@ // This file contains a Javascript/Webassembly/WebAudio export of the Cmajor // patch 'Pro54.cmajorpatch'. // -// This file was auto-generated by the Cmajor toolkit v1.0.2632 +// This file was auto-generated by the Cmajor toolkit v1.0.2633 // // To use it, import this module into your HTML/Javascript code and call // `createAudioWorkletNodePatchConnection()`. The AudioWorkletPatchConnection diff --git a/assets/example_patches/Replicant/cmaj_Replicant.js b/assets/example_patches/Replicant/cmaj_Replicant.js index b08ba874..cf85683e 100644 --- a/assets/example_patches/Replicant/cmaj_Replicant.js +++ b/assets/example_patches/Replicant/cmaj_Replicant.js @@ -3,7 +3,7 @@ // This file contains a Javascript/Webassembly/WebAudio export of the Cmajor // patch 'replicant.cmajorpatch'. // -// This file was auto-generated by the Cmajor toolkit v1.0.2632 +// This file was auto-generated by the Cmajor toolkit v1.0.2633 // // To use it, import this module into your HTML/Javascript code and call // `createAudioWorkletNodePatchConnection()`. The AudioWorkletPatchConnection diff --git a/assets/example_patches/RingMod/cmaj_Ring_Mod_Demo.js b/assets/example_patches/RingMod/cmaj_Ring_Mod_Demo.js index 09187139..5dc53345 100644 --- a/assets/example_patches/RingMod/cmaj_Ring_Mod_Demo.js +++ b/assets/example_patches/RingMod/cmaj_Ring_Mod_Demo.js @@ -3,7 +3,7 @@ // This file contains a Javascript/Webassembly/WebAudio export of the Cmajor // patch 'RingMod.cmajorpatch'. // -// This file was auto-generated by the Cmajor toolkit v1.0.2632 +// This file was auto-generated by the Cmajor toolkit v1.0.2633 // // To use it, import this module into your HTML/Javascript code and call // `createAudioWorkletNodePatchConnection()`. The AudioWorkletPatchConnection diff --git a/assets/example_patches/STunedBar6/cmaj_STunedBar6.js b/assets/example_patches/STunedBar6/cmaj_STunedBar6.js index 60116b7c..be1e9a95 100644 --- a/assets/example_patches/STunedBar6/cmaj_STunedBar6.js +++ b/assets/example_patches/STunedBar6/cmaj_STunedBar6.js @@ -3,7 +3,7 @@ // This file contains a Javascript/Webassembly/WebAudio export of the Cmajor // patch 'STunedBar6.cmajorpatch'. // -// This file was auto-generated by the Cmajor toolkit v1.0.2632 +// This file was auto-generated by the Cmajor toolkit v1.0.2633 // // To use it, import this module into your HTML/Javascript code and call // `createAudioWorkletNodePatchConnection()`. The AudioWorkletPatchConnection diff --git a/assets/example_patches/SubtractOne/README.md b/assets/example_patches/SubtractOne/README.md new file mode 100644 index 00000000..0d726a56 --- /dev/null +++ b/assets/example_patches/SubtractOne/README.md @@ -0,0 +1,23 @@ +### Auto-generated HTML & Javascript for Cmajor Patch "SubtractOne" + +This folder contains some self-contained HTML/Javascript files that play and show a Cmajor +patch using WebAssembly and WebAudio. + +For `index.html` to display correctly, this folder needs to be served as HTTP, so if you're +running it locally, you'll need to start a webserver that serves this folder, and then +point your browser at whatever URL your webserver provides. For example, you could run +`python3 -m http.server` in this folder, and then browse to the address it chooses. + +The files have all been generated using the Cmajor command-line tool: +``` +cmaj generate --target=webaudio --output= +``` + +- `index.html` is a minimal page that creates the javascript object that implements the patch, + connects it to the default audio and MIDI devices, and displays its view. +- `cmaj_SubtractOne.js` - this is the Javascript wrapper class for the patch, encapsulating its + DSP as webassembly, and providing an API that is used to both render the audio and + control its properties. +- `cmaj_api` - this folder contains javascript helper modules and resources. + +To learn more about Cmajor, visit [cmajor.dev](cmajor.dev) diff --git a/assets/example_patches/SubtractOne/cmaj_SubtractOne.js b/assets/example_patches/SubtractOne/cmaj_SubtractOne.js new file mode 100644 index 00000000..2637f098 --- /dev/null +++ b/assets/example_patches/SubtractOne/cmaj_SubtractOne.js @@ -0,0 +1,1659 @@ +//============================================================================== +// +// This file contains a Javascript/Webassembly/WebAudio export of the Cmajor +// patch 'SubtractOne.cmajorpatch'. +// +// This file was auto-generated by the Cmajor toolkit v1.0.2633 +// +// To use it, import this module into your HTML/Javascript code and call +// `createAudioWorkletNodePatchConnection()`. The AudioWorkletPatchConnection +// object that is returned is a PatchConnection with some extra functionality +// to let you connect it to web audio/MIDI. +// +// For more details about Cmajor, visit https://cmajor.dev +// +//============================================================================== + +import * as helpers from "./cmaj_api/cmaj-audio-worklet-helper.js" + + +//============================================================================== +/** This exports the patch's manifest, in case a caller needs to find out about its properties. + */ +export const manifest = +{ + "CmajorVersion": 1, + "pluginCode": "DEMO", + "ID": "com.your_name.your_patch_ID", + "version": "1.0", + "name": "SubtractOne", + "description": "SubtractOne", + "category": "generator", + "manufacturer": "Your Company Goes Here", + "isInstrument": true, + "source": "SubtractOne.cmajor", + "view": { + "src": "gui/stripped-build/index.js", + "width": 1024, + "height": 768, + "resizable": false + } +}; + +/** Returns the patch's output endpoint list */ +export function getOutputEndpoints() { return Voice.prototype.getOutputEndpoints(); } + +/** Returns the patch's input endpoint list */ +export function getInputEndpoints() { return Voice.prototype.getInputEndpoints(); } + +//============================================================================== +/** Creates an audio worklet node for the patch with the given name, attaches it + * to the audio context provided, and returns an object containing the node + * and a PatchConnection class to control it. + * + * @param {AudioContext} audioContext - a web audio AudioContext object + * @param {string} workletName - the name to give the new worklet that is created + * @returns {AudioWorkletPatchConnection} an AudioWorkletPatchConnection which has been initialised + */ +export async function createAudioWorkletNodePatchConnection (audioContext, workletName) +{ + const connection = new helpers.AudioWorkletPatchConnection (manifest); + + await connection.initialise ({ CmajorClass: Voice, + audioContext, + workletName, + hostDescription: "WebAudio" }); + return connection; +} + +/*********************************************************************************** + * + * A Javascript/Webassembly implementation of the Cmajor processor 'Voice'. + * + * This class was auto-generated by the Cmajor toolkit. + * + * To use it, construct an instance of this class, and call `initialise()` to + * asynchronously prepare it for use. Once initialised, the class provides + * appropriate setter/getter methods for reading/writing data to its endpoints, + * and an `advance()` method to render the next block. + * + * This roughly mirrors functionality of the cmajor Performer API - see the + * C++ API classes and Cmajor docs for more information about how this is used. + */ +class Voice +{ + /** After constructing one of these objects, call its + * initialise() method to prepare it for use. + */ + constructor() + { + } + + //============================================================================== + /** Prepares this processor for use. + * + * @param {number} sessionID - A unique integer ID which will be used for `processor.session`. + * @param {number} frequency - The frequency in Hz that the processor will be expected to run at. + */ + async initialise (sessionID, frequency) + { + if (! ((sessionID ^ 0) > 1)) + throw new Error ("initialise() requires a valid non-zero session ID argument"); + + if (! (frequency > 1)) + throw new Error ("initialise() requires a valid frequency argument"); + + const isSIMDAvailable = WebAssembly.validate (new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,123,3,2,1,0,10,10,1,8,0,65,0,253,15,253,98,11])); + + if (isSIMDAvailable) + await this._initialiseInternalSIMD (sessionID, frequency); + else + await this._initialiseInternalNonSIMD (sessionID, frequency); + + return true; + } + + //============================================================================== + /** Advances the processor by a number of frames. + * + * Before calling `advance()` you should use the appropriate functions to + * push data and events into the processor's input endpoints. After calling + * `advance()` you can use its output endpoint access functions to read the + * results. + * + * @param {number} numFrames - An integer number of frames to advance. + * This must be greater than zero. + */ + advance (numFrames) + { + this._advanceInternal (numFrames); + } + + //============================================================================== + /** Returns an object which encapsulates the state of the patch at this point. + * The state can be restored by passing this object to `restoreState()`. + */ + getState() + { + return { memory: this.byteMemory.slice(0) }; + } + + /** Restores the patch to a state that was previously saved by a call to `getState()` + */ + restoreState (savedState) + { + if (savedState?.memory && savedState.memory?.length === this.byteMemory.length) + this.byteMemory.set (savedState.memory); + else + throw Error ("restoreState(): not a valid state object"); + } + + /** Returns a list of the output endpoints that this processor exposes. + * @returns {Array} + */ + getOutputEndpoints() + { + return [ + { + "endpointID": "out", + "endpointType": "stream", + "dataType": { + "type": "float32" + }, + "purpose": "audio out", + "numAudioChannels": 1 + }, + { + "endpointID": "snapshot", + "endpointType": "event", + "dataType": { + "type": "array", + "element": { + "type": "float32" + }, + "size": 992 + } + } + ]; + } + + /** Returns a list of the input endpoints that this processor exposes. + * @returns {Array} + */ + getInputEndpoints() + { + return [ + { + "endpointID": "midiIn", + "endpointType": "event", + "dataType": { + "type": "object", + "class": "Message", + "members": { + "message": { + "type": "int32" + } + } + }, + "purpose": "midi in" + }, + { + "endpointID": "power", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "Power", + "init": 1, + "boolean": true + }, + "purpose": "parameter" + }, + { + "endpointID": "masterGain", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "Master Gain", + "min": 0, + "max": 1, + "init": 1, + "step": 0.01 + }, + "purpose": "parameter" + }, + { + "endpointID": "masterOctave", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "Master Octave", + "min": -3, + "max": 3, + "init": 0, + "step": 1 + }, + "purpose": "parameter" + }, + { + "endpointID": "masterGlide", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "Master Glide", + "min": 0, + "max": 3, + "init": 0, + "step": 0.01 + }, + "purpose": "parameter" + }, + { + "endpointID": "vco1Semitones", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "VCO1 Semitones", + "min": -24, + "max": 24, + "init": 0, + "step": 1 + }, + "purpose": "parameter" + }, + { + "endpointID": "vco1Detune", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "VCO1 Detune", + "min": -50, + "max": 50, + "init": 0, + "step": 1 + }, + "purpose": "parameter" + }, + { + "endpointID": "vco1Level", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "VCO1 Level", + "min": 0, + "max": 1, + "init": 1, + "step": 0.001 + }, + "purpose": "parameter" + }, + { + "endpointID": "vco1Shape", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "VCO1 Shape", + "min": 0, + "max": 4, + "init": 3, + "text": "Sine|Triangle|Square|Ramp Up|Ramp Down" + }, + "purpose": "parameter" + }, + { + "endpointID": "vco2Semitones", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "VCO2 Semitones", + "min": -24, + "max": 24, + "init": 0, + "step": 1 + }, + "purpose": "parameter" + }, + { + "endpointID": "vco2Detune", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "VCO2 Detune", + "min": -50, + "max": 50, + "init": 0, + "step": 1 + }, + "purpose": "parameter" + }, + { + "endpointID": "vco2Level", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "VCO2 Level", + "min": 0, + "max": 1, + "init": 0, + "step": 0.001 + }, + "purpose": "parameter" + }, + { + "endpointID": "vco2Shape", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "VCO2 Shape", + "min": 0, + "max": 4, + "init": 3, + "text": "Sine|Triangle|Square|Ramp Up|Ramp Down" + }, + "purpose": "parameter" + }, + { + "endpointID": "vco3Semitones", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "VCO3 Semitones", + "min": -24, + "max": 24, + "init": 0, + "step": 1 + }, + "purpose": "parameter" + }, + { + "endpointID": "vco3Detune", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "VCO3 Detune", + "min": -50, + "max": 50, + "init": 0, + "step": 1 + }, + "purpose": "parameter" + }, + { + "endpointID": "vco3Level", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "VCO3 Level", + "min": 0, + "max": 1, + "init": 0, + "step": 0.001 + }, + "purpose": "parameter" + }, + { + "endpointID": "vco3Shape", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "VCO3 Shape", + "min": 0, + "max": 4, + "init": 3, + "text": "Sine|Triangle|Square|Ramp Up|Ramp Down" + }, + "purpose": "parameter" + }, + { + "endpointID": "filterCutoff", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "Filter Cutoff", + "min": 100, + "max": 20000, + "init": 1500, + "step": 1 + }, + "purpose": "parameter" + }, + { + "endpointID": "filterResonance", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "Filter Resonance", + "min": 0, + "max": 100, + "init": 1, + "step": 1 + }, + "purpose": "parameter" + }, + { + "endpointID": "filterEgInt", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "Filter Eg Int", + "min": -100, + "max": 100, + "init": 50, + "step": 1 + }, + "purpose": "parameter" + }, + { + "endpointID": "ampEgAttack", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "AmpEg Attack", + "min": 0, + "max": 10, + "init": 0.1, + "step": 0.01 + }, + "purpose": "parameter" + }, + { + "endpointID": "ampEgDecay", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "AmpEg Decay", + "min": 0, + "max": 10, + "init": 1, + "step": 0.01 + }, + "purpose": "parameter" + }, + { + "endpointID": "ampEgSustain", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "AmpEg Sustain", + "min": 0, + "max": 100, + "init": 100, + "step": 1 + }, + "purpose": "parameter" + }, + { + "endpointID": "ampEgRelease", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "AmpEg Release", + "min": 0, + "max": 10, + "init": 2, + "step": 0.01 + }, + "purpose": "parameter" + }, + { + "endpointID": "filterEgAttack", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "FilterEg Attack", + "min": 0, + "max": 10, + "init": 0.1, + "step": 0.01 + }, + "purpose": "parameter" + }, + { + "endpointID": "filterEgDecay", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "FilterEg Decay", + "min": 0, + "max": 10, + "init": 1, + "step": 0.01 + }, + "purpose": "parameter" + }, + { + "endpointID": "filterEgSustain", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "FilterEg Sustain", + "min": 0, + "max": 100, + "init": 100, + "step": 1 + }, + "purpose": "parameter" + }, + { + "endpointID": "filterEgRelease", + "endpointType": "event", + "dataType": { + "type": "float32" + }, + "annotation": { + "name": "FilterEg Release", + "min": 0, + "max": 10, + "init": 2, + "step": 0.01 + }, + "purpose": "parameter" + } + ]; + } + + /** Sends an event of type `std::midi::Message` to endpoint "midiIn". + * @param {Object} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_midiIn (eventValue) + { + this._pack_o1_Message_message_i32 (this.scratchSpaceAddress, eventValue); + this.instance.exports._sendEvent_midiIn (this.stateAddress, this.scratchSpaceAddress); + } + + /** Sends an event of type `float32` to endpoint "power". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_power (eventValue) + { + this.instance.exports._sendEvent_power (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "masterGain". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_masterGain (eventValue) + { + this.instance.exports._sendEvent_masterGain (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "masterOctave". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_masterOctave (eventValue) + { + this.instance.exports._sendEvent_masterOctave (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "masterGlide". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_masterGlide (eventValue) + { + this.instance.exports._sendEvent_masterGlide (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "vco1Semitones". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_vco1Semitones (eventValue) + { + this.instance.exports._sendEvent_vco1Semitones (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "vco1Detune". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_vco1Detune (eventValue) + { + this.instance.exports._sendEvent_vco1Detune (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "vco1Level". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_vco1Level (eventValue) + { + this.instance.exports._sendEvent_vco1Level (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "vco1Shape". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_vco1Shape (eventValue) + { + this.instance.exports._sendEvent_vco1Shape (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "vco2Semitones". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_vco2Semitones (eventValue) + { + this.instance.exports._sendEvent_vco2Semitones (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "vco2Detune". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_vco2Detune (eventValue) + { + this.instance.exports._sendEvent_vco2Detune (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "vco2Level". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_vco2Level (eventValue) + { + this.instance.exports._sendEvent_vco2Level (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "vco2Shape". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_vco2Shape (eventValue) + { + this.instance.exports._sendEvent_vco2Shape (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "vco3Semitones". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_vco3Semitones (eventValue) + { + this.instance.exports._sendEvent_vco3Semitones (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "vco3Detune". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_vco3Detune (eventValue) + { + this.instance.exports._sendEvent_vco3Detune (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "vco3Level". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_vco3Level (eventValue) + { + this.instance.exports._sendEvent_vco3Level (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "vco3Shape". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_vco3Shape (eventValue) + { + this.instance.exports._sendEvent_vco3Shape (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "filterCutoff". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_filterCutoff (eventValue) + { + this.instance.exports._sendEvent_filterCutoff (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "filterResonance". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_filterResonance (eventValue) + { + this.instance.exports._sendEvent_filterResonance (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "filterEgInt". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_filterEgInt (eventValue) + { + this.instance.exports._sendEvent_filterEgInt (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "ampEgAttack". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_ampEgAttack (eventValue) + { + this.instance.exports._sendEvent_ampEgAttack (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "ampEgDecay". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_ampEgDecay (eventValue) + { + this.instance.exports._sendEvent_ampEgDecay (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "ampEgSustain". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_ampEgSustain (eventValue) + { + this.instance.exports._sendEvent_ampEgSustain (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "ampEgRelease". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_ampEgRelease (eventValue) + { + this.instance.exports._sendEvent_ampEgRelease (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "filterEgAttack". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_filterEgAttack (eventValue) + { + this.instance.exports._sendEvent_filterEgAttack (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "filterEgDecay". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_filterEgDecay (eventValue) + { + this.instance.exports._sendEvent_filterEgDecay (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "filterEgSustain". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_filterEgSustain (eventValue) + { + this.instance.exports._sendEvent_filterEgSustain (this.stateAddress, eventValue); + } + + /** Sends an event of type `float32` to endpoint "filterEgRelease". + * @param {number} eventValue - The event to be added to the queue for this endpoint. + */ + sendInputEvent_filterEgRelease (eventValue) + { + this.instance.exports._sendEvent_filterEgRelease (this.stateAddress, eventValue); + } + + /** Returns a frame from the output stream "out" + * + * @param {number} frameIndex - the index of the frame to fetch + */ + getOutputFrame_out (frameIndex) + { + return this._getOutputFrameInternal_out (frameIndex); + } + + /** Copies frames from the output stream "out" into a destination array. + * + * @param {Array} destChannelArrays - An array of arrays (one per channel) into + * which the samples will be copied + * @param {number} maxNumFramesToRead - The maximum number of frames to copy + * @param {number} destChannel - The channel to start writing from + */ + getOutputFrames_out (destChannelArrays, maxNumFramesToRead, destChannel) + { + this._getOutputFramesInternal_out (destChannelArrays, maxNumFramesToRead, destChannel); + } + + /** Returns the number of events available for endpoint "snapshot" */ + getOutputEventCount_snapshot() + { + return this._unpackEventCountInternal_snapshot(); + } + + /** Resets the FIFO for event endpoint "snapshot" */ + resetOutputEventCount_snapshot() + { + this._resetEventCountInternal_snapshot(); + } + + /** Returns one of the events from the FIFO for endpoint "snapshot" + * @param {number} index - The index of the event to return + */ + getOutputEvent_snapshot (index) + { + return this._readEventInternal_snapshot (index); + } + + //============================================================================== + // Code beyond this point is private internal implementation detail + + //============================================================================== + /** @access private */ + async _initialiseInternalSIMD (sessionID, frequency) + { + this.stateAddress = 86064; + this.scratchSpaceAddress = 219904; + + const memory = new WebAssembly.Memory ({ initial: 5 }); + const stack = new WebAssembly.Global ({ value: "i32", mutable: true }, 86064); + const imports = { + env: { + __linear_memory: memory, + __memory_base: 0, + __stack_pointer: stack, + __table_base: 0, + memcpy: (dst, src, len) => { this.byteMemory.copyWithin (dst, src, src + len); return dst; }, + memmove: (dst, src, len) => { this.byteMemory.copyWithin (dst, src, src + len); return dst; }, + memset: (dst, value, len) => { this.byteMemory.fill (value, dst, dst + len); return dst; } + }, + }; + + const result = await WebAssembly.instantiate (this._getWasmBytesSIMD(), imports); + this.instance = result.instance; + const exports = this.instance.exports; + const memoryBuffer = exports.memory?.buffer || memory.buffer; + const memoryDataView = new DataView (memoryBuffer); + const byteMemory = new Uint8Array (memoryBuffer); + this.byteMemory = byteMemory; + this.memoryDataView = memoryDataView; + + exports.initialise?.(this.stateAddress, this.scratchSpaceAddress, sessionID, frequency); + + const advanceFn = exports.advanceBlock ? ((numFrames) => exports.advanceBlock (86064, 217856, numFrames)) + : (() => exports.advanceOneFrame (86064, 217856)); + + this.reset = () => { + byteMemory.fill (0, 86064, 217856); + byteMemory.fill (0, 219904, 219904 + 4); + exports.initialise?.(this.stateAddress, this.scratchSpaceAddress, sessionID, frequency); + }; + + this._advanceInternal = (numFrames) => { + byteMemory.fill (0, 217856, 217856 + numFrames * 4); + advanceFn (numFrames); + }; + + this._getOutputFrameInternal_out = (frameIndex) => { return memoryDataView.getFloat32 (217856 + frameIndex * 4, true); }; + + this._getOutputFramesInternal_out = (destChannelArrays, maxNumFramesToRead, destChannel) => { + if (maxNumFramesToRead > 512) + maxNumFramesToRead = 512; + + const channelsToCopy = Math.min (1, destChannelArrays.length - destChannel); + let source = 217856; + + for (let frame = 0; frame < maxNumFramesToRead; ++frame) + { + for (let channel = 0; channel < channelsToCopy; ++channel) + destChannelArrays[destChannel + channel][frame] = memoryDataView.getFloat32 (source + 4 * channel, true); + + source += 4; + } + }; + + this._unpackEventCountInternal_snapshot = () => { return memoryDataView.getInt32 (90608, true); }; + this._resetEventCountInternal_snapshot = () => { memoryDataView.setInt32 (90608, 0, true); }; + + this._readEventInternal_snapshot = (index) => { + const eventAddress = 90612 + (3976 * index); + const frame = memoryDataView.getInt32 (eventAddress, true); + return { frame, typeIndex: 0, event: this._unpack_a992_f32 (eventAddress + 8) }; + }; + + this._pack_o1_Message_message_i32 = (address, newValue) => { + memoryDataView.setInt32 (address, newValue.message, true); + }; + + this._unpack_a992_f32 = (address) => { + return [memoryDataView.getFloat32 (address, true), memoryDataView.getFloat32 (address + 4, true), memoryDataView.getFloat32 (address + 8, true), memoryDataView.getFloat32 (address + 12, true), memoryDataView.getFloat32 (address + 16, true), memoryDataView.getFloat32 (address + 20, true), memoryDataView.getFloat32 (address + 24, true), memoryDataView.getFloat32 (address + 28, true), memoryDataView.getFloat32 (address + 32, true), memoryDataView.getFloat32 (address + 36, true), memoryDataView.getFloat32 (address + 40, true), memoryDataView.getFloat32 (address + 44, true), memoryDataView.getFloat32 (address + 48, true), memoryDataView.getFloat32 (address + 52, true), memoryDataView.getFloat32 (address + 56, true), memoryDataView.getFloat32 (address + 60, true), memoryDataView.getFloat32 (address + 64, true), memoryDataView.getFloat32 (address + 68, true), memoryDataView.getFloat32 (address + 72, true), memoryDataView.getFloat32 (address + 76, true), memoryDataView.getFloat32 (address + 80, true), memoryDataView.getFloat32 (address + 84, true), memoryDataView.getFloat32 (address + 88, true), memoryDataView.getFloat32 (address + 92, true), memoryDataView.getFloat32 (address + 96, true), memoryDataView.getFloat32 (address + 100, true), memoryDataView.getFloat32 (address + 104, true), memoryDataView.getFloat32 (address + 108, true), memoryDataView.getFloat32 (address + 112, true), memoryDataView.getFloat32 (address + 116, true), memoryDataView.getFloat32 (address + 120, true), memoryDataView.getFloat32 (address + 124, true), memoryDataView.getFloat32 (address + 128, true), memoryDataView.getFloat32 (address + 132, true), memoryDataView.getFloat32 (address + 136, true), memoryDataView.getFloat32 (address + 140, true), memoryDataView.getFloat32 (address + 144, true), memoryDataView.getFloat32 (address + 148, true), memoryDataView.getFloat32 (address + 152, true), memoryDataView.getFloat32 (address + 156, true), memoryDataView.getFloat32 (address + 160, true), memoryDataView.getFloat32 (address + 164, true), memoryDataView.getFloat32 (address + 168, true), memoryDataView.getFloat32 (address + 172, true), memoryDataView.getFloat32 (address + 176, true), memoryDataView.getFloat32 (address + 180, true), memoryDataView.getFloat32 (address + 184, true), memoryDataView.getFloat32 (address + 188, true), memoryDataView.getFloat32 (address + 192, true), memoryDataView.getFloat32 (address + 196, true), memoryDataView.getFloat32 (address + 200, true), memoryDataView.getFloat32 (address + 204, true), memoryDataView.getFloat32 (address + 208, true), memoryDataView.getFloat32 (address + 212, true), memoryDataView.getFloat32 (address + 216, true), memoryDataView.getFloat32 (address + 220, true), memoryDataView.getFloat32 (address + 224, true), memoryDataView.getFloat32 (address + 228, true), memoryDataView.getFloat32 (address + 232, true), memoryDataView.getFloat32 (address + 236, true), memoryDataView.getFloat32 (address + 240, true), memoryDataView.getFloat32 (address + 244, true), memoryDataView.getFloat32 (address + 248, true), memoryDataView.getFloat32 (address + 252, true), memoryDataView.getFloat32 (address + 256, true), memoryDataView.getFloat32 (address + 260, true), memoryDataView.getFloat32 (address + 264, true), memoryDataView.getFloat32 (address + 268, true), memoryDataView.getFloat32 (address + 272, true), memoryDataView.getFloat32 (address + 276, true), memoryDataView.getFloat32 (address + 280, true), memoryDataView.getFloat32 (address + 284, true), memoryDataView.getFloat32 (address + 288, true), memoryDataView.getFloat32 (address + 292, true), memoryDataView.getFloat32 (address + 296, true), memoryDataView.getFloat32 (address + 300, true), memoryDataView.getFloat32 (address + 304, true), memoryDataView.getFloat32 (address + 308, true), memoryDataView.getFloat32 (address + 312, true), memoryDataView.getFloat32 (address + 316, true), memoryDataView.getFloat32 (address + 320, true), memoryDataView.getFloat32 (address + 324, true), memoryDataView.getFloat32 (address + 328, true), memoryDataView.getFloat32 (address + 332, true), memoryDataView.getFloat32 (address + 336, true), memoryDataView.getFloat32 (address + 340, true), memoryDataView.getFloat32 (address + 344, true), memoryDataView.getFloat32 (address + 348, true), memoryDataView.getFloat32 (address + 352, true), memoryDataView.getFloat32 (address + 356, true), memoryDataView.getFloat32 (address + 360, true), memoryDataView.getFloat32 (address + 364, true), memoryDataView.getFloat32 (address + 368, true), memoryDataView.getFloat32 (address + 372, true), memoryDataView.getFloat32 (address + 376, true), memoryDataView.getFloat32 (address + 380, true), memoryDataView.getFloat32 (address + 384, true), memoryDataView.getFloat32 (address + 388, true), memoryDataView.getFloat32 (address + 392, true), memoryDataView.getFloat32 (address + 396, true), memoryDataView.getFloat32 (address + 400, true), memoryDataView.getFloat32 (address + 404, true), memoryDataView.getFloat32 (address + 408, true), memoryDataView.getFloat32 (address + 412, true), memoryDataView.getFloat32 (address + 416, true), memoryDataView.getFloat32 (address + 420, true), memoryDataView.getFloat32 (address + 424, true), memoryDataView.getFloat32 (address + 428, true), memoryDataView.getFloat32 (address + 432, true), memoryDataView.getFloat32 (address + 436, true), memoryDataView.getFloat32 (address + 440, true), memoryDataView.getFloat32 (address + 444, true), memoryDataView.getFloat32 (address + 448, true), memoryDataView.getFloat32 (address + 452, true), memoryDataView.getFloat32 (address + 456, true), memoryDataView.getFloat32 (address + 460, true), memoryDataView.getFloat32 (address + 464, true), memoryDataView.getFloat32 (address + 468, true), memoryDataView.getFloat32 (address + 472, true), memoryDataView.getFloat32 (address + 476, true), memoryDataView.getFloat32 (address + 480, true), memoryDataView.getFloat32 (address + 484, true), memoryDataView.getFloat32 (address + 488, true), memoryDataView.getFloat32 (address + 492, true), memoryDataView.getFloat32 (address + 496, true), memoryDataView.getFloat32 (address + 500, true), memoryDataView.getFloat32 (address + 504, true), memoryDataView.getFloat32 (address + 508, true), memoryDataView.getFloat32 (address + 512, true), memoryDataView.getFloat32 (address + 516, true), memoryDataView.getFloat32 (address + 520, true), memoryDataView.getFloat32 (address + 524, true), memoryDataView.getFloat32 (address + 528, true), memoryDataView.getFloat32 (address + 532, true), memoryDataView.getFloat32 (address + 536, true), memoryDataView.getFloat32 (address + 540, true), memoryDataView.getFloat32 (address + 544, true), memoryDataView.getFloat32 (address + 548, true), memoryDataView.getFloat32 (address + 552, true), memoryDataView.getFloat32 (address + 556, true), memoryDataView.getFloat32 (address + 560, true), memoryDataView.getFloat32 (address + 564, true), memoryDataView.getFloat32 (address + 568, true), memoryDataView.getFloat32 (address + 572, true), memoryDataView.getFloat32 (address + 576, true), memoryDataView.getFloat32 (address + 580, true), memoryDataView.getFloat32 (address + 584, true), memoryDataView.getFloat32 (address + 588, true), memoryDataView.getFloat32 (address + 592, true), memoryDataView.getFloat32 (address + 596, true), memoryDataView.getFloat32 (address + 600, true), memoryDataView.getFloat32 (address + 604, true), memoryDataView.getFloat32 (address + 608, true), memoryDataView.getFloat32 (address + 612, true), memoryDataView.getFloat32 (address + 616, true), memoryDataView.getFloat32 (address + 620, true), memoryDataView.getFloat32 (address + 624, true), memoryDataView.getFloat32 (address + 628, true), memoryDataView.getFloat32 (address + 632, true), memoryDataView.getFloat32 (address + 636, true), memoryDataView.getFloat32 (address + 640, true), memoryDataView.getFloat32 (address + 644, true), memoryDataView.getFloat32 (address + 648, true), memoryDataView.getFloat32 (address + 652, true), memoryDataView.getFloat32 (address + 656, true), memoryDataView.getFloat32 (address + 660, true), memoryDataView.getFloat32 (address + 664, true), memoryDataView.getFloat32 (address + 668, true), memoryDataView.getFloat32 (address + 672, true), memoryDataView.getFloat32 (address + 676, true), memoryDataView.getFloat32 (address + 680, true), memoryDataView.getFloat32 (address + 684, true), memoryDataView.getFloat32 (address + 688, true), memoryDataView.getFloat32 (address + 692, true), memoryDataView.getFloat32 (address + 696, true), memoryDataView.getFloat32 (address + 700, true), memoryDataView.getFloat32 (address + 704, true), memoryDataView.getFloat32 (address + 708, true), memoryDataView.getFloat32 (address + 712, true), memoryDataView.getFloat32 (address + 716, true), memoryDataView.getFloat32 (address + 720, true), memoryDataView.getFloat32 (address + 724, true), memoryDataView.getFloat32 (address + 728, true), memoryDataView.getFloat32 (address + 732, true), memoryDataView.getFloat32 (address + 736, true), memoryDataView.getFloat32 (address + 740, true), memoryDataView.getFloat32 (address + 744, true), memoryDataView.getFloat32 (address + 748, true), memoryDataView.getFloat32 (address + 752, true), memoryDataView.getFloat32 (address + 756, true), memoryDataView.getFloat32 (address + 760, true), memoryDataView.getFloat32 (address + 764, true), memoryDataView.getFloat32 (address + 768, true), memoryDataView.getFloat32 (address + 772, true), memoryDataView.getFloat32 (address + 776, true), memoryDataView.getFloat32 (address + 780, true), memoryDataView.getFloat32 (address + 784, true), memoryDataView.getFloat32 (address + 788, true), memoryDataView.getFloat32 (address + 792, true), memoryDataView.getFloat32 (address + 796, true), memoryDataView.getFloat32 (address + 800, true), memoryDataView.getFloat32 (address + 804, true), memoryDataView.getFloat32 (address + 808, true), memoryDataView.getFloat32 (address + 812, true), memoryDataView.getFloat32 (address + 816, true), memoryDataView.getFloat32 (address + 820, true), memoryDataView.getFloat32 (address + 824, true), memoryDataView.getFloat32 (address + 828, true), memoryDataView.getFloat32 (address + 832, true), memoryDataView.getFloat32 (address + 836, true), memoryDataView.getFloat32 (address + 840, true), memoryDataView.getFloat32 (address + 844, true), memoryDataView.getFloat32 (address + 848, true), memoryDataView.getFloat32 (address + 852, true), memoryDataView.getFloat32 (address + 856, true), memoryDataView.getFloat32 (address + 860, true), memoryDataView.getFloat32 (address + 864, true), memoryDataView.getFloat32 (address + 868, true), memoryDataView.getFloat32 (address + 872, true), memoryDataView.getFloat32 (address + 876, true), memoryDataView.getFloat32 (address + 880, true), memoryDataView.getFloat32 (address + 884, true), memoryDataView.getFloat32 (address + 888, true), memoryDataView.getFloat32 (address + 892, true), memoryDataView.getFloat32 (address + 896, true), memoryDataView.getFloat32 (address + 900, true), memoryDataView.getFloat32 (address + 904, true), memoryDataView.getFloat32 (address + 908, true), memoryDataView.getFloat32 (address + 912, true), memoryDataView.getFloat32 (address + 916, true), memoryDataView.getFloat32 (address + 920, true), memoryDataView.getFloat32 (address + 924, true), memoryDataView.getFloat32 (address + 928, true), memoryDataView.getFloat32 (address + 932, true), memoryDataView.getFloat32 (address + 936, true), memoryDataView.getFloat32 (address + 940, true), memoryDataView.getFloat32 (address + 944, true), memoryDataView.getFloat32 (address + 948, true), memoryDataView.getFloat32 (address + 952, true), memoryDataView.getFloat32 (address + 956, true), memoryDataView.getFloat32 (address + 960, true), memoryDataView.getFloat32 (address + 964, true), memoryDataView.getFloat32 (address + 968, true), memoryDataView.getFloat32 (address + 972, true), memoryDataView.getFloat32 (address + 976, true), memoryDataView.getFloat32 (address + 980, true), memoryDataView.getFloat32 (address + 984, true), memoryDataView.getFloat32 (address + 988, true), memoryDataView.getFloat32 (address + 992, true), memoryDataView.getFloat32 (address + 996, true), memoryDataView.getFloat32 (address + 1000, true), memoryDataView.getFloat32 (address + 1004, true), memoryDataView.getFloat32 (address + 1008, true), memoryDataView.getFloat32 (address + 1012, true), memoryDataView.getFloat32 (address + 1016, true), memoryDataView.getFloat32 (address + 1020, true), memoryDataView.getFloat32 (address + 1024, true), memoryDataView.getFloat32 (address + 1028, true), memoryDataView.getFloat32 (address + 1032, true), memoryDataView.getFloat32 (address + 1036, true), memoryDataView.getFloat32 (address + 1040, true), memoryDataView.getFloat32 (address + 1044, true), memoryDataView.getFloat32 (address + 1048, true), memoryDataView.getFloat32 (address + 1052, true), memoryDataView.getFloat32 (address + 1056, true), memoryDataView.getFloat32 (address + 1060, true), memoryDataView.getFloat32 (address + 1064, true), memoryDataView.getFloat32 (address + 1068, true), memoryDataView.getFloat32 (address + 1072, true), memoryDataView.getFloat32 (address + 1076, true), memoryDataView.getFloat32 (address + 1080, true), memoryDataView.getFloat32 (address + 1084, true), memoryDataView.getFloat32 (address + 1088, true), memoryDataView.getFloat32 (address + 1092, true), memoryDataView.getFloat32 (address + 1096, true), memoryDataView.getFloat32 (address + 1100, true), memoryDataView.getFloat32 (address + 1104, true), memoryDataView.getFloat32 (address + 1108, true), memoryDataView.getFloat32 (address + 1112, true), memoryDataView.getFloat32 (address + 1116, true), memoryDataView.getFloat32 (address + 1120, true), memoryDataView.getFloat32 (address + 1124, true), memoryDataView.getFloat32 (address + 1128, true), memoryDataView.getFloat32 (address + 1132, true), memoryDataView.getFloat32 (address + 1136, true), memoryDataView.getFloat32 (address + 1140, true), memoryDataView.getFloat32 (address + 1144, true), memoryDataView.getFloat32 (address + 1148, true), memoryDataView.getFloat32 (address + 1152, true), memoryDataView.getFloat32 (address + 1156, true), memoryDataView.getFloat32 (address + 1160, true), memoryDataView.getFloat32 (address + 1164, true), memoryDataView.getFloat32 (address + 1168, true), memoryDataView.getFloat32 (address + 1172, true), memoryDataView.getFloat32 (address + 1176, true), memoryDataView.getFloat32 (address + 1180, true), memoryDataView.getFloat32 (address + 1184, true), memoryDataView.getFloat32 (address + 1188, true), memoryDataView.getFloat32 (address + 1192, true), memoryDataView.getFloat32 (address + 1196, true), memoryDataView.getFloat32 (address + 1200, true), memoryDataView.getFloat32 (address + 1204, true), memoryDataView.getFloat32 (address + 1208, true), memoryDataView.getFloat32 (address + 1212, true), memoryDataView.getFloat32 (address + 1216, true), memoryDataView.getFloat32 (address + 1220, true), memoryDataView.getFloat32 (address + 1224, true), memoryDataView.getFloat32 (address + 1228, true), memoryDataView.getFloat32 (address + 1232, true), memoryDataView.getFloat32 (address + 1236, true), memoryDataView.getFloat32 (address + 1240, true), memoryDataView.getFloat32 (address + 1244, true), memoryDataView.getFloat32 (address + 1248, true), memoryDataView.getFloat32 (address + 1252, true), memoryDataView.getFloat32 (address + 1256, true), memoryDataView.getFloat32 (address + 1260, true), memoryDataView.getFloat32 (address + 1264, true), memoryDataView.getFloat32 (address + 1268, true), memoryDataView.getFloat32 (address + 1272, true), memoryDataView.getFloat32 (address + 1276, true), memoryDataView.getFloat32 (address + 1280, true), memoryDataView.getFloat32 (address + 1284, true), memoryDataView.getFloat32 (address + 1288, true), memoryDataView.getFloat32 (address + 1292, true), memoryDataView.getFloat32 (address + 1296, true), memoryDataView.getFloat32 (address + 1300, true), memoryDataView.getFloat32 (address + 1304, true), memoryDataView.getFloat32 (address + 1308, true), memoryDataView.getFloat32 (address + 1312, true), memoryDataView.getFloat32 (address + 1316, true), memoryDataView.getFloat32 (address + 1320, true), memoryDataView.getFloat32 (address + 1324, true), memoryDataView.getFloat32 (address + 1328, true), memoryDataView.getFloat32 (address + 1332, true), memoryDataView.getFloat32 (address + 1336, true), memoryDataView.getFloat32 (address + 1340, true), memoryDataView.getFloat32 (address + 1344, true), memoryDataView.getFloat32 (address + 1348, true), memoryDataView.getFloat32 (address + 1352, true), memoryDataView.getFloat32 (address + 1356, true), memoryDataView.getFloat32 (address + 1360, true), memoryDataView.getFloat32 (address + 1364, true), memoryDataView.getFloat32 (address + 1368, true), memoryDataView.getFloat32 (address + 1372, true), memoryDataView.getFloat32 (address + 1376, true), memoryDataView.getFloat32 (address + 1380, true), memoryDataView.getFloat32 (address + 1384, true), memoryDataView.getFloat32 (address + 1388, true), memoryDataView.getFloat32 (address + 1392, true), memoryDataView.getFloat32 (address + 1396, true), memoryDataView.getFloat32 (address + 1400, true), memoryDataView.getFloat32 (address + 1404, true), memoryDataView.getFloat32 (address + 1408, true), memoryDataView.getFloat32 (address + 1412, true), memoryDataView.getFloat32 (address + 1416, true), memoryDataView.getFloat32 (address + 1420, true), memoryDataView.getFloat32 (address + 1424, true), memoryDataView.getFloat32 (address + 1428, true), memoryDataView.getFloat32 (address + 1432, true), memoryDataView.getFloat32 (address + 1436, true), memoryDataView.getFloat32 (address + 1440, true), memoryDataView.getFloat32 (address + 1444, true), memoryDataView.getFloat32 (address + 1448, true), memoryDataView.getFloat32 (address + 1452, true), memoryDataView.getFloat32 (address + 1456, true), memoryDataView.getFloat32 (address + 1460, true), memoryDataView.getFloat32 (address + 1464, true), memoryDataView.getFloat32 (address + 1468, true), memoryDataView.getFloat32 (address + 1472, true), memoryDataView.getFloat32 (address + 1476, true), memoryDataView.getFloat32 (address + 1480, true), memoryDataView.getFloat32 (address + 1484, true), memoryDataView.getFloat32 (address + 1488, true), memoryDataView.getFloat32 (address + 1492, true), memoryDataView.getFloat32 (address + 1496, true), memoryDataView.getFloat32 (address + 1500, true), memoryDataView.getFloat32 (address + 1504, true), memoryDataView.getFloat32 (address + 1508, true), memoryDataView.getFloat32 (address + 1512, true), memoryDataView.getFloat32 (address + 1516, true), memoryDataView.getFloat32 (address + 1520, true), memoryDataView.getFloat32 (address + 1524, true), memoryDataView.getFloat32 (address + 1528, true), memoryDataView.getFloat32 (address + 1532, true), memoryDataView.getFloat32 (address + 1536, true), memoryDataView.getFloat32 (address + 1540, true), memoryDataView.getFloat32 (address + 1544, true), memoryDataView.getFloat32 (address + 1548, true), memoryDataView.getFloat32 (address + 1552, true), memoryDataView.getFloat32 (address + 1556, true), memoryDataView.getFloat32 (address + 1560, true), memoryDataView.getFloat32 (address + 1564, true), memoryDataView.getFloat32 (address + 1568, true), memoryDataView.getFloat32 (address + 1572, true), memoryDataView.getFloat32 (address + 1576, true), memoryDataView.getFloat32 (address + 1580, true), memoryDataView.getFloat32 (address + 1584, true), memoryDataView.getFloat32 (address + 1588, true), memoryDataView.getFloat32 (address + 1592, true), memoryDataView.getFloat32 (address + 1596, true), memoryDataView.getFloat32 (address + 1600, true), memoryDataView.getFloat32 (address + 1604, true), memoryDataView.getFloat32 (address + 1608, true), memoryDataView.getFloat32 (address + 1612, true), memoryDataView.getFloat32 (address + 1616, true), memoryDataView.getFloat32 (address + 1620, true), memoryDataView.getFloat32 (address + 1624, true), memoryDataView.getFloat32 (address + 1628, true), memoryDataView.getFloat32 (address + 1632, true), memoryDataView.getFloat32 (address + 1636, true), memoryDataView.getFloat32 (address + 1640, true), memoryDataView.getFloat32 (address + 1644, true), memoryDataView.getFloat32 (address + 1648, true), memoryDataView.getFloat32 (address + 1652, true), memoryDataView.getFloat32 (address + 1656, true), memoryDataView.getFloat32 (address + 1660, true), memoryDataView.getFloat32 (address + 1664, true), memoryDataView.getFloat32 (address + 1668, true), memoryDataView.getFloat32 (address + 1672, true), memoryDataView.getFloat32 (address + 1676, true), memoryDataView.getFloat32 (address + 1680, true), memoryDataView.getFloat32 (address + 1684, true), memoryDataView.getFloat32 (address + 1688, true), memoryDataView.getFloat32 (address + 1692, true), memoryDataView.getFloat32 (address + 1696, true), memoryDataView.getFloat32 (address + 1700, true), memoryDataView.getFloat32 (address + 1704, true), memoryDataView.getFloat32 (address + 1708, true), memoryDataView.getFloat32 (address + 1712, true), memoryDataView.getFloat32 (address + 1716, true), memoryDataView.getFloat32 (address + 1720, true), memoryDataView.getFloat32 (address + 1724, true), memoryDataView.getFloat32 (address + 1728, true), memoryDataView.getFloat32 (address + 1732, true), memoryDataView.getFloat32 (address + 1736, true), memoryDataView.getFloat32 (address + 1740, true), memoryDataView.getFloat32 (address + 1744, true), memoryDataView.getFloat32 (address + 1748, true), memoryDataView.getFloat32 (address + 1752, true), memoryDataView.getFloat32 (address + 1756, true), memoryDataView.getFloat32 (address + 1760, true), memoryDataView.getFloat32 (address + 1764, true), memoryDataView.getFloat32 (address + 1768, true), memoryDataView.getFloat32 (address + 1772, true), memoryDataView.getFloat32 (address + 1776, true), memoryDataView.getFloat32 (address + 1780, true), memoryDataView.getFloat32 (address + 1784, true), memoryDataView.getFloat32 (address + 1788, true), memoryDataView.getFloat32 (address + 1792, true), memoryDataView.getFloat32 (address + 1796, true), memoryDataView.getFloat32 (address + 1800, true), memoryDataView.getFloat32 (address + 1804, true), memoryDataView.getFloat32 (address + 1808, true), memoryDataView.getFloat32 (address + 1812, true), memoryDataView.getFloat32 (address + 1816, true), memoryDataView.getFloat32 (address + 1820, true), memoryDataView.getFloat32 (address + 1824, true), memoryDataView.getFloat32 (address + 1828, true), memoryDataView.getFloat32 (address + 1832, true), memoryDataView.getFloat32 (address + 1836, true), memoryDataView.getFloat32 (address + 1840, true), memoryDataView.getFloat32 (address + 1844, true), memoryDataView.getFloat32 (address + 1848, true), memoryDataView.getFloat32 (address + 1852, true), memoryDataView.getFloat32 (address + 1856, true), memoryDataView.getFloat32 (address + 1860, true), memoryDataView.getFloat32 (address + 1864, true), memoryDataView.getFloat32 (address + 1868, true), memoryDataView.getFloat32 (address + 1872, true), memoryDataView.getFloat32 (address + 1876, true), memoryDataView.getFloat32 (address + 1880, true), memoryDataView.getFloat32 (address + 1884, true), memoryDataView.getFloat32 (address + 1888, true), memoryDataView.getFloat32 (address + 1892, true), memoryDataView.getFloat32 (address + 1896, true), memoryDataView.getFloat32 (address + 1900, true), memoryDataView.getFloat32 (address + 1904, true), memoryDataView.getFloat32 (address + 1908, true), memoryDataView.getFloat32 (address + 1912, true), memoryDataView.getFloat32 (address + 1916, true), memoryDataView.getFloat32 (address + 1920, true), memoryDataView.getFloat32 (address + 1924, true), memoryDataView.getFloat32 (address + 1928, true), memoryDataView.getFloat32 (address + 1932, true), memoryDataView.getFloat32 (address + 1936, true), memoryDataView.getFloat32 (address + 1940, true), memoryDataView.getFloat32 (address + 1944, true), memoryDataView.getFloat32 (address + 1948, true), memoryDataView.getFloat32 (address + 1952, true), memoryDataView.getFloat32 (address + 1956, true), memoryDataView.getFloat32 (address + 1960, true), memoryDataView.getFloat32 (address + 1964, true), memoryDataView.getFloat32 (address + 1968, true), memoryDataView.getFloat32 (address + 1972, true), memoryDataView.getFloat32 (address + 1976, true), memoryDataView.getFloat32 (address + 1980, true), memoryDataView.getFloat32 (address + 1984, true), memoryDataView.getFloat32 (address + 1988, true), memoryDataView.getFloat32 (address + 1992, true), memoryDataView.getFloat32 (address + 1996, true), memoryDataView.getFloat32 (address + 2000, true), memoryDataView.getFloat32 (address + 2004, true), memoryDataView.getFloat32 (address + 2008, true), memoryDataView.getFloat32 (address + 2012, true), memoryDataView.getFloat32 (address + 2016, true), memoryDataView.getFloat32 (address + 2020, true), memoryDataView.getFloat32 (address + 2024, true), memoryDataView.getFloat32 (address + 2028, true), memoryDataView.getFloat32 (address + 2032, true), memoryDataView.getFloat32 (address + 2036, true), memoryDataView.getFloat32 (address + 2040, true), memoryDataView.getFloat32 (address + 2044, true), memoryDataView.getFloat32 (address + 2048, true), memoryDataView.getFloat32 (address + 2052, true), memoryDataView.getFloat32 (address + 2056, true), memoryDataView.getFloat32 (address + 2060, true), memoryDataView.getFloat32 (address + 2064, true), memoryDataView.getFloat32 (address + 2068, true), memoryDataView.getFloat32 (address + 2072, true), memoryDataView.getFloat32 (address + 2076, true), memoryDataView.getFloat32 (address + 2080, true), memoryDataView.getFloat32 (address + 2084, true), memoryDataView.getFloat32 (address + 2088, true), memoryDataView.getFloat32 (address + 2092, true), memoryDataView.getFloat32 (address + 2096, true), memoryDataView.getFloat32 (address + 2100, true), memoryDataView.getFloat32 (address + 2104, true), memoryDataView.getFloat32 (address + 2108, true), memoryDataView.getFloat32 (address + 2112, true), memoryDataView.getFloat32 (address + 2116, true), memoryDataView.getFloat32 (address + 2120, true), memoryDataView.getFloat32 (address + 2124, true), memoryDataView.getFloat32 (address + 2128, true), memoryDataView.getFloat32 (address + 2132, true), memoryDataView.getFloat32 (address + 2136, true), memoryDataView.getFloat32 (address + 2140, true), memoryDataView.getFloat32 (address + 2144, true), memoryDataView.getFloat32 (address + 2148, true), memoryDataView.getFloat32 (address + 2152, true), memoryDataView.getFloat32 (address + 2156, true), memoryDataView.getFloat32 (address + 2160, true), memoryDataView.getFloat32 (address + 2164, true), memoryDataView.getFloat32 (address + 2168, true), memoryDataView.getFloat32 (address + 2172, true), memoryDataView.getFloat32 (address + 2176, true), memoryDataView.getFloat32 (address + 2180, true), memoryDataView.getFloat32 (address + 2184, true), memoryDataView.getFloat32 (address + 2188, true), memoryDataView.getFloat32 (address + 2192, true), memoryDataView.getFloat32 (address + 2196, true), memoryDataView.getFloat32 (address + 2200, true), memoryDataView.getFloat32 (address + 2204, true), memoryDataView.getFloat32 (address + 2208, true), memoryDataView.getFloat32 (address + 2212, true), memoryDataView.getFloat32 (address + 2216, true), memoryDataView.getFloat32 (address + 2220, true), memoryDataView.getFloat32 (address + 2224, true), memoryDataView.getFloat32 (address + 2228, true), memoryDataView.getFloat32 (address + 2232, true), memoryDataView.getFloat32 (address + 2236, true), memoryDataView.getFloat32 (address + 2240, true), memoryDataView.getFloat32 (address + 2244, true), memoryDataView.getFloat32 (address + 2248, true), memoryDataView.getFloat32 (address + 2252, true), memoryDataView.getFloat32 (address + 2256, true), memoryDataView.getFloat32 (address + 2260, true), memoryDataView.getFloat32 (address + 2264, true), memoryDataView.getFloat32 (address + 2268, true), memoryDataView.getFloat32 (address + 2272, true), memoryDataView.getFloat32 (address + 2276, true), memoryDataView.getFloat32 (address + 2280, true), memoryDataView.getFloat32 (address + 2284, true), memoryDataView.getFloat32 (address + 2288, true), memoryDataView.getFloat32 (address + 2292, true), memoryDataView.getFloat32 (address + 2296, true), memoryDataView.getFloat32 (address + 2300, true), memoryDataView.getFloat32 (address + 2304, true), memoryDataView.getFloat32 (address + 2308, true), memoryDataView.getFloat32 (address + 2312, true), memoryDataView.getFloat32 (address + 2316, true), memoryDataView.getFloat32 (address + 2320, true), memoryDataView.getFloat32 (address + 2324, true), memoryDataView.getFloat32 (address + 2328, true), memoryDataView.getFloat32 (address + 2332, true), memoryDataView.getFloat32 (address + 2336, true), memoryDataView.getFloat32 (address + 2340, true), memoryDataView.getFloat32 (address + 2344, true), memoryDataView.getFloat32 (address + 2348, true), memoryDataView.getFloat32 (address + 2352, true), memoryDataView.getFloat32 (address + 2356, true), memoryDataView.getFloat32 (address + 2360, true), memoryDataView.getFloat32 (address + 2364, true), memoryDataView.getFloat32 (address + 2368, true), memoryDataView.getFloat32 (address + 2372, true), memoryDataView.getFloat32 (address + 2376, true), memoryDataView.getFloat32 (address + 2380, true), memoryDataView.getFloat32 (address + 2384, true), memoryDataView.getFloat32 (address + 2388, true), memoryDataView.getFloat32 (address + 2392, true), memoryDataView.getFloat32 (address + 2396, true), memoryDataView.getFloat32 (address + 2400, true), memoryDataView.getFloat32 (address + 2404, true), memoryDataView.getFloat32 (address + 2408, true), memoryDataView.getFloat32 (address + 2412, true), memoryDataView.getFloat32 (address + 2416, true), memoryDataView.getFloat32 (address + 2420, true), memoryDataView.getFloat32 (address + 2424, true), memoryDataView.getFloat32 (address + 2428, true), memoryDataView.getFloat32 (address + 2432, true), memoryDataView.getFloat32 (address + 2436, true), memoryDataView.getFloat32 (address + 2440, true), memoryDataView.getFloat32 (address + 2444, true), memoryDataView.getFloat32 (address + 2448, true), memoryDataView.getFloat32 (address + 2452, true), memoryDataView.getFloat32 (address + 2456, true), memoryDataView.getFloat32 (address + 2460, true), memoryDataView.getFloat32 (address + 2464, true), memoryDataView.getFloat32 (address + 2468, true), memoryDataView.getFloat32 (address + 2472, true), memoryDataView.getFloat32 (address + 2476, true), memoryDataView.getFloat32 (address + 2480, true), memoryDataView.getFloat32 (address + 2484, true), memoryDataView.getFloat32 (address + 2488, true), memoryDataView.getFloat32 (address + 2492, true), memoryDataView.getFloat32 (address + 2496, true), memoryDataView.getFloat32 (address + 2500, true), memoryDataView.getFloat32 (address + 2504, true), memoryDataView.getFloat32 (address + 2508, true), memoryDataView.getFloat32 (address + 2512, true), memoryDataView.getFloat32 (address + 2516, true), memoryDataView.getFloat32 (address + 2520, true), memoryDataView.getFloat32 (address + 2524, true), memoryDataView.getFloat32 (address + 2528, true), memoryDataView.getFloat32 (address + 2532, true), memoryDataView.getFloat32 (address + 2536, true), memoryDataView.getFloat32 (address + 2540, true), memoryDataView.getFloat32 (address + 2544, true), memoryDataView.getFloat32 (address + 2548, true), memoryDataView.getFloat32 (address + 2552, true), memoryDataView.getFloat32 (address + 2556, true), memoryDataView.getFloat32 (address + 2560, true), memoryDataView.getFloat32 (address + 2564, true), memoryDataView.getFloat32 (address + 2568, true), memoryDataView.getFloat32 (address + 2572, true), memoryDataView.getFloat32 (address + 2576, true), memoryDataView.getFloat32 (address + 2580, true), memoryDataView.getFloat32 (address + 2584, true), memoryDataView.getFloat32 (address + 2588, true), memoryDataView.getFloat32 (address + 2592, true), memoryDataView.getFloat32 (address + 2596, true), memoryDataView.getFloat32 (address + 2600, true), memoryDataView.getFloat32 (address + 2604, true), memoryDataView.getFloat32 (address + 2608, true), memoryDataView.getFloat32 (address + 2612, true), memoryDataView.getFloat32 (address + 2616, true), memoryDataView.getFloat32 (address + 2620, true), memoryDataView.getFloat32 (address + 2624, true), memoryDataView.getFloat32 (address + 2628, true), memoryDataView.getFloat32 (address + 2632, true), memoryDataView.getFloat32 (address + 2636, true), memoryDataView.getFloat32 (address + 2640, true), memoryDataView.getFloat32 (address + 2644, true), memoryDataView.getFloat32 (address + 2648, true), memoryDataView.getFloat32 (address + 2652, true), memoryDataView.getFloat32 (address + 2656, true), memoryDataView.getFloat32 (address + 2660, true), memoryDataView.getFloat32 (address + 2664, true), memoryDataView.getFloat32 (address + 2668, true), memoryDataView.getFloat32 (address + 2672, true), memoryDataView.getFloat32 (address + 2676, true), memoryDataView.getFloat32 (address + 2680, true), memoryDataView.getFloat32 (address + 2684, true), memoryDataView.getFloat32 (address + 2688, true), memoryDataView.getFloat32 (address + 2692, true), memoryDataView.getFloat32 (address + 2696, true), memoryDataView.getFloat32 (address + 2700, true), memoryDataView.getFloat32 (address + 2704, true), memoryDataView.getFloat32 (address + 2708, true), memoryDataView.getFloat32 (address + 2712, true), memoryDataView.getFloat32 (address + 2716, true), memoryDataView.getFloat32 (address + 2720, true), memoryDataView.getFloat32 (address + 2724, true), memoryDataView.getFloat32 (address + 2728, true), memoryDataView.getFloat32 (address + 2732, true), memoryDataView.getFloat32 (address + 2736, true), memoryDataView.getFloat32 (address + 2740, true), memoryDataView.getFloat32 (address + 2744, true), memoryDataView.getFloat32 (address + 2748, true), memoryDataView.getFloat32 (address + 2752, true), memoryDataView.getFloat32 (address + 2756, true), memoryDataView.getFloat32 (address + 2760, true), memoryDataView.getFloat32 (address + 2764, true), memoryDataView.getFloat32 (address + 2768, true), memoryDataView.getFloat32 (address + 2772, true), memoryDataView.getFloat32 (address + 2776, true), memoryDataView.getFloat32 (address + 2780, true), memoryDataView.getFloat32 (address + 2784, true), memoryDataView.getFloat32 (address + 2788, true), memoryDataView.getFloat32 (address + 2792, true), memoryDataView.getFloat32 (address + 2796, true), memoryDataView.getFloat32 (address + 2800, true), memoryDataView.getFloat32 (address + 2804, true), memoryDataView.getFloat32 (address + 2808, true), memoryDataView.getFloat32 (address + 2812, true), memoryDataView.getFloat32 (address + 2816, true), memoryDataView.getFloat32 (address + 2820, true), memoryDataView.getFloat32 (address + 2824, true), memoryDataView.getFloat32 (address + 2828, true), memoryDataView.getFloat32 (address + 2832, true), memoryDataView.getFloat32 (address + 2836, true), memoryDataView.getFloat32 (address + 2840, true), memoryDataView.getFloat32 (address + 2844, true), memoryDataView.getFloat32 (address + 2848, true), memoryDataView.getFloat32 (address + 2852, true), memoryDataView.getFloat32 (address + 2856, true), memoryDataView.getFloat32 (address + 2860, true), memoryDataView.getFloat32 (address + 2864, true), memoryDataView.getFloat32 (address + 2868, true), memoryDataView.getFloat32 (address + 2872, true), memoryDataView.getFloat32 (address + 2876, true), memoryDataView.getFloat32 (address + 2880, true), memoryDataView.getFloat32 (address + 2884, true), memoryDataView.getFloat32 (address + 2888, true), memoryDataView.getFloat32 (address + 2892, true), memoryDataView.getFloat32 (address + 2896, true), memoryDataView.getFloat32 (address + 2900, true), memoryDataView.getFloat32 (address + 2904, true), memoryDataView.getFloat32 (address + 2908, true), memoryDataView.getFloat32 (address + 2912, true), memoryDataView.getFloat32 (address + 2916, true), memoryDataView.getFloat32 (address + 2920, true), memoryDataView.getFloat32 (address + 2924, true), memoryDataView.getFloat32 (address + 2928, true), memoryDataView.getFloat32 (address + 2932, true), memoryDataView.getFloat32 (address + 2936, true), memoryDataView.getFloat32 (address + 2940, true), memoryDataView.getFloat32 (address + 2944, true), memoryDataView.getFloat32 (address + 2948, true), memoryDataView.getFloat32 (address + 2952, true), memoryDataView.getFloat32 (address + 2956, true), memoryDataView.getFloat32 (address + 2960, true), memoryDataView.getFloat32 (address + 2964, true), memoryDataView.getFloat32 (address + 2968, true), memoryDataView.getFloat32 (address + 2972, true), memoryDataView.getFloat32 (address + 2976, true), memoryDataView.getFloat32 (address + 2980, true), memoryDataView.getFloat32 (address + 2984, true), memoryDataView.getFloat32 (address + 2988, true), memoryDataView.getFloat32 (address + 2992, true), memoryDataView.getFloat32 (address + 2996, true), memoryDataView.getFloat32 (address + 3000, true), memoryDataView.getFloat32 (address + 3004, true), memoryDataView.getFloat32 (address + 3008, true), memoryDataView.getFloat32 (address + 3012, true), memoryDataView.getFloat32 (address + 3016, true), memoryDataView.getFloat32 (address + 3020, true), memoryDataView.getFloat32 (address + 3024, true), memoryDataView.getFloat32 (address + 3028, true), memoryDataView.getFloat32 (address + 3032, true), memoryDataView.getFloat32 (address + 3036, true), memoryDataView.getFloat32 (address + 3040, true), memoryDataView.getFloat32 (address + 3044, true), memoryDataView.getFloat32 (address + 3048, true), memoryDataView.getFloat32 (address + 3052, true), memoryDataView.getFloat32 (address + 3056, true), memoryDataView.getFloat32 (address + 3060, true), memoryDataView.getFloat32 (address + 3064, true), memoryDataView.getFloat32 (address + 3068, true), memoryDataView.getFloat32 (address + 3072, true), memoryDataView.getFloat32 (address + 3076, true), memoryDataView.getFloat32 (address + 3080, true), memoryDataView.getFloat32 (address + 3084, true), memoryDataView.getFloat32 (address + 3088, true), memoryDataView.getFloat32 (address + 3092, true), memoryDataView.getFloat32 (address + 3096, true), memoryDataView.getFloat32 (address + 3100, true), memoryDataView.getFloat32 (address + 3104, true), memoryDataView.getFloat32 (address + 3108, true), memoryDataView.getFloat32 (address + 3112, true), memoryDataView.getFloat32 (address + 3116, true), memoryDataView.getFloat32 (address + 3120, true), memoryDataView.getFloat32 (address + 3124, true), memoryDataView.getFloat32 (address + 3128, true), memoryDataView.getFloat32 (address + 3132, true), memoryDataView.getFloat32 (address + 3136, true), memoryDataView.getFloat32 (address + 3140, true), memoryDataView.getFloat32 (address + 3144, true), memoryDataView.getFloat32 (address + 3148, true), memoryDataView.getFloat32 (address + 3152, true), memoryDataView.getFloat32 (address + 3156, true), memoryDataView.getFloat32 (address + 3160, true), memoryDataView.getFloat32 (address + 3164, true), memoryDataView.getFloat32 (address + 3168, true), memoryDataView.getFloat32 (address + 3172, true), memoryDataView.getFloat32 (address + 3176, true), memoryDataView.getFloat32 (address + 3180, true), memoryDataView.getFloat32 (address + 3184, true), memoryDataView.getFloat32 (address + 3188, true), memoryDataView.getFloat32 (address + 3192, true), memoryDataView.getFloat32 (address + 3196, true), memoryDataView.getFloat32 (address + 3200, true), memoryDataView.getFloat32 (address + 3204, true), memoryDataView.getFloat32 (address + 3208, true), memoryDataView.getFloat32 (address + 3212, true), memoryDataView.getFloat32 (address + 3216, true), memoryDataView.getFloat32 (address + 3220, true), memoryDataView.getFloat32 (address + 3224, true), memoryDataView.getFloat32 (address + 3228, true), memoryDataView.getFloat32 (address + 3232, true), memoryDataView.getFloat32 (address + 3236, true), memoryDataView.getFloat32 (address + 3240, true), memoryDataView.getFloat32 (address + 3244, true), memoryDataView.getFloat32 (address + 3248, true), memoryDataView.getFloat32 (address + 3252, true), memoryDataView.getFloat32 (address + 3256, true), memoryDataView.getFloat32 (address + 3260, true), memoryDataView.getFloat32 (address + 3264, true), memoryDataView.getFloat32 (address + 3268, true), memoryDataView.getFloat32 (address + 3272, true), memoryDataView.getFloat32 (address + 3276, true), memoryDataView.getFloat32 (address + 3280, true), memoryDataView.getFloat32 (address + 3284, true), memoryDataView.getFloat32 (address + 3288, true), memoryDataView.getFloat32 (address + 3292, true), memoryDataView.getFloat32 (address + 3296, true), memoryDataView.getFloat32 (address + 3300, true), memoryDataView.getFloat32 (address + 3304, true), memoryDataView.getFloat32 (address + 3308, true), memoryDataView.getFloat32 (address + 3312, true), memoryDataView.getFloat32 (address + 3316, true), memoryDataView.getFloat32 (address + 3320, true), memoryDataView.getFloat32 (address + 3324, true), memoryDataView.getFloat32 (address + 3328, true), memoryDataView.getFloat32 (address + 3332, true), memoryDataView.getFloat32 (address + 3336, true), memoryDataView.getFloat32 (address + 3340, true), memoryDataView.getFloat32 (address + 3344, true), memoryDataView.getFloat32 (address + 3348, true), memoryDataView.getFloat32 (address + 3352, true), memoryDataView.getFloat32 (address + 3356, true), memoryDataView.getFloat32 (address + 3360, true), memoryDataView.getFloat32 (address + 3364, true), memoryDataView.getFloat32 (address + 3368, true), memoryDataView.getFloat32 (address + 3372, true), memoryDataView.getFloat32 (address + 3376, true), memoryDataView.getFloat32 (address + 3380, true), memoryDataView.getFloat32 (address + 3384, true), memoryDataView.getFloat32 (address + 3388, true), memoryDataView.getFloat32 (address + 3392, true), memoryDataView.getFloat32 (address + 3396, true), memoryDataView.getFloat32 (address + 3400, true), memoryDataView.getFloat32 (address + 3404, true), memoryDataView.getFloat32 (address + 3408, true), memoryDataView.getFloat32 (address + 3412, true), memoryDataView.getFloat32 (address + 3416, true), memoryDataView.getFloat32 (address + 3420, true), memoryDataView.getFloat32 (address + 3424, true), memoryDataView.getFloat32 (address + 3428, true), memoryDataView.getFloat32 (address + 3432, true), memoryDataView.getFloat32 (address + 3436, true), memoryDataView.getFloat32 (address + 3440, true), memoryDataView.getFloat32 (address + 3444, true), memoryDataView.getFloat32 (address + 3448, true), memoryDataView.getFloat32 (address + 3452, true), memoryDataView.getFloat32 (address + 3456, true), memoryDataView.getFloat32 (address + 3460, true), memoryDataView.getFloat32 (address + 3464, true), memoryDataView.getFloat32 (address + 3468, true), memoryDataView.getFloat32 (address + 3472, true), memoryDataView.getFloat32 (address + 3476, true), memoryDataView.getFloat32 (address + 3480, true), memoryDataView.getFloat32 (address + 3484, true), memoryDataView.getFloat32 (address + 3488, true), memoryDataView.getFloat32 (address + 3492, true), memoryDataView.getFloat32 (address + 3496, true), memoryDataView.getFloat32 (address + 3500, true), memoryDataView.getFloat32 (address + 3504, true), memoryDataView.getFloat32 (address + 3508, true), memoryDataView.getFloat32 (address + 3512, true), memoryDataView.getFloat32 (address + 3516, true), memoryDataView.getFloat32 (address + 3520, true), memoryDataView.getFloat32 (address + 3524, true), memoryDataView.getFloat32 (address + 3528, true), memoryDataView.getFloat32 (address + 3532, true), memoryDataView.getFloat32 (address + 3536, true), memoryDataView.getFloat32 (address + 3540, true), memoryDataView.getFloat32 (address + 3544, true), memoryDataView.getFloat32 (address + 3548, true), memoryDataView.getFloat32 (address + 3552, true), memoryDataView.getFloat32 (address + 3556, true), memoryDataView.getFloat32 (address + 3560, true), memoryDataView.getFloat32 (address + 3564, true), memoryDataView.getFloat32 (address + 3568, true), memoryDataView.getFloat32 (address + 3572, true), memoryDataView.getFloat32 (address + 3576, true), memoryDataView.getFloat32 (address + 3580, true), memoryDataView.getFloat32 (address + 3584, true), memoryDataView.getFloat32 (address + 3588, true), memoryDataView.getFloat32 (address + 3592, true), memoryDataView.getFloat32 (address + 3596, true), memoryDataView.getFloat32 (address + 3600, true), memoryDataView.getFloat32 (address + 3604, true), memoryDataView.getFloat32 (address + 3608, true), memoryDataView.getFloat32 (address + 3612, true), memoryDataView.getFloat32 (address + 3616, true), memoryDataView.getFloat32 (address + 3620, true), memoryDataView.getFloat32 (address + 3624, true), memoryDataView.getFloat32 (address + 3628, true), memoryDataView.getFloat32 (address + 3632, true), memoryDataView.getFloat32 (address + 3636, true), memoryDataView.getFloat32 (address + 3640, true), memoryDataView.getFloat32 (address + 3644, true), memoryDataView.getFloat32 (address + 3648, true), memoryDataView.getFloat32 (address + 3652, true), memoryDataView.getFloat32 (address + 3656, true), memoryDataView.getFloat32 (address + 3660, true), memoryDataView.getFloat32 (address + 3664, true), memoryDataView.getFloat32 (address + 3668, true), memoryDataView.getFloat32 (address + 3672, true), memoryDataView.getFloat32 (address + 3676, true), memoryDataView.getFloat32 (address + 3680, true), memoryDataView.getFloat32 (address + 3684, true), memoryDataView.getFloat32 (address + 3688, true), memoryDataView.getFloat32 (address + 3692, true), memoryDataView.getFloat32 (address + 3696, true), memoryDataView.getFloat32 (address + 3700, true), memoryDataView.getFloat32 (address + 3704, true), memoryDataView.getFloat32 (address + 3708, true), memoryDataView.getFloat32 (address + 3712, true), memoryDataView.getFloat32 (address + 3716, true), memoryDataView.getFloat32 (address + 3720, true), memoryDataView.getFloat32 (address + 3724, true), memoryDataView.getFloat32 (address + 3728, true), memoryDataView.getFloat32 (address + 3732, true), memoryDataView.getFloat32 (address + 3736, true), memoryDataView.getFloat32 (address + 3740, true), memoryDataView.getFloat32 (address + 3744, true), memoryDataView.getFloat32 (address + 3748, true), memoryDataView.getFloat32 (address + 3752, true), memoryDataView.getFloat32 (address + 3756, true), memoryDataView.getFloat32 (address + 3760, true), memoryDataView.getFloat32 (address + 3764, true), memoryDataView.getFloat32 (address + 3768, true), memoryDataView.getFloat32 (address + 3772, true), memoryDataView.getFloat32 (address + 3776, true), memoryDataView.getFloat32 (address + 3780, true), memoryDataView.getFloat32 (address + 3784, true), memoryDataView.getFloat32 (address + 3788, true), memoryDataView.getFloat32 (address + 3792, true), memoryDataView.getFloat32 (address + 3796, true), memoryDataView.getFloat32 (address + 3800, true), memoryDataView.getFloat32 (address + 3804, true), memoryDataView.getFloat32 (address + 3808, true), memoryDataView.getFloat32 (address + 3812, true), memoryDataView.getFloat32 (address + 3816, true), memoryDataView.getFloat32 (address + 3820, true), memoryDataView.getFloat32 (address + 3824, true), memoryDataView.getFloat32 (address + 3828, true), memoryDataView.getFloat32 (address + 3832, true), memoryDataView.getFloat32 (address + 3836, true), memoryDataView.getFloat32 (address + 3840, true), memoryDataView.getFloat32 (address + 3844, true), memoryDataView.getFloat32 (address + 3848, true), memoryDataView.getFloat32 (address + 3852, true), memoryDataView.getFloat32 (address + 3856, true), memoryDataView.getFloat32 (address + 3860, true), memoryDataView.getFloat32 (address + 3864, true), memoryDataView.getFloat32 (address + 3868, true), memoryDataView.getFloat32 (address + 3872, true), memoryDataView.getFloat32 (address + 3876, true), memoryDataView.getFloat32 (address + 3880, true), memoryDataView.getFloat32 (address + 3884, true), memoryDataView.getFloat32 (address + 3888, true), memoryDataView.getFloat32 (address + 3892, true), memoryDataView.getFloat32 (address + 3896, true), memoryDataView.getFloat32 (address + 3900, true), memoryDataView.getFloat32 (address + 3904, true), memoryDataView.getFloat32 (address + 3908, true), memoryDataView.getFloat32 (address + 3912, true), memoryDataView.getFloat32 (address + 3916, true), memoryDataView.getFloat32 (address + 3920, true), memoryDataView.getFloat32 (address + 3924, true), memoryDataView.getFloat32 (address + 3928, true), memoryDataView.getFloat32 (address + 3932, true), memoryDataView.getFloat32 (address + 3936, true), memoryDataView.getFloat32 (address + 3940, true), memoryDataView.getFloat32 (address + 3944, true), memoryDataView.getFloat32 (address + 3948, true), memoryDataView.getFloat32 (address + 3952, true), memoryDataView.getFloat32 (address + 3956, true), memoryDataView.getFloat32 (address + 3960, true), memoryDataView.getFloat32 (address + 3964, true)]; + }; + } + + //============================================================================== + /** @access private */ + async _initialiseInternalNonSIMD (sessionID, frequency) + { + this.stateAddress = 86096; + this.scratchSpaceAddress = 219936; + + const memory = new WebAssembly.Memory ({ initial: 5 }); + const stack = new WebAssembly.Global ({ value: "i32", mutable: true }, 86096); + const imports = { + env: { + __linear_memory: memory, + __memory_base: 0, + __stack_pointer: stack, + __table_base: 0, + memcpy: (dst, src, len) => { this.byteMemory.copyWithin (dst, src, src + len); return dst; }, + memmove: (dst, src, len) => { this.byteMemory.copyWithin (dst, src, src + len); return dst; }, + memset: (dst, value, len) => { this.byteMemory.fill (value, dst, dst + len); return dst; } + }, + }; + + const result = await WebAssembly.instantiate (this._getWasmBytesNonSIMD(), imports); + this.instance = result.instance; + const exports = this.instance.exports; + const memoryBuffer = exports.memory?.buffer || memory.buffer; + const memoryDataView = new DataView (memoryBuffer); + const byteMemory = new Uint8Array (memoryBuffer); + this.byteMemory = byteMemory; + this.memoryDataView = memoryDataView; + + exports.initialise?.(this.stateAddress, this.scratchSpaceAddress, sessionID, frequency); + + const advanceFn = exports.advanceBlock ? ((numFrames) => exports.advanceBlock (86096, 217888, numFrames)) + : (() => exports.advanceOneFrame (86096, 217888)); + + this.reset = () => { + byteMemory.fill (0, 86096, 217888); + byteMemory.fill (0, 219936, 219936 + 4); + exports.initialise?.(this.stateAddress, this.scratchSpaceAddress, sessionID, frequency); + }; + + this._advanceInternal = (numFrames) => { + byteMemory.fill (0, 217888, 217888 + numFrames * 4); + advanceFn (numFrames); + }; + + this._getOutputFrameInternal_out = (frameIndex) => { return memoryDataView.getFloat32 (217888 + frameIndex * 4, true); }; + + this._getOutputFramesInternal_out = (destChannelArrays, maxNumFramesToRead, destChannel) => { + if (maxNumFramesToRead > 512) + maxNumFramesToRead = 512; + + const channelsToCopy = Math.min (1, destChannelArrays.length - destChannel); + let source = 217888; + + for (let frame = 0; frame < maxNumFramesToRead; ++frame) + { + for (let channel = 0; channel < channelsToCopy; ++channel) + destChannelArrays[destChannel + channel][frame] = memoryDataView.getFloat32 (source + 4 * channel, true); + + source += 4; + } + }; + + this._unpackEventCountInternal_snapshot = () => { return memoryDataView.getInt32 (90640, true); }; + this._resetEventCountInternal_snapshot = () => { memoryDataView.setInt32 (90640, 0, true); }; + + this._readEventInternal_snapshot = (index) => { + const eventAddress = 90644 + (3976 * index); + const frame = memoryDataView.getInt32 (eventAddress, true); + return { frame, typeIndex: 0, event: this._unpack_a992_f32 (eventAddress + 8) }; + }; + + this._pack_o1_Message_message_i32 = (address, newValue) => { + memoryDataView.setInt32 (address, newValue.message, true); + }; + + this._unpack_a992_f32 = (address) => { + return [memoryDataView.getFloat32 (address, true), memoryDataView.getFloat32 (address + 4, true), memoryDataView.getFloat32 (address + 8, true), memoryDataView.getFloat32 (address + 12, true), memoryDataView.getFloat32 (address + 16, true), memoryDataView.getFloat32 (address + 20, true), memoryDataView.getFloat32 (address + 24, true), memoryDataView.getFloat32 (address + 28, true), memoryDataView.getFloat32 (address + 32, true), memoryDataView.getFloat32 (address + 36, true), memoryDataView.getFloat32 (address + 40, true), memoryDataView.getFloat32 (address + 44, true), memoryDataView.getFloat32 (address + 48, true), memoryDataView.getFloat32 (address + 52, true), memoryDataView.getFloat32 (address + 56, true), memoryDataView.getFloat32 (address + 60, true), memoryDataView.getFloat32 (address + 64, true), memoryDataView.getFloat32 (address + 68, true), memoryDataView.getFloat32 (address + 72, true), memoryDataView.getFloat32 (address + 76, true), memoryDataView.getFloat32 (address + 80, true), memoryDataView.getFloat32 (address + 84, true), memoryDataView.getFloat32 (address + 88, true), memoryDataView.getFloat32 (address + 92, true), memoryDataView.getFloat32 (address + 96, true), memoryDataView.getFloat32 (address + 100, true), memoryDataView.getFloat32 (address + 104, true), memoryDataView.getFloat32 (address + 108, true), memoryDataView.getFloat32 (address + 112, true), memoryDataView.getFloat32 (address + 116, true), memoryDataView.getFloat32 (address + 120, true), memoryDataView.getFloat32 (address + 124, true), memoryDataView.getFloat32 (address + 128, true), memoryDataView.getFloat32 (address + 132, true), memoryDataView.getFloat32 (address + 136, true), memoryDataView.getFloat32 (address + 140, true), memoryDataView.getFloat32 (address + 144, true), memoryDataView.getFloat32 (address + 148, true), memoryDataView.getFloat32 (address + 152, true), memoryDataView.getFloat32 (address + 156, true), memoryDataView.getFloat32 (address + 160, true), memoryDataView.getFloat32 (address + 164, true), memoryDataView.getFloat32 (address + 168, true), memoryDataView.getFloat32 (address + 172, true), memoryDataView.getFloat32 (address + 176, true), memoryDataView.getFloat32 (address + 180, true), memoryDataView.getFloat32 (address + 184, true), memoryDataView.getFloat32 (address + 188, true), memoryDataView.getFloat32 (address + 192, true), memoryDataView.getFloat32 (address + 196, true), memoryDataView.getFloat32 (address + 200, true), memoryDataView.getFloat32 (address + 204, true), memoryDataView.getFloat32 (address + 208, true), memoryDataView.getFloat32 (address + 212, true), memoryDataView.getFloat32 (address + 216, true), memoryDataView.getFloat32 (address + 220, true), memoryDataView.getFloat32 (address + 224, true), memoryDataView.getFloat32 (address + 228, true), memoryDataView.getFloat32 (address + 232, true), memoryDataView.getFloat32 (address + 236, true), memoryDataView.getFloat32 (address + 240, true), memoryDataView.getFloat32 (address + 244, true), memoryDataView.getFloat32 (address + 248, true), memoryDataView.getFloat32 (address + 252, true), memoryDataView.getFloat32 (address + 256, true), memoryDataView.getFloat32 (address + 260, true), memoryDataView.getFloat32 (address + 264, true), memoryDataView.getFloat32 (address + 268, true), memoryDataView.getFloat32 (address + 272, true), memoryDataView.getFloat32 (address + 276, true), memoryDataView.getFloat32 (address + 280, true), memoryDataView.getFloat32 (address + 284, true), memoryDataView.getFloat32 (address + 288, true), memoryDataView.getFloat32 (address + 292, true), memoryDataView.getFloat32 (address + 296, true), memoryDataView.getFloat32 (address + 300, true), memoryDataView.getFloat32 (address + 304, true), memoryDataView.getFloat32 (address + 308, true), memoryDataView.getFloat32 (address + 312, true), memoryDataView.getFloat32 (address + 316, true), memoryDataView.getFloat32 (address + 320, true), memoryDataView.getFloat32 (address + 324, true), memoryDataView.getFloat32 (address + 328, true), memoryDataView.getFloat32 (address + 332, true), memoryDataView.getFloat32 (address + 336, true), memoryDataView.getFloat32 (address + 340, true), memoryDataView.getFloat32 (address + 344, true), memoryDataView.getFloat32 (address + 348, true), memoryDataView.getFloat32 (address + 352, true), memoryDataView.getFloat32 (address + 356, true), memoryDataView.getFloat32 (address + 360, true), memoryDataView.getFloat32 (address + 364, true), memoryDataView.getFloat32 (address + 368, true), memoryDataView.getFloat32 (address + 372, true), memoryDataView.getFloat32 (address + 376, true), memoryDataView.getFloat32 (address + 380, true), memoryDataView.getFloat32 (address + 384, true), memoryDataView.getFloat32 (address + 388, true), memoryDataView.getFloat32 (address + 392, true), memoryDataView.getFloat32 (address + 396, true), memoryDataView.getFloat32 (address + 400, true), memoryDataView.getFloat32 (address + 404, true), memoryDataView.getFloat32 (address + 408, true), memoryDataView.getFloat32 (address + 412, true), memoryDataView.getFloat32 (address + 416, true), memoryDataView.getFloat32 (address + 420, true), memoryDataView.getFloat32 (address + 424, true), memoryDataView.getFloat32 (address + 428, true), memoryDataView.getFloat32 (address + 432, true), memoryDataView.getFloat32 (address + 436, true), memoryDataView.getFloat32 (address + 440, true), memoryDataView.getFloat32 (address + 444, true), memoryDataView.getFloat32 (address + 448, true), memoryDataView.getFloat32 (address + 452, true), memoryDataView.getFloat32 (address + 456, true), memoryDataView.getFloat32 (address + 460, true), memoryDataView.getFloat32 (address + 464, true), memoryDataView.getFloat32 (address + 468, true), memoryDataView.getFloat32 (address + 472, true), memoryDataView.getFloat32 (address + 476, true), memoryDataView.getFloat32 (address + 480, true), memoryDataView.getFloat32 (address + 484, true), memoryDataView.getFloat32 (address + 488, true), memoryDataView.getFloat32 (address + 492, true), memoryDataView.getFloat32 (address + 496, true), memoryDataView.getFloat32 (address + 500, true), memoryDataView.getFloat32 (address + 504, true), memoryDataView.getFloat32 (address + 508, true), memoryDataView.getFloat32 (address + 512, true), memoryDataView.getFloat32 (address + 516, true), memoryDataView.getFloat32 (address + 520, true), memoryDataView.getFloat32 (address + 524, true), memoryDataView.getFloat32 (address + 528, true), memoryDataView.getFloat32 (address + 532, true), memoryDataView.getFloat32 (address + 536, true), memoryDataView.getFloat32 (address + 540, true), memoryDataView.getFloat32 (address + 544, true), memoryDataView.getFloat32 (address + 548, true), memoryDataView.getFloat32 (address + 552, true), memoryDataView.getFloat32 (address + 556, true), memoryDataView.getFloat32 (address + 560, true), memoryDataView.getFloat32 (address + 564, true), memoryDataView.getFloat32 (address + 568, true), memoryDataView.getFloat32 (address + 572, true), memoryDataView.getFloat32 (address + 576, true), memoryDataView.getFloat32 (address + 580, true), memoryDataView.getFloat32 (address + 584, true), memoryDataView.getFloat32 (address + 588, true), memoryDataView.getFloat32 (address + 592, true), memoryDataView.getFloat32 (address + 596, true), memoryDataView.getFloat32 (address + 600, true), memoryDataView.getFloat32 (address + 604, true), memoryDataView.getFloat32 (address + 608, true), memoryDataView.getFloat32 (address + 612, true), memoryDataView.getFloat32 (address + 616, true), memoryDataView.getFloat32 (address + 620, true), memoryDataView.getFloat32 (address + 624, true), memoryDataView.getFloat32 (address + 628, true), memoryDataView.getFloat32 (address + 632, true), memoryDataView.getFloat32 (address + 636, true), memoryDataView.getFloat32 (address + 640, true), memoryDataView.getFloat32 (address + 644, true), memoryDataView.getFloat32 (address + 648, true), memoryDataView.getFloat32 (address + 652, true), memoryDataView.getFloat32 (address + 656, true), memoryDataView.getFloat32 (address + 660, true), memoryDataView.getFloat32 (address + 664, true), memoryDataView.getFloat32 (address + 668, true), memoryDataView.getFloat32 (address + 672, true), memoryDataView.getFloat32 (address + 676, true), memoryDataView.getFloat32 (address + 680, true), memoryDataView.getFloat32 (address + 684, true), memoryDataView.getFloat32 (address + 688, true), memoryDataView.getFloat32 (address + 692, true), memoryDataView.getFloat32 (address + 696, true), memoryDataView.getFloat32 (address + 700, true), memoryDataView.getFloat32 (address + 704, true), memoryDataView.getFloat32 (address + 708, true), memoryDataView.getFloat32 (address + 712, true), memoryDataView.getFloat32 (address + 716, true), memoryDataView.getFloat32 (address + 720, true), memoryDataView.getFloat32 (address + 724, true), memoryDataView.getFloat32 (address + 728, true), memoryDataView.getFloat32 (address + 732, true), memoryDataView.getFloat32 (address + 736, true), memoryDataView.getFloat32 (address + 740, true), memoryDataView.getFloat32 (address + 744, true), memoryDataView.getFloat32 (address + 748, true), memoryDataView.getFloat32 (address + 752, true), memoryDataView.getFloat32 (address + 756, true), memoryDataView.getFloat32 (address + 760, true), memoryDataView.getFloat32 (address + 764, true), memoryDataView.getFloat32 (address + 768, true), memoryDataView.getFloat32 (address + 772, true), memoryDataView.getFloat32 (address + 776, true), memoryDataView.getFloat32 (address + 780, true), memoryDataView.getFloat32 (address + 784, true), memoryDataView.getFloat32 (address + 788, true), memoryDataView.getFloat32 (address + 792, true), memoryDataView.getFloat32 (address + 796, true), memoryDataView.getFloat32 (address + 800, true), memoryDataView.getFloat32 (address + 804, true), memoryDataView.getFloat32 (address + 808, true), memoryDataView.getFloat32 (address + 812, true), memoryDataView.getFloat32 (address + 816, true), memoryDataView.getFloat32 (address + 820, true), memoryDataView.getFloat32 (address + 824, true), memoryDataView.getFloat32 (address + 828, true), memoryDataView.getFloat32 (address + 832, true), memoryDataView.getFloat32 (address + 836, true), memoryDataView.getFloat32 (address + 840, true), memoryDataView.getFloat32 (address + 844, true), memoryDataView.getFloat32 (address + 848, true), memoryDataView.getFloat32 (address + 852, true), memoryDataView.getFloat32 (address + 856, true), memoryDataView.getFloat32 (address + 860, true), memoryDataView.getFloat32 (address + 864, true), memoryDataView.getFloat32 (address + 868, true), memoryDataView.getFloat32 (address + 872, true), memoryDataView.getFloat32 (address + 876, true), memoryDataView.getFloat32 (address + 880, true), memoryDataView.getFloat32 (address + 884, true), memoryDataView.getFloat32 (address + 888, true), memoryDataView.getFloat32 (address + 892, true), memoryDataView.getFloat32 (address + 896, true), memoryDataView.getFloat32 (address + 900, true), memoryDataView.getFloat32 (address + 904, true), memoryDataView.getFloat32 (address + 908, true), memoryDataView.getFloat32 (address + 912, true), memoryDataView.getFloat32 (address + 916, true), memoryDataView.getFloat32 (address + 920, true), memoryDataView.getFloat32 (address + 924, true), memoryDataView.getFloat32 (address + 928, true), memoryDataView.getFloat32 (address + 932, true), memoryDataView.getFloat32 (address + 936, true), memoryDataView.getFloat32 (address + 940, true), memoryDataView.getFloat32 (address + 944, true), memoryDataView.getFloat32 (address + 948, true), memoryDataView.getFloat32 (address + 952, true), memoryDataView.getFloat32 (address + 956, true), memoryDataView.getFloat32 (address + 960, true), memoryDataView.getFloat32 (address + 964, true), memoryDataView.getFloat32 (address + 968, true), memoryDataView.getFloat32 (address + 972, true), memoryDataView.getFloat32 (address + 976, true), memoryDataView.getFloat32 (address + 980, true), memoryDataView.getFloat32 (address + 984, true), memoryDataView.getFloat32 (address + 988, true), memoryDataView.getFloat32 (address + 992, true), memoryDataView.getFloat32 (address + 996, true), memoryDataView.getFloat32 (address + 1000, true), memoryDataView.getFloat32 (address + 1004, true), memoryDataView.getFloat32 (address + 1008, true), memoryDataView.getFloat32 (address + 1012, true), memoryDataView.getFloat32 (address + 1016, true), memoryDataView.getFloat32 (address + 1020, true), memoryDataView.getFloat32 (address + 1024, true), memoryDataView.getFloat32 (address + 1028, true), memoryDataView.getFloat32 (address + 1032, true), memoryDataView.getFloat32 (address + 1036, true), memoryDataView.getFloat32 (address + 1040, true), memoryDataView.getFloat32 (address + 1044, true), memoryDataView.getFloat32 (address + 1048, true), memoryDataView.getFloat32 (address + 1052, true), memoryDataView.getFloat32 (address + 1056, true), memoryDataView.getFloat32 (address + 1060, true), memoryDataView.getFloat32 (address + 1064, true), memoryDataView.getFloat32 (address + 1068, true), memoryDataView.getFloat32 (address + 1072, true), memoryDataView.getFloat32 (address + 1076, true), memoryDataView.getFloat32 (address + 1080, true), memoryDataView.getFloat32 (address + 1084, true), memoryDataView.getFloat32 (address + 1088, true), memoryDataView.getFloat32 (address + 1092, true), memoryDataView.getFloat32 (address + 1096, true), memoryDataView.getFloat32 (address + 1100, true), memoryDataView.getFloat32 (address + 1104, true), memoryDataView.getFloat32 (address + 1108, true), memoryDataView.getFloat32 (address + 1112, true), memoryDataView.getFloat32 (address + 1116, true), memoryDataView.getFloat32 (address + 1120, true), memoryDataView.getFloat32 (address + 1124, true), memoryDataView.getFloat32 (address + 1128, true), memoryDataView.getFloat32 (address + 1132, true), memoryDataView.getFloat32 (address + 1136, true), memoryDataView.getFloat32 (address + 1140, true), memoryDataView.getFloat32 (address + 1144, true), memoryDataView.getFloat32 (address + 1148, true), memoryDataView.getFloat32 (address + 1152, true), memoryDataView.getFloat32 (address + 1156, true), memoryDataView.getFloat32 (address + 1160, true), memoryDataView.getFloat32 (address + 1164, true), memoryDataView.getFloat32 (address + 1168, true), memoryDataView.getFloat32 (address + 1172, true), memoryDataView.getFloat32 (address + 1176, true), memoryDataView.getFloat32 (address + 1180, true), memoryDataView.getFloat32 (address + 1184, true), memoryDataView.getFloat32 (address + 1188, true), memoryDataView.getFloat32 (address + 1192, true), memoryDataView.getFloat32 (address + 1196, true), memoryDataView.getFloat32 (address + 1200, true), memoryDataView.getFloat32 (address + 1204, true), memoryDataView.getFloat32 (address + 1208, true), memoryDataView.getFloat32 (address + 1212, true), memoryDataView.getFloat32 (address + 1216, true), memoryDataView.getFloat32 (address + 1220, true), memoryDataView.getFloat32 (address + 1224, true), memoryDataView.getFloat32 (address + 1228, true), memoryDataView.getFloat32 (address + 1232, true), memoryDataView.getFloat32 (address + 1236, true), memoryDataView.getFloat32 (address + 1240, true), memoryDataView.getFloat32 (address + 1244, true), memoryDataView.getFloat32 (address + 1248, true), memoryDataView.getFloat32 (address + 1252, true), memoryDataView.getFloat32 (address + 1256, true), memoryDataView.getFloat32 (address + 1260, true), memoryDataView.getFloat32 (address + 1264, true), memoryDataView.getFloat32 (address + 1268, true), memoryDataView.getFloat32 (address + 1272, true), memoryDataView.getFloat32 (address + 1276, true), memoryDataView.getFloat32 (address + 1280, true), memoryDataView.getFloat32 (address + 1284, true), memoryDataView.getFloat32 (address + 1288, true), memoryDataView.getFloat32 (address + 1292, true), memoryDataView.getFloat32 (address + 1296, true), memoryDataView.getFloat32 (address + 1300, true), memoryDataView.getFloat32 (address + 1304, true), memoryDataView.getFloat32 (address + 1308, true), memoryDataView.getFloat32 (address + 1312, true), memoryDataView.getFloat32 (address + 1316, true), memoryDataView.getFloat32 (address + 1320, true), memoryDataView.getFloat32 (address + 1324, true), memoryDataView.getFloat32 (address + 1328, true), memoryDataView.getFloat32 (address + 1332, true), memoryDataView.getFloat32 (address + 1336, true), memoryDataView.getFloat32 (address + 1340, true), memoryDataView.getFloat32 (address + 1344, true), memoryDataView.getFloat32 (address + 1348, true), memoryDataView.getFloat32 (address + 1352, true), memoryDataView.getFloat32 (address + 1356, true), memoryDataView.getFloat32 (address + 1360, true), memoryDataView.getFloat32 (address + 1364, true), memoryDataView.getFloat32 (address + 1368, true), memoryDataView.getFloat32 (address + 1372, true), memoryDataView.getFloat32 (address + 1376, true), memoryDataView.getFloat32 (address + 1380, true), memoryDataView.getFloat32 (address + 1384, true), memoryDataView.getFloat32 (address + 1388, true), memoryDataView.getFloat32 (address + 1392, true), memoryDataView.getFloat32 (address + 1396, true), memoryDataView.getFloat32 (address + 1400, true), memoryDataView.getFloat32 (address + 1404, true), memoryDataView.getFloat32 (address + 1408, true), memoryDataView.getFloat32 (address + 1412, true), memoryDataView.getFloat32 (address + 1416, true), memoryDataView.getFloat32 (address + 1420, true), memoryDataView.getFloat32 (address + 1424, true), memoryDataView.getFloat32 (address + 1428, true), memoryDataView.getFloat32 (address + 1432, true), memoryDataView.getFloat32 (address + 1436, true), memoryDataView.getFloat32 (address + 1440, true), memoryDataView.getFloat32 (address + 1444, true), memoryDataView.getFloat32 (address + 1448, true), memoryDataView.getFloat32 (address + 1452, true), memoryDataView.getFloat32 (address + 1456, true), memoryDataView.getFloat32 (address + 1460, true), memoryDataView.getFloat32 (address + 1464, true), memoryDataView.getFloat32 (address + 1468, true), memoryDataView.getFloat32 (address + 1472, true), memoryDataView.getFloat32 (address + 1476, true), memoryDataView.getFloat32 (address + 1480, true), memoryDataView.getFloat32 (address + 1484, true), memoryDataView.getFloat32 (address + 1488, true), memoryDataView.getFloat32 (address + 1492, true), memoryDataView.getFloat32 (address + 1496, true), memoryDataView.getFloat32 (address + 1500, true), memoryDataView.getFloat32 (address + 1504, true), memoryDataView.getFloat32 (address + 1508, true), memoryDataView.getFloat32 (address + 1512, true), memoryDataView.getFloat32 (address + 1516, true), memoryDataView.getFloat32 (address + 1520, true), memoryDataView.getFloat32 (address + 1524, true), memoryDataView.getFloat32 (address + 1528, true), memoryDataView.getFloat32 (address + 1532, true), memoryDataView.getFloat32 (address + 1536, true), memoryDataView.getFloat32 (address + 1540, true), memoryDataView.getFloat32 (address + 1544, true), memoryDataView.getFloat32 (address + 1548, true), memoryDataView.getFloat32 (address + 1552, true), memoryDataView.getFloat32 (address + 1556, true), memoryDataView.getFloat32 (address + 1560, true), memoryDataView.getFloat32 (address + 1564, true), memoryDataView.getFloat32 (address + 1568, true), memoryDataView.getFloat32 (address + 1572, true), memoryDataView.getFloat32 (address + 1576, true), memoryDataView.getFloat32 (address + 1580, true), memoryDataView.getFloat32 (address + 1584, true), memoryDataView.getFloat32 (address + 1588, true), memoryDataView.getFloat32 (address + 1592, true), memoryDataView.getFloat32 (address + 1596, true), memoryDataView.getFloat32 (address + 1600, true), memoryDataView.getFloat32 (address + 1604, true), memoryDataView.getFloat32 (address + 1608, true), memoryDataView.getFloat32 (address + 1612, true), memoryDataView.getFloat32 (address + 1616, true), memoryDataView.getFloat32 (address + 1620, true), memoryDataView.getFloat32 (address + 1624, true), memoryDataView.getFloat32 (address + 1628, true), memoryDataView.getFloat32 (address + 1632, true), memoryDataView.getFloat32 (address + 1636, true), memoryDataView.getFloat32 (address + 1640, true), memoryDataView.getFloat32 (address + 1644, true), memoryDataView.getFloat32 (address + 1648, true), memoryDataView.getFloat32 (address + 1652, true), memoryDataView.getFloat32 (address + 1656, true), memoryDataView.getFloat32 (address + 1660, true), memoryDataView.getFloat32 (address + 1664, true), memoryDataView.getFloat32 (address + 1668, true), memoryDataView.getFloat32 (address + 1672, true), memoryDataView.getFloat32 (address + 1676, true), memoryDataView.getFloat32 (address + 1680, true), memoryDataView.getFloat32 (address + 1684, true), memoryDataView.getFloat32 (address + 1688, true), memoryDataView.getFloat32 (address + 1692, true), memoryDataView.getFloat32 (address + 1696, true), memoryDataView.getFloat32 (address + 1700, true), memoryDataView.getFloat32 (address + 1704, true), memoryDataView.getFloat32 (address + 1708, true), memoryDataView.getFloat32 (address + 1712, true), memoryDataView.getFloat32 (address + 1716, true), memoryDataView.getFloat32 (address + 1720, true), memoryDataView.getFloat32 (address + 1724, true), memoryDataView.getFloat32 (address + 1728, true), memoryDataView.getFloat32 (address + 1732, true), memoryDataView.getFloat32 (address + 1736, true), memoryDataView.getFloat32 (address + 1740, true), memoryDataView.getFloat32 (address + 1744, true), memoryDataView.getFloat32 (address + 1748, true), memoryDataView.getFloat32 (address + 1752, true), memoryDataView.getFloat32 (address + 1756, true), memoryDataView.getFloat32 (address + 1760, true), memoryDataView.getFloat32 (address + 1764, true), memoryDataView.getFloat32 (address + 1768, true), memoryDataView.getFloat32 (address + 1772, true), memoryDataView.getFloat32 (address + 1776, true), memoryDataView.getFloat32 (address + 1780, true), memoryDataView.getFloat32 (address + 1784, true), memoryDataView.getFloat32 (address + 1788, true), memoryDataView.getFloat32 (address + 1792, true), memoryDataView.getFloat32 (address + 1796, true), memoryDataView.getFloat32 (address + 1800, true), memoryDataView.getFloat32 (address + 1804, true), memoryDataView.getFloat32 (address + 1808, true), memoryDataView.getFloat32 (address + 1812, true), memoryDataView.getFloat32 (address + 1816, true), memoryDataView.getFloat32 (address + 1820, true), memoryDataView.getFloat32 (address + 1824, true), memoryDataView.getFloat32 (address + 1828, true), memoryDataView.getFloat32 (address + 1832, true), memoryDataView.getFloat32 (address + 1836, true), memoryDataView.getFloat32 (address + 1840, true), memoryDataView.getFloat32 (address + 1844, true), memoryDataView.getFloat32 (address + 1848, true), memoryDataView.getFloat32 (address + 1852, true), memoryDataView.getFloat32 (address + 1856, true), memoryDataView.getFloat32 (address + 1860, true), memoryDataView.getFloat32 (address + 1864, true), memoryDataView.getFloat32 (address + 1868, true), memoryDataView.getFloat32 (address + 1872, true), memoryDataView.getFloat32 (address + 1876, true), memoryDataView.getFloat32 (address + 1880, true), memoryDataView.getFloat32 (address + 1884, true), memoryDataView.getFloat32 (address + 1888, true), memoryDataView.getFloat32 (address + 1892, true), memoryDataView.getFloat32 (address + 1896, true), memoryDataView.getFloat32 (address + 1900, true), memoryDataView.getFloat32 (address + 1904, true), memoryDataView.getFloat32 (address + 1908, true), memoryDataView.getFloat32 (address + 1912, true), memoryDataView.getFloat32 (address + 1916, true), memoryDataView.getFloat32 (address + 1920, true), memoryDataView.getFloat32 (address + 1924, true), memoryDataView.getFloat32 (address + 1928, true), memoryDataView.getFloat32 (address + 1932, true), memoryDataView.getFloat32 (address + 1936, true), memoryDataView.getFloat32 (address + 1940, true), memoryDataView.getFloat32 (address + 1944, true), memoryDataView.getFloat32 (address + 1948, true), memoryDataView.getFloat32 (address + 1952, true), memoryDataView.getFloat32 (address + 1956, true), memoryDataView.getFloat32 (address + 1960, true), memoryDataView.getFloat32 (address + 1964, true), memoryDataView.getFloat32 (address + 1968, true), memoryDataView.getFloat32 (address + 1972, true), memoryDataView.getFloat32 (address + 1976, true), memoryDataView.getFloat32 (address + 1980, true), memoryDataView.getFloat32 (address + 1984, true), memoryDataView.getFloat32 (address + 1988, true), memoryDataView.getFloat32 (address + 1992, true), memoryDataView.getFloat32 (address + 1996, true), memoryDataView.getFloat32 (address + 2000, true), memoryDataView.getFloat32 (address + 2004, true), memoryDataView.getFloat32 (address + 2008, true), memoryDataView.getFloat32 (address + 2012, true), memoryDataView.getFloat32 (address + 2016, true), memoryDataView.getFloat32 (address + 2020, true), memoryDataView.getFloat32 (address + 2024, true), memoryDataView.getFloat32 (address + 2028, true), memoryDataView.getFloat32 (address + 2032, true), memoryDataView.getFloat32 (address + 2036, true), memoryDataView.getFloat32 (address + 2040, true), memoryDataView.getFloat32 (address + 2044, true), memoryDataView.getFloat32 (address + 2048, true), memoryDataView.getFloat32 (address + 2052, true), memoryDataView.getFloat32 (address + 2056, true), memoryDataView.getFloat32 (address + 2060, true), memoryDataView.getFloat32 (address + 2064, true), memoryDataView.getFloat32 (address + 2068, true), memoryDataView.getFloat32 (address + 2072, true), memoryDataView.getFloat32 (address + 2076, true), memoryDataView.getFloat32 (address + 2080, true), memoryDataView.getFloat32 (address + 2084, true), memoryDataView.getFloat32 (address + 2088, true), memoryDataView.getFloat32 (address + 2092, true), memoryDataView.getFloat32 (address + 2096, true), memoryDataView.getFloat32 (address + 2100, true), memoryDataView.getFloat32 (address + 2104, true), memoryDataView.getFloat32 (address + 2108, true), memoryDataView.getFloat32 (address + 2112, true), memoryDataView.getFloat32 (address + 2116, true), memoryDataView.getFloat32 (address + 2120, true), memoryDataView.getFloat32 (address + 2124, true), memoryDataView.getFloat32 (address + 2128, true), memoryDataView.getFloat32 (address + 2132, true), memoryDataView.getFloat32 (address + 2136, true), memoryDataView.getFloat32 (address + 2140, true), memoryDataView.getFloat32 (address + 2144, true), memoryDataView.getFloat32 (address + 2148, true), memoryDataView.getFloat32 (address + 2152, true), memoryDataView.getFloat32 (address + 2156, true), memoryDataView.getFloat32 (address + 2160, true), memoryDataView.getFloat32 (address + 2164, true), memoryDataView.getFloat32 (address + 2168, true), memoryDataView.getFloat32 (address + 2172, true), memoryDataView.getFloat32 (address + 2176, true), memoryDataView.getFloat32 (address + 2180, true), memoryDataView.getFloat32 (address + 2184, true), memoryDataView.getFloat32 (address + 2188, true), memoryDataView.getFloat32 (address + 2192, true), memoryDataView.getFloat32 (address + 2196, true), memoryDataView.getFloat32 (address + 2200, true), memoryDataView.getFloat32 (address + 2204, true), memoryDataView.getFloat32 (address + 2208, true), memoryDataView.getFloat32 (address + 2212, true), memoryDataView.getFloat32 (address + 2216, true), memoryDataView.getFloat32 (address + 2220, true), memoryDataView.getFloat32 (address + 2224, true), memoryDataView.getFloat32 (address + 2228, true), memoryDataView.getFloat32 (address + 2232, true), memoryDataView.getFloat32 (address + 2236, true), memoryDataView.getFloat32 (address + 2240, true), memoryDataView.getFloat32 (address + 2244, true), memoryDataView.getFloat32 (address + 2248, true), memoryDataView.getFloat32 (address + 2252, true), memoryDataView.getFloat32 (address + 2256, true), memoryDataView.getFloat32 (address + 2260, true), memoryDataView.getFloat32 (address + 2264, true), memoryDataView.getFloat32 (address + 2268, true), memoryDataView.getFloat32 (address + 2272, true), memoryDataView.getFloat32 (address + 2276, true), memoryDataView.getFloat32 (address + 2280, true), memoryDataView.getFloat32 (address + 2284, true), memoryDataView.getFloat32 (address + 2288, true), memoryDataView.getFloat32 (address + 2292, true), memoryDataView.getFloat32 (address + 2296, true), memoryDataView.getFloat32 (address + 2300, true), memoryDataView.getFloat32 (address + 2304, true), memoryDataView.getFloat32 (address + 2308, true), memoryDataView.getFloat32 (address + 2312, true), memoryDataView.getFloat32 (address + 2316, true), memoryDataView.getFloat32 (address + 2320, true), memoryDataView.getFloat32 (address + 2324, true), memoryDataView.getFloat32 (address + 2328, true), memoryDataView.getFloat32 (address + 2332, true), memoryDataView.getFloat32 (address + 2336, true), memoryDataView.getFloat32 (address + 2340, true), memoryDataView.getFloat32 (address + 2344, true), memoryDataView.getFloat32 (address + 2348, true), memoryDataView.getFloat32 (address + 2352, true), memoryDataView.getFloat32 (address + 2356, true), memoryDataView.getFloat32 (address + 2360, true), memoryDataView.getFloat32 (address + 2364, true), memoryDataView.getFloat32 (address + 2368, true), memoryDataView.getFloat32 (address + 2372, true), memoryDataView.getFloat32 (address + 2376, true), memoryDataView.getFloat32 (address + 2380, true), memoryDataView.getFloat32 (address + 2384, true), memoryDataView.getFloat32 (address + 2388, true), memoryDataView.getFloat32 (address + 2392, true), memoryDataView.getFloat32 (address + 2396, true), memoryDataView.getFloat32 (address + 2400, true), memoryDataView.getFloat32 (address + 2404, true), memoryDataView.getFloat32 (address + 2408, true), memoryDataView.getFloat32 (address + 2412, true), memoryDataView.getFloat32 (address + 2416, true), memoryDataView.getFloat32 (address + 2420, true), memoryDataView.getFloat32 (address + 2424, true), memoryDataView.getFloat32 (address + 2428, true), memoryDataView.getFloat32 (address + 2432, true), memoryDataView.getFloat32 (address + 2436, true), memoryDataView.getFloat32 (address + 2440, true), memoryDataView.getFloat32 (address + 2444, true), memoryDataView.getFloat32 (address + 2448, true), memoryDataView.getFloat32 (address + 2452, true), memoryDataView.getFloat32 (address + 2456, true), memoryDataView.getFloat32 (address + 2460, true), memoryDataView.getFloat32 (address + 2464, true), memoryDataView.getFloat32 (address + 2468, true), memoryDataView.getFloat32 (address + 2472, true), memoryDataView.getFloat32 (address + 2476, true), memoryDataView.getFloat32 (address + 2480, true), memoryDataView.getFloat32 (address + 2484, true), memoryDataView.getFloat32 (address + 2488, true), memoryDataView.getFloat32 (address + 2492, true), memoryDataView.getFloat32 (address + 2496, true), memoryDataView.getFloat32 (address + 2500, true), memoryDataView.getFloat32 (address + 2504, true), memoryDataView.getFloat32 (address + 2508, true), memoryDataView.getFloat32 (address + 2512, true), memoryDataView.getFloat32 (address + 2516, true), memoryDataView.getFloat32 (address + 2520, true), memoryDataView.getFloat32 (address + 2524, true), memoryDataView.getFloat32 (address + 2528, true), memoryDataView.getFloat32 (address + 2532, true), memoryDataView.getFloat32 (address + 2536, true), memoryDataView.getFloat32 (address + 2540, true), memoryDataView.getFloat32 (address + 2544, true), memoryDataView.getFloat32 (address + 2548, true), memoryDataView.getFloat32 (address + 2552, true), memoryDataView.getFloat32 (address + 2556, true), memoryDataView.getFloat32 (address + 2560, true), memoryDataView.getFloat32 (address + 2564, true), memoryDataView.getFloat32 (address + 2568, true), memoryDataView.getFloat32 (address + 2572, true), memoryDataView.getFloat32 (address + 2576, true), memoryDataView.getFloat32 (address + 2580, true), memoryDataView.getFloat32 (address + 2584, true), memoryDataView.getFloat32 (address + 2588, true), memoryDataView.getFloat32 (address + 2592, true), memoryDataView.getFloat32 (address + 2596, true), memoryDataView.getFloat32 (address + 2600, true), memoryDataView.getFloat32 (address + 2604, true), memoryDataView.getFloat32 (address + 2608, true), memoryDataView.getFloat32 (address + 2612, true), memoryDataView.getFloat32 (address + 2616, true), memoryDataView.getFloat32 (address + 2620, true), memoryDataView.getFloat32 (address + 2624, true), memoryDataView.getFloat32 (address + 2628, true), memoryDataView.getFloat32 (address + 2632, true), memoryDataView.getFloat32 (address + 2636, true), memoryDataView.getFloat32 (address + 2640, true), memoryDataView.getFloat32 (address + 2644, true), memoryDataView.getFloat32 (address + 2648, true), memoryDataView.getFloat32 (address + 2652, true), memoryDataView.getFloat32 (address + 2656, true), memoryDataView.getFloat32 (address + 2660, true), memoryDataView.getFloat32 (address + 2664, true), memoryDataView.getFloat32 (address + 2668, true), memoryDataView.getFloat32 (address + 2672, true), memoryDataView.getFloat32 (address + 2676, true), memoryDataView.getFloat32 (address + 2680, true), memoryDataView.getFloat32 (address + 2684, true), memoryDataView.getFloat32 (address + 2688, true), memoryDataView.getFloat32 (address + 2692, true), memoryDataView.getFloat32 (address + 2696, true), memoryDataView.getFloat32 (address + 2700, true), memoryDataView.getFloat32 (address + 2704, true), memoryDataView.getFloat32 (address + 2708, true), memoryDataView.getFloat32 (address + 2712, true), memoryDataView.getFloat32 (address + 2716, true), memoryDataView.getFloat32 (address + 2720, true), memoryDataView.getFloat32 (address + 2724, true), memoryDataView.getFloat32 (address + 2728, true), memoryDataView.getFloat32 (address + 2732, true), memoryDataView.getFloat32 (address + 2736, true), memoryDataView.getFloat32 (address + 2740, true), memoryDataView.getFloat32 (address + 2744, true), memoryDataView.getFloat32 (address + 2748, true), memoryDataView.getFloat32 (address + 2752, true), memoryDataView.getFloat32 (address + 2756, true), memoryDataView.getFloat32 (address + 2760, true), memoryDataView.getFloat32 (address + 2764, true), memoryDataView.getFloat32 (address + 2768, true), memoryDataView.getFloat32 (address + 2772, true), memoryDataView.getFloat32 (address + 2776, true), memoryDataView.getFloat32 (address + 2780, true), memoryDataView.getFloat32 (address + 2784, true), memoryDataView.getFloat32 (address + 2788, true), memoryDataView.getFloat32 (address + 2792, true), memoryDataView.getFloat32 (address + 2796, true), memoryDataView.getFloat32 (address + 2800, true), memoryDataView.getFloat32 (address + 2804, true), memoryDataView.getFloat32 (address + 2808, true), memoryDataView.getFloat32 (address + 2812, true), memoryDataView.getFloat32 (address + 2816, true), memoryDataView.getFloat32 (address + 2820, true), memoryDataView.getFloat32 (address + 2824, true), memoryDataView.getFloat32 (address + 2828, true), memoryDataView.getFloat32 (address + 2832, true), memoryDataView.getFloat32 (address + 2836, true), memoryDataView.getFloat32 (address + 2840, true), memoryDataView.getFloat32 (address + 2844, true), memoryDataView.getFloat32 (address + 2848, true), memoryDataView.getFloat32 (address + 2852, true), memoryDataView.getFloat32 (address + 2856, true), memoryDataView.getFloat32 (address + 2860, true), memoryDataView.getFloat32 (address + 2864, true), memoryDataView.getFloat32 (address + 2868, true), memoryDataView.getFloat32 (address + 2872, true), memoryDataView.getFloat32 (address + 2876, true), memoryDataView.getFloat32 (address + 2880, true), memoryDataView.getFloat32 (address + 2884, true), memoryDataView.getFloat32 (address + 2888, true), memoryDataView.getFloat32 (address + 2892, true), memoryDataView.getFloat32 (address + 2896, true), memoryDataView.getFloat32 (address + 2900, true), memoryDataView.getFloat32 (address + 2904, true), memoryDataView.getFloat32 (address + 2908, true), memoryDataView.getFloat32 (address + 2912, true), memoryDataView.getFloat32 (address + 2916, true), memoryDataView.getFloat32 (address + 2920, true), memoryDataView.getFloat32 (address + 2924, true), memoryDataView.getFloat32 (address + 2928, true), memoryDataView.getFloat32 (address + 2932, true), memoryDataView.getFloat32 (address + 2936, true), memoryDataView.getFloat32 (address + 2940, true), memoryDataView.getFloat32 (address + 2944, true), memoryDataView.getFloat32 (address + 2948, true), memoryDataView.getFloat32 (address + 2952, true), memoryDataView.getFloat32 (address + 2956, true), memoryDataView.getFloat32 (address + 2960, true), memoryDataView.getFloat32 (address + 2964, true), memoryDataView.getFloat32 (address + 2968, true), memoryDataView.getFloat32 (address + 2972, true), memoryDataView.getFloat32 (address + 2976, true), memoryDataView.getFloat32 (address + 2980, true), memoryDataView.getFloat32 (address + 2984, true), memoryDataView.getFloat32 (address + 2988, true), memoryDataView.getFloat32 (address + 2992, true), memoryDataView.getFloat32 (address + 2996, true), memoryDataView.getFloat32 (address + 3000, true), memoryDataView.getFloat32 (address + 3004, true), memoryDataView.getFloat32 (address + 3008, true), memoryDataView.getFloat32 (address + 3012, true), memoryDataView.getFloat32 (address + 3016, true), memoryDataView.getFloat32 (address + 3020, true), memoryDataView.getFloat32 (address + 3024, true), memoryDataView.getFloat32 (address + 3028, true), memoryDataView.getFloat32 (address + 3032, true), memoryDataView.getFloat32 (address + 3036, true), memoryDataView.getFloat32 (address + 3040, true), memoryDataView.getFloat32 (address + 3044, true), memoryDataView.getFloat32 (address + 3048, true), memoryDataView.getFloat32 (address + 3052, true), memoryDataView.getFloat32 (address + 3056, true), memoryDataView.getFloat32 (address + 3060, true), memoryDataView.getFloat32 (address + 3064, true), memoryDataView.getFloat32 (address + 3068, true), memoryDataView.getFloat32 (address + 3072, true), memoryDataView.getFloat32 (address + 3076, true), memoryDataView.getFloat32 (address + 3080, true), memoryDataView.getFloat32 (address + 3084, true), memoryDataView.getFloat32 (address + 3088, true), memoryDataView.getFloat32 (address + 3092, true), memoryDataView.getFloat32 (address + 3096, true), memoryDataView.getFloat32 (address + 3100, true), memoryDataView.getFloat32 (address + 3104, true), memoryDataView.getFloat32 (address + 3108, true), memoryDataView.getFloat32 (address + 3112, true), memoryDataView.getFloat32 (address + 3116, true), memoryDataView.getFloat32 (address + 3120, true), memoryDataView.getFloat32 (address + 3124, true), memoryDataView.getFloat32 (address + 3128, true), memoryDataView.getFloat32 (address + 3132, true), memoryDataView.getFloat32 (address + 3136, true), memoryDataView.getFloat32 (address + 3140, true), memoryDataView.getFloat32 (address + 3144, true), memoryDataView.getFloat32 (address + 3148, true), memoryDataView.getFloat32 (address + 3152, true), memoryDataView.getFloat32 (address + 3156, true), memoryDataView.getFloat32 (address + 3160, true), memoryDataView.getFloat32 (address + 3164, true), memoryDataView.getFloat32 (address + 3168, true), memoryDataView.getFloat32 (address + 3172, true), memoryDataView.getFloat32 (address + 3176, true), memoryDataView.getFloat32 (address + 3180, true), memoryDataView.getFloat32 (address + 3184, true), memoryDataView.getFloat32 (address + 3188, true), memoryDataView.getFloat32 (address + 3192, true), memoryDataView.getFloat32 (address + 3196, true), memoryDataView.getFloat32 (address + 3200, true), memoryDataView.getFloat32 (address + 3204, true), memoryDataView.getFloat32 (address + 3208, true), memoryDataView.getFloat32 (address + 3212, true), memoryDataView.getFloat32 (address + 3216, true), memoryDataView.getFloat32 (address + 3220, true), memoryDataView.getFloat32 (address + 3224, true), memoryDataView.getFloat32 (address + 3228, true), memoryDataView.getFloat32 (address + 3232, true), memoryDataView.getFloat32 (address + 3236, true), memoryDataView.getFloat32 (address + 3240, true), memoryDataView.getFloat32 (address + 3244, true), memoryDataView.getFloat32 (address + 3248, true), memoryDataView.getFloat32 (address + 3252, true), memoryDataView.getFloat32 (address + 3256, true), memoryDataView.getFloat32 (address + 3260, true), memoryDataView.getFloat32 (address + 3264, true), memoryDataView.getFloat32 (address + 3268, true), memoryDataView.getFloat32 (address + 3272, true), memoryDataView.getFloat32 (address + 3276, true), memoryDataView.getFloat32 (address + 3280, true), memoryDataView.getFloat32 (address + 3284, true), memoryDataView.getFloat32 (address + 3288, true), memoryDataView.getFloat32 (address + 3292, true), memoryDataView.getFloat32 (address + 3296, true), memoryDataView.getFloat32 (address + 3300, true), memoryDataView.getFloat32 (address + 3304, true), memoryDataView.getFloat32 (address + 3308, true), memoryDataView.getFloat32 (address + 3312, true), memoryDataView.getFloat32 (address + 3316, true), memoryDataView.getFloat32 (address + 3320, true), memoryDataView.getFloat32 (address + 3324, true), memoryDataView.getFloat32 (address + 3328, true), memoryDataView.getFloat32 (address + 3332, true), memoryDataView.getFloat32 (address + 3336, true), memoryDataView.getFloat32 (address + 3340, true), memoryDataView.getFloat32 (address + 3344, true), memoryDataView.getFloat32 (address + 3348, true), memoryDataView.getFloat32 (address + 3352, true), memoryDataView.getFloat32 (address + 3356, true), memoryDataView.getFloat32 (address + 3360, true), memoryDataView.getFloat32 (address + 3364, true), memoryDataView.getFloat32 (address + 3368, true), memoryDataView.getFloat32 (address + 3372, true), memoryDataView.getFloat32 (address + 3376, true), memoryDataView.getFloat32 (address + 3380, true), memoryDataView.getFloat32 (address + 3384, true), memoryDataView.getFloat32 (address + 3388, true), memoryDataView.getFloat32 (address + 3392, true), memoryDataView.getFloat32 (address + 3396, true), memoryDataView.getFloat32 (address + 3400, true), memoryDataView.getFloat32 (address + 3404, true), memoryDataView.getFloat32 (address + 3408, true), memoryDataView.getFloat32 (address + 3412, true), memoryDataView.getFloat32 (address + 3416, true), memoryDataView.getFloat32 (address + 3420, true), memoryDataView.getFloat32 (address + 3424, true), memoryDataView.getFloat32 (address + 3428, true), memoryDataView.getFloat32 (address + 3432, true), memoryDataView.getFloat32 (address + 3436, true), memoryDataView.getFloat32 (address + 3440, true), memoryDataView.getFloat32 (address + 3444, true), memoryDataView.getFloat32 (address + 3448, true), memoryDataView.getFloat32 (address + 3452, true), memoryDataView.getFloat32 (address + 3456, true), memoryDataView.getFloat32 (address + 3460, true), memoryDataView.getFloat32 (address + 3464, true), memoryDataView.getFloat32 (address + 3468, true), memoryDataView.getFloat32 (address + 3472, true), memoryDataView.getFloat32 (address + 3476, true), memoryDataView.getFloat32 (address + 3480, true), memoryDataView.getFloat32 (address + 3484, true), memoryDataView.getFloat32 (address + 3488, true), memoryDataView.getFloat32 (address + 3492, true), memoryDataView.getFloat32 (address + 3496, true), memoryDataView.getFloat32 (address + 3500, true), memoryDataView.getFloat32 (address + 3504, true), memoryDataView.getFloat32 (address + 3508, true), memoryDataView.getFloat32 (address + 3512, true), memoryDataView.getFloat32 (address + 3516, true), memoryDataView.getFloat32 (address + 3520, true), memoryDataView.getFloat32 (address + 3524, true), memoryDataView.getFloat32 (address + 3528, true), memoryDataView.getFloat32 (address + 3532, true), memoryDataView.getFloat32 (address + 3536, true), memoryDataView.getFloat32 (address + 3540, true), memoryDataView.getFloat32 (address + 3544, true), memoryDataView.getFloat32 (address + 3548, true), memoryDataView.getFloat32 (address + 3552, true), memoryDataView.getFloat32 (address + 3556, true), memoryDataView.getFloat32 (address + 3560, true), memoryDataView.getFloat32 (address + 3564, true), memoryDataView.getFloat32 (address + 3568, true), memoryDataView.getFloat32 (address + 3572, true), memoryDataView.getFloat32 (address + 3576, true), memoryDataView.getFloat32 (address + 3580, true), memoryDataView.getFloat32 (address + 3584, true), memoryDataView.getFloat32 (address + 3588, true), memoryDataView.getFloat32 (address + 3592, true), memoryDataView.getFloat32 (address + 3596, true), memoryDataView.getFloat32 (address + 3600, true), memoryDataView.getFloat32 (address + 3604, true), memoryDataView.getFloat32 (address + 3608, true), memoryDataView.getFloat32 (address + 3612, true), memoryDataView.getFloat32 (address + 3616, true), memoryDataView.getFloat32 (address + 3620, true), memoryDataView.getFloat32 (address + 3624, true), memoryDataView.getFloat32 (address + 3628, true), memoryDataView.getFloat32 (address + 3632, true), memoryDataView.getFloat32 (address + 3636, true), memoryDataView.getFloat32 (address + 3640, true), memoryDataView.getFloat32 (address + 3644, true), memoryDataView.getFloat32 (address + 3648, true), memoryDataView.getFloat32 (address + 3652, true), memoryDataView.getFloat32 (address + 3656, true), memoryDataView.getFloat32 (address + 3660, true), memoryDataView.getFloat32 (address + 3664, true), memoryDataView.getFloat32 (address + 3668, true), memoryDataView.getFloat32 (address + 3672, true), memoryDataView.getFloat32 (address + 3676, true), memoryDataView.getFloat32 (address + 3680, true), memoryDataView.getFloat32 (address + 3684, true), memoryDataView.getFloat32 (address + 3688, true), memoryDataView.getFloat32 (address + 3692, true), memoryDataView.getFloat32 (address + 3696, true), memoryDataView.getFloat32 (address + 3700, true), memoryDataView.getFloat32 (address + 3704, true), memoryDataView.getFloat32 (address + 3708, true), memoryDataView.getFloat32 (address + 3712, true), memoryDataView.getFloat32 (address + 3716, true), memoryDataView.getFloat32 (address + 3720, true), memoryDataView.getFloat32 (address + 3724, true), memoryDataView.getFloat32 (address + 3728, true), memoryDataView.getFloat32 (address + 3732, true), memoryDataView.getFloat32 (address + 3736, true), memoryDataView.getFloat32 (address + 3740, true), memoryDataView.getFloat32 (address + 3744, true), memoryDataView.getFloat32 (address + 3748, true), memoryDataView.getFloat32 (address + 3752, true), memoryDataView.getFloat32 (address + 3756, true), memoryDataView.getFloat32 (address + 3760, true), memoryDataView.getFloat32 (address + 3764, true), memoryDataView.getFloat32 (address + 3768, true), memoryDataView.getFloat32 (address + 3772, true), memoryDataView.getFloat32 (address + 3776, true), memoryDataView.getFloat32 (address + 3780, true), memoryDataView.getFloat32 (address + 3784, true), memoryDataView.getFloat32 (address + 3788, true), memoryDataView.getFloat32 (address + 3792, true), memoryDataView.getFloat32 (address + 3796, true), memoryDataView.getFloat32 (address + 3800, true), memoryDataView.getFloat32 (address + 3804, true), memoryDataView.getFloat32 (address + 3808, true), memoryDataView.getFloat32 (address + 3812, true), memoryDataView.getFloat32 (address + 3816, true), memoryDataView.getFloat32 (address + 3820, true), memoryDataView.getFloat32 (address + 3824, true), memoryDataView.getFloat32 (address + 3828, true), memoryDataView.getFloat32 (address + 3832, true), memoryDataView.getFloat32 (address + 3836, true), memoryDataView.getFloat32 (address + 3840, true), memoryDataView.getFloat32 (address + 3844, true), memoryDataView.getFloat32 (address + 3848, true), memoryDataView.getFloat32 (address + 3852, true), memoryDataView.getFloat32 (address + 3856, true), memoryDataView.getFloat32 (address + 3860, true), memoryDataView.getFloat32 (address + 3864, true), memoryDataView.getFloat32 (address + 3868, true), memoryDataView.getFloat32 (address + 3872, true), memoryDataView.getFloat32 (address + 3876, true), memoryDataView.getFloat32 (address + 3880, true), memoryDataView.getFloat32 (address + 3884, true), memoryDataView.getFloat32 (address + 3888, true), memoryDataView.getFloat32 (address + 3892, true), memoryDataView.getFloat32 (address + 3896, true), memoryDataView.getFloat32 (address + 3900, true), memoryDataView.getFloat32 (address + 3904, true), memoryDataView.getFloat32 (address + 3908, true), memoryDataView.getFloat32 (address + 3912, true), memoryDataView.getFloat32 (address + 3916, true), memoryDataView.getFloat32 (address + 3920, true), memoryDataView.getFloat32 (address + 3924, true), memoryDataView.getFloat32 (address + 3928, true), memoryDataView.getFloat32 (address + 3932, true), memoryDataView.getFloat32 (address + 3936, true), memoryDataView.getFloat32 (address + 3940, true), memoryDataView.getFloat32 (address + 3944, true), memoryDataView.getFloat32 (address + 3948, true), memoryDataView.getFloat32 (address + 3952, true), memoryDataView.getFloat32 (address + 3956, true), memoryDataView.getFloat32 (address + 3960, true), memoryDataView.getFloat32 (address + 3964, true)]; + }; + } + + /** @access private */ + _getWasmBytesSIMD() + { + return new Uint8Array([0,97,115,109,1,0,0,0,1,203,128,128,128,0,12,96,2,127,127,0,96,2,127,125,0,96,1,125,1,125,96,3,127,124,124,0,96,2,125,127,1,125,96,1,124,1,124,96,4,127,127,127,124,0,96,4,127,124, + 124,124,0,96,7,127,124,124,124,127,127,127,0,96,3,127,127,127,1,127,96,3,127,127,127,0,96,1,127,1,125,2,201,128,128,128,0,4,3,101,110,118,15,95,95,108,105,110,101,97,114,95,109,101,109,111,114,121,2,0, + 1,3,101,110,118,15,95,95,115,116,97,99,107,95,112,111,105,110,116,101,114,3,127,1,3,101,110,118,6,109,101,109,115,101,116,0,9,3,101,110,118,6,109,101,109,99,112,121,0,9,3,167,128,128,128,0,38,0,1,1,1,2, + 3,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,1,1,1,1,1,1,6,7,8,10,11,11,7,216,133,128,128,0,30,17,95,115,101,110,100,69,118,101,110,116,95,109,105,100,105,73,110,0,2,16,95,115,101,110,100,69,118,101,110,116, + 95,112,111,119,101,114,0,3,21,95,115,101,110,100,69,118,101,110,116,95,109,97,115,116,101,114,71,97,105,110,0,4,23,95,115,101,110,100,69,118,101,110,116,95,109,97,115,116,101,114,79,99,116,97,118,101,0, + 5,22,95,115,101,110,100,69,118,101,110,116,95,109,97,115,116,101,114,71,108,105,100,101,0,9,24,95,115,101,110,100,69,118,101,110,116,95,118,99,111,49,83,101,109,105,116,111,110,101,115,0,10,21,95,115,101, + 110,100,69,118,101,110,116,95,118,99,111,49,68,101,116,117,110,101,0,11,20,95,115,101,110,100,69,118,101,110,116,95,118,99,111,49,76,101,118,101,108,0,12,20,95,115,101,110,100,69,118,101,110,116,95,118, + 99,111,49,83,104,97,112,101,0,13,24,95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,83,101,109,105,116,111,110,101,115,0,14,21,95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,68,101,116,117, + 110,101,0,15,20,95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,76,101,118,101,108,0,16,20,95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,83,104,97,112,101,0,17,24,95,115,101,110,100,69, + 118,101,110,116,95,118,99,111,51,83,101,109,105,116,111,110,101,115,0,18,21,95,115,101,110,100,69,118,101,110,116,95,118,99,111,51,68,101,116,117,110,101,0,19,20,95,115,101,110,100,69,118,101,110,116,95, + 118,99,111,51,76,101,118,101,108,0,20,20,95,115,101,110,100,69,118,101,110,116,95,118,99,111,51,83,104,97,112,101,0,21,23,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,67,117,116,111, + 102,102,0,22,26,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,82,101,115,111,110,97,110,99,101,0,23,22,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,69,103,73,110, + 116,0,24,22,95,115,101,110,100,69,118,101,110,116,95,97,109,112,69,103,65,116,116,97,99,107,0,25,21,95,115,101,110,100,69,118,101,110,116,95,97,109,112,69,103,68,101,99,97,121,0,26,23,95,115,101,110,100, + 69,118,101,110,116,95,97,109,112,69,103,83,117,115,116,97,105,110,0,28,23,95,115,101,110,100,69,118,101,110,116,95,97,109,112,69,103,82,101,108,101,97,115,101,0,29,25,95,115,101,110,100,69,118,101,110, + 116,95,102,105,108,116,101,114,69,103,65,116,116,97,99,107,0,30,24,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,69,103,68,101,99,97,121,0,31,26,95,115,101,110,100,69,118,101,110,116, + 95,102,105,108,116,101,114,69,103,83,117,115,116,97,105,110,0,32,26,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,69,103,82,101,108,101,97,115,101,0,33,10,105,110,105,116,105,97,108, + 105,115,101,0,34,12,97,100,118,97,110,99,101,66,108,111,99,107,0,37,12,129,128,128,128,0,2,10,240,136,129,128,0,38,141,5,6,3,127,1,125,2,127,1,125,1,127,1,124,32,0,65,188,34,106,33,2,2,64,2,64,2,64,2,64, + 32,1,40,2,0,34,1,65,128,128,192,7,113,34,3,65,128,128,192,4,71,13,0,32,1,65,255,1,113,69,13,0,32,2,32,0,65,180,35,106,34,3,40,2,0,65,12,108,106,34,4,32,1,65,8,118,65,255,0,113,178,34,5,56,2,4,32,4,32,1, + 65,16,118,65,15,113,54,2,0,32,4,32,1,65,255,0,113,178,67,4,2,1,60,148,56,2,8,32,0,65,184,35,106,34,1,32,1,40,2,0,65,1,106,54,2,0,32,3,32,3,40,2,0,65,1,106,65,10,111,34,1,65,10,106,32,1,32,1,65,0,72,27, + 54,2,0,65,204,94,33,1,65,149,94,33,3,12,1,11,2,64,32,3,65,128,128,128,4,70,13,0,32,1,65,255,129,192,7,113,65,128,128,192,4,71,13,3,11,65,0,33,6,65,0,33,7,2,64,32,0,65,180,35,106,40,2,0,34,4,65,127,106, + 65,0,72,13,0,32,1,65,8,118,65,255,0,113,178,33,8,65,0,33,7,65,0,33,1,3,64,2,64,2,64,32,2,32,1,65,12,108,106,34,3,42,2,4,34,5,32,8,94,32,5,32,8,93,114,65,1,71,13,0,32,2,32,7,65,12,108,106,34,9,32,5,56,2, + 4,32,9,32,3,42,2,8,56,2,8,32,9,32,3,40,2,0,54,2,0,32,7,65,1,106,65,10,111,34,3,65,10,106,32,3,32,3,65,0,72,27,33,7,12,1,11,32,0,32,0,40,2,184,35,65,127,106,54,2,184,35,11,32,1,65,1,106,65,10,111,34,1,65, + 10,106,32,1,32,1,65,0,72,27,33,1,32,4,65,127,106,34,4,65,1,78,13,0,11,11,32,0,32,7,54,2,180,35,2,64,32,0,65,184,35,106,40,2,0,13,0,65,149,94,33,1,12,2,11,32,2,32,7,65,127,106,65,10,111,34,1,65,10,106,32, + 1,32,1,65,0,72,27,65,12,108,106,42,2,4,33,5,65,149,94,33,1,65,204,94,33,3,11,65,1,33,6,32,0,65,208,0,106,65,1,58,0,0,32,0,65,32,106,32,5,56,2,0,32,2,32,3,106,65,1,58,0,0,32,0,65,24,106,42,2,0,34,8,67,0, + 0,0,0,94,33,3,2,64,2,64,65,0,43,3,128,128,128,128,0,32,8,187,162,34,10,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,10,170,33,4,12,1,11,65,128,128,128,128,120,33,4,11,32,0,65,40,106,32,4,65,1,32,3,27,34,3,54, + 2,0,32,0,65,36,106,32,5,32,0,65,28,106,42,2,0,147,32,3,178,149,56,2,0,11,32,2,32,1,106,32,6,58,0,0,32,0,65,137,1,106,32,6,58,0,0,11,11,158,1,3,1,127,2,125,2,127,32,0,65,152,3,106,32,1,56,2,0,32,0,65,148, + 3,106,34,2,42,2,0,33,3,32,2,32,1,56,2,0,2,64,2,64,67,10,215,163,60,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,163,182,149,34,4,139,67,0,0,0,79,93,69,13,0,32,4,168,33,2,12,1,11,65,128,128,128,128, + 120,33,2,11,32,0,65,160,3,106,34,5,40,2,0,33,6,32,5,32,2,65,1,32,2,65,1,74,27,34,2,54,2,0,32,0,65,156,3,106,34,0,32,1,32,3,32,0,42,2,0,32,6,178,148,147,147,32,2,178,149,56,2,0,11,158,1,3,1,127,2,125,2, + 127,32,0,65,132,3,106,32,1,56,2,0,32,0,65,128,3,106,34,2,42,2,0,33,3,32,2,32,1,56,2,0,2,64,2,64,67,10,215,163,60,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,163,182,149,34,4,139,67,0,0,0,79,93,69, + 13,0,32,4,168,33,2,12,1,11,65,128,128,128,128,120,33,2,11,32,0,65,140,3,106,34,5,40,2,0,33,6,32,5,32,2,65,1,32,2,65,1,74,27,34,2,54,2,0,32,0,65,136,3,106,34,0,32,1,32,3,32,0,42,2,0,32,6,178,148,147,147, + 32,2,178,149,56,2,0,11,213,1,1,1,124,32,0,65,236,1,106,32,1,67,0,0,64,65,148,34,1,56,2,0,32,0,65,216,1,106,65,0,43,3,128,128,128,128,0,34,2,32,1,32,0,65,240,1,106,42,2,0,146,32,0,65,244,1,106,42,2,0,146, + 32,0,65,248,1,106,42,2,0,146,16,134,128,128,128,0,187,16,135,128,128,128,0,32,0,65,164,2,106,32,1,56,2,0,32,0,65,144,2,106,32,2,32,1,32,0,65,168,2,106,42,2,0,146,32,0,65,172,2,106,42,2,0,146,32,0,65,176, + 2,106,42,2,0,146,16,134,128,128,128,0,187,16,135,128,128,128,0,32,0,65,220,2,106,32,1,56,2,0,32,0,65,200,2,106,32,2,32,1,32,0,65,224,2,106,42,2,0,146,32,0,65,228,2,106,42,2,0,146,32,0,65,232,2,106,42,2, + 0,146,16,134,128,128,128,0,187,16,135,128,128,128,0,11,147,5,5,1,125,2,127,2,125,2,127,1,125,2,64,2,64,32,0,67,0,0,138,194,146,67,171,170,170,61,148,34,1,188,34,2,65,255,255,255,255,7,113,34,3,13,0,67, + 0,0,128,63,33,0,12,1,11,2,64,32,3,65,129,128,128,252,7,72,13,0,32,1,67,0,0,0,64,146,33,0,12,1,11,2,64,2,64,32,3,65,128,128,128,252,3,70,13,0,32,3,65,128,128,128,252,7,71,13,1,32,1,67,0,0,0,0,32,2,65,127, + 74,27,33,0,12,2,11,67,0,0,0,64,67,0,0,0,63,32,2,65,127,74,27,33,0,12,1,11,2,64,32,2,65,128,128,128,248,3,70,13,0,67,0,0,128,64,33,0,32,2,65,128,128,128,128,4,70,13,1,2,64,32,3,65,129,128,128,232,4,72,13, + 0,67,0,0,128,127,67,0,0,0,0,32,2,65,0,74,27,33,0,12,2,11,67,0,0,128,127,33,0,32,1,67,0,0,0,0,148,32,1,32,2,65,128,96,113,190,34,4,147,146,34,5,32,4,146,34,1,188,34,3,65,128,128,128,152,4,74,13,1,2,64,2, + 64,32,3,65,128,128,128,152,4,71,13,0,32,5,67,60,170,56,51,146,32,1,32,4,147,94,13,3,32,1,188,65,255,255,255,255,7,113,33,2,12,1,11,67,0,0,0,0,33,0,32,1,188,65,255,255,255,255,7,113,34,2,65,128,128,216, + 152,4,74,13,2,32,3,65,128,128,216,152,124,71,13,0,32,5,32,1,32,4,147,95,13,2,11,65,0,33,6,2,64,32,2,65,128,128,128,248,3,76,13,0,65,0,65,128,128,128,4,32,2,65,23,118,65,130,127,106,118,32,3,106,34,2,65, + 255,255,255,3,113,65,128,128,128,4,114,65,150,1,32,2,65,23,118,65,255,1,113,34,7,107,118,34,6,107,32,6,32,3,65,0,72,27,33,6,32,5,32,4,65,128,128,128,124,32,7,65,129,127,106,117,32,2,113,190,147,34,4,146, + 188,33,3,11,2,64,32,6,65,23,116,32,3,65,128,128,126,113,190,34,0,67,0,114,49,63,148,34,8,32,0,67,140,190,191,53,148,32,5,32,0,32,4,147,147,67,24,114,49,63,148,146,34,4,146,34,0,32,0,32,0,32,0,32,0,148, + 34,1,32,1,32,1,32,1,32,1,67,76,187,49,51,148,67,14,234,221,181,146,148,67,85,179,138,56,146,148,67,97,11,54,187,146,148,67,171,170,42,62,146,148,147,34,1,148,32,1,67,0,0,0,192,146,149,32,4,32,0,32,8,147, + 147,34,1,32,0,32,1,148,146,147,147,67,0,0,128,63,146,34,0,188,106,34,3,65,255,255,255,3,74,13,0,32,0,32,6,16,136,128,128,128,0,33,0,12,2,11,32,3,190,33,0,12,1,11,67,243,4,181,63,33,0,11,32,0,67,0,0,220, + 67,148,11,237,3,4,1,126,1,127,2,126,1,127,2,64,2,64,32,2,32,1,163,34,1,189,34,3,66,52,136,167,65,255,15,113,34,4,65,255,15,71,13,0,32,1,32,1,163,33,1,12,1,11,2,64,32,3,66,255,255,255,255,255,255,255,255, + 255,0,131,34,5,66,128,128,128,128,128,128,128,248,63,85,13,0,32,1,68,0,0,0,0,0,0,0,0,162,32,1,32,5,66,128,128,128,128,128,128,128,248,63,81,27,33,1,12,1,11,2,64,2,64,32,4,13,0,65,0,33,4,2,64,32,3,66,12, + 134,34,5,66,0,83,13,0,3,64,32,4,65,127,106,33,4,32,5,66,1,134,34,5,66,127,85,13,0,11,11,32,3,65,1,32,4,107,173,134,33,5,12,1,11,32,3,66,255,255,255,255,255,255,255,7,131,66,128,128,128,128,128,128,128, + 8,132,33,5,11,2,64,2,64,2,64,32,4,65,128,8,72,13,0,32,4,65,1,106,33,4,3,64,2,64,32,5,66,128,128,128,128,128,128,128,120,124,34,6,66,0,83,13,0,32,6,33,5,32,6,80,13,3,11,32,5,66,1,134,33,5,32,4,65,127,106, + 34,4,65,128,8,74,13,0,11,65,255,7,33,4,11,2,64,2,64,2,64,2,64,32,5,66,128,128,128,128,128,128,128,120,124,34,6,66,0,83,13,0,32,6,33,5,32,6,80,13,1,11,32,5,66,255,255,255,255,255,255,255,7,88,13,1,32,5, + 33,6,12,2,11,32,1,68,0,0,0,0,0,0,0,0,162,33,1,12,4,11,3,64,32,4,65,127,106,33,4,32,5,66,128,128,128,128,128,128,128,4,84,33,7,32,5,66,1,134,34,6,33,5,32,7,13,0,11,11,32,3,66,128,128,128,128,128,128,128, + 128,128,127,131,33,5,2,64,32,4,65,1,72,13,0,32,6,66,128,128,128,128,128,128,128,120,124,32,4,173,66,52,134,132,33,6,12,2,11,32,6,65,1,32,4,107,173,135,33,6,12,1,11,32,1,68,0,0,0,0,0,0,0,0,162,33,1,12,1, + 11,32,6,32,5,132,191,33,1,11,32,0,32,1,182,56,2,4,11,160,1,0,2,64,2,64,2,64,32,1,65,128,1,72,13,0,32,0,67,0,0,0,127,148,33,0,32,1,65,254,1,75,13,1,32,1,65,129,127,106,33,1,12,2,11,32,1,65,130,127,78,13, + 1,32,0,67,0,0,128,12,148,33,0,2,64,32,1,65,155,126,77,13,0,32,1,65,230,0,106,33,1,12,2,11,32,0,67,0,0,128,12,148,33,0,32,1,65,182,125,32,1,65,182,125,74,27,65,204,1,106,33,1,12,1,11,32,0,67,0,0,0,127,148, + 33,0,32,1,65,253,2,32,1,65,253,2,72,27,65,130,126,106,33,1,11,32,0,32,1,65,23,116,65,128,128,128,252,3,106,190,148,11,12,0,32,0,65,24,106,32,1,56,2,0,11,73,0,32,0,65,244,1,106,32,1,56,2,0,32,0,65,216,1, + 106,65,0,43,3,128,128,128,128,0,32,0,65,248,1,106,42,2,0,32,0,65,236,1,106,42,2,0,32,0,65,240,1,106,42,2,0,146,32,1,146,146,16,134,128,128,128,0,187,16,135,128,128,128,0,11,81,0,32,0,65,248,1,106,32,1, + 67,10,215,35,60,148,34,1,56,2,0,32,0,65,216,1,106,65,0,43,3,128,128,128,128,0,32,1,32,0,65,236,1,106,42,2,0,32,0,65,240,1,106,42,2,0,146,32,0,65,244,1,106,42,2,0,146,146,16,134,128,128,128,0,187,16,135, + 128,128,128,0,11,158,1,3,1,127,2,125,2,127,32,0,65,128,2,106,32,1,56,2,0,32,0,65,252,1,106,34,2,42,2,0,33,3,32,2,32,1,56,2,0,2,64,2,64,67,10,215,163,60,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0, + 163,182,149,34,4,139,67,0,0,0,79,93,69,13,0,32,4,168,33,2,12,1,11,65,128,128,128,128,120,33,2,11,32,0,65,136,2,106,34,5,40,2,0,33,6,32,5,32,2,65,1,32,2,65,1,74,27,34,2,54,2,0,32,0,65,132,2,106,34,0,32, + 1,32,3,32,0,42,2,0,32,6,178,148,147,147,32,2,178,149,56,2,0,11,59,1,1,127,2,64,2,64,32,1,142,34,1,139,67,0,0,0,79,93,69,13,0,32,1,168,33,2,12,1,11,65,128,128,128,128,120,33,2,11,32,0,65,228,1,106,32,2, + 65,4,32,2,65,4,73,27,54,2,0,11,73,0,32,0,65,172,2,106,32,1,56,2,0,32,0,65,144,2,106,65,0,43,3,128,128,128,128,0,32,0,65,176,2,106,42,2,0,32,0,65,164,2,106,42,2,0,32,0,65,168,2,106,42,2,0,146,32,1,146,146, + 16,134,128,128,128,0,187,16,135,128,128,128,0,11,81,0,32,0,65,176,2,106,32,1,67,10,215,35,60,148,34,1,56,2,0,32,0,65,144,2,106,65,0,43,3,128,128,128,128,0,32,1,32,0,65,164,2,106,42,2,0,32,0,65,168,2,106, + 42,2,0,146,32,0,65,172,2,106,42,2,0,146,146,16,134,128,128,128,0,187,16,135,128,128,128,0,11,158,1,3,1,127,2,125,2,127,32,0,65,184,2,106,32,1,56,2,0,32,0,65,180,2,106,34,2,42,2,0,33,3,32,2,32,1,56,2,0, + 2,64,2,64,67,10,215,163,60,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,163,182,149,34,4,139,67,0,0,0,79,93,69,13,0,32,4,168,33,2,12,1,11,65,128,128,128,128,120,33,2,11,32,0,65,192,2,106,34,5,40,2, + 0,33,6,32,5,32,2,65,1,32,2,65,1,74,27,34,2,54,2,0,32,0,65,188,2,106,34,0,32,1,32,3,32,0,42,2,0,32,6,178,148,147,147,32,2,178,149,56,2,0,11,59,1,1,127,2,64,2,64,32,1,142,34,1,139,67,0,0,0,79,93,69,13,0, + 32,1,168,33,2,12,1,11,65,128,128,128,128,120,33,2,11,32,0,65,156,2,106,32,2,65,4,32,2,65,4,73,27,54,2,0,11,73,0,32,0,65,228,2,106,32,1,56,2,0,32,0,65,200,2,106,65,0,43,3,128,128,128,128,0,32,0,65,232,2, + 106,42,2,0,32,0,65,220,2,106,42,2,0,32,0,65,224,2,106,42,2,0,146,32,1,146,146,16,134,128,128,128,0,187,16,135,128,128,128,0,11,81,0,32,0,65,232,2,106,32,1,67,10,215,35,60,148,34,1,56,2,0,32,0,65,200,2, + 106,65,0,43,3,128,128,128,128,0,32,1,32,0,65,220,2,106,42,2,0,32,0,65,224,2,106,42,2,0,146,32,0,65,228,2,106,42,2,0,146,146,16,134,128,128,128,0,187,16,135,128,128,128,0,11,158,1,3,1,127,2,125,2,127,32, + 0,65,240,2,106,32,1,56,2,0,32,0,65,236,2,106,34,2,42,2,0,33,3,32,2,32,1,56,2,0,2,64,2,64,67,10,215,163,60,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,163,182,149,34,4,139,67,0,0,0,79,93,69,13,0,32, + 4,168,33,2,12,1,11,65,128,128,128,128,120,33,2,11,32,0,65,248,2,106,34,5,40,2,0,33,6,32,5,32,2,65,1,32,2,65,1,74,27,34,2,54,2,0,32,0,65,244,2,106,34,0,32,1,32,3,32,0,42,2,0,32,6,178,148,147,147,32,2,178, + 149,56,2,0,11,59,1,1,127,2,64,2,64,32,1,142,34,1,139,67,0,0,0,79,93,69,13,0,32,1,168,33,2,12,1,11,65,128,128,128,128,120,33,2,11,32,0,65,212,2,106,32,2,65,4,32,2,65,4,73,27,54,2,0,11,13,0,32,0,65,204,1, + 106,32,1,56,2,0,11,36,0,32,0,65,184,1,106,65,1,58,0,0,32,0,65,192,1,106,32,1,67,205,204,76,61,148,67,0,0,0,63,146,56,2,0,11,13,0,32,0,65,208,1,106,32,1,56,2,0,11,47,0,32,0,65,48,106,68,0,0,0,0,0,0,240, + 63,65,0,43,3,128,128,128,128,0,67,111,18,131,58,32,1,32,1,67,111,18,131,58,93,27,187,162,163,57,3,0,11,53,0,32,0,65,56,106,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,67,111,18,131,58,32,1,32,1,67, + 111,18,131,58,93,27,187,162,163,16,155,128,128,128,0,57,3,0,11,202,7,3,1,126,3,127,3,124,2,64,32,0,189,34,1,66,32,136,167,34,2,65,255,255,255,255,7,113,34,3,32,1,167,34,4,114,13,0,68,0,0,0,0,0,0,240,63, + 15,11,2,64,2,64,32,3,65,128,128,192,255,7,75,13,0,32,4,65,0,71,32,3,65,128,128,192,255,7,70,113,69,13,1,11,32,0,68,45,67,28,235,226,54,26,63,160,15,11,2,64,2,64,2,64,2,64,2,64,32,4,13,0,32,3,65,128,128, + 192,255,7,70,13,1,2,64,32,3,65,128,128,192,255,3,71,13,0,68,45,67,28,235,226,54,26,63,68,0,0,0,0,0,136,195,64,32,1,66,127,85,27,15,11,32,2,65,128,128,128,255,3,70,13,3,68,58,140,48,226,142,121,69,62,33, + 5,32,2,65,128,128,128,128,4,70,13,4,11,2,64,32,3,65,129,128,128,143,4,73,13,0,68,0,0,0,0,0,0,240,127,68,0,0,0,0,0,0,0,0,32,1,66,0,83,27,15,11,32,1,66,128,128,128,128,112,131,191,34,5,68,0,0,0,0,79,147, + 42,192,162,34,6,32,0,68,235,164,171,226,70,243,146,190,162,32,0,32,5,161,68,0,0,0,0,79,147,42,192,162,160,34,0,160,34,7,189,34,1,167,33,4,2,64,32,1,66,32,136,167,34,3,65,128,128,192,132,4,72,13,0,68,0, + 0,0,0,0,0,240,127,33,5,32,3,65,128,128,192,251,123,106,32,4,114,13,4,32,0,68,254,130,43,101,71,21,151,60,160,32,7,32,6,161,100,13,4,12,2,11,32,3,65,128,248,255,255,7,113,65,255,151,195,132,4,77,13,1,68, + 0,0,0,0,0,0,0,0,33,5,32,0,32,7,32,6,161,101,13,3,32,3,65,128,232,188,251,3,106,32,4,114,13,3,12,1,11,68,0,0,0,0,0,0,0,0,32,0,154,32,1,66,127,85,27,15,11,65,0,33,4,2,64,32,3,65,255,255,255,255,7,113,34, + 2,65,128,128,128,255,3,77,13,0,65,0,65,128,128,192,0,32,2,65,20,118,65,130,120,106,118,32,3,106,34,3,65,255,255,63,113,65,128,128,192,0,114,65,147,8,32,3,65,20,118,65,255,15,113,34,2,107,118,34,4,107,32, + 4,32,1,66,0,83,27,33,4,32,0,32,6,65,128,128,64,32,2,65,129,120,106,117,32,3,113,173,66,32,134,191,161,34,6,160,189,33,1,11,2,64,2,64,2,64,32,4,65,20,116,32,1,66,128,128,128,128,112,131,191,34,5,68,0,0, + 0,0,67,46,230,63,162,34,7,32,0,32,5,32,6,161,161,68,239,57,250,254,66,46,230,63,162,32,5,68,57,108,168,12,97,92,32,190,162,160,34,5,160,34,0,32,0,32,0,32,0,32,0,162,34,6,32,6,32,6,32,6,32,6,68,208,164, + 190,114,105,55,102,62,162,68,241,107,210,197,65,189,187,190,160,162,68,44,222,37,175,106,86,17,63,160,162,68,147,189,190,22,108,193,102,191,160,162,68,62,85,85,85,85,85,197,63,160,162,161,34,6,162,32,6, + 68,0,0,0,0,0,0,0,192,160,163,32,5,32,0,32,7,161,161,34,6,32,0,32,6,162,160,161,161,68,0,0,0,0,0,0,240,63,160,34,0,189,34,1,66,32,136,167,106,34,3,65,255,255,63,74,13,0,2,64,32,4,65,128,8,72,13,0,32,0,68, + 0,0,0,0,0,0,224,127,162,33,0,32,4,65,254,15,75,13,2,32,4,65,129,120,106,33,4,12,3,11,32,4,65,130,120,78,13,2,32,0,68,0,0,0,0,0,0,96,3,162,33,0,2,64,32,4,65,184,112,77,13,0,32,4,65,201,7,106,33,4,12,3,11, + 32,0,68,0,0,0,0,0,0,96,3,162,33,0,32,4,65,240,104,32,4,65,240,104,74,27,65,146,15,106,33,4,12,2,11,32,3,173,66,32,134,32,1,66,255,255,255,255,15,131,132,191,15,11,32,0,68,0,0,0,0,0,0,224,127,162,33,0,32, + 4,65,253,23,32,4,65,253,23,72,27,65,130,112,106,33,4,11,32,0,32,4,65,255,7,106,173,66,52,134,191,162,15,11,68,123,20,174,71,225,122,132,63,33,5,11,32,5,11,24,0,32,0,65,192,0,106,32,1,187,68,123,20,174, + 71,225,122,132,63,162,57,3,0,11,54,0,32,0,65,200,0,106,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,67,111,18,131,58,32,1,32,1,67,111,18,131,58,93,27,187,162,163,16,155,128,128,128,0,57,3,0,11,48, + 0,32,0,65,232,0,106,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,67,111,18,131,58,32,1,32,1,67,111,18,131,58,93,27,187,162,163,57,3,0,11,54,0,32,0,65,240,0,106,68,0,0,0,0,0,0,240,63,65,0,43,3,128, + 128,128,128,0,67,111,18,131,58,32,1,32,1,67,111,18,131,58,93,27,187,162,163,16,155,128,128,128,0,57,3,0,11,24,0,32,0,65,248,0,106,32,1,187,68,123,20,174,71,225,122,132,63,162,57,3,0,11,54,0,32,0,65,128, + 1,106,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,67,111,18,131,58,32,1,32,1,67,111,18,131,58,93,27,187,162,163,16,155,128,128,128,0,57,3,0,11,255,3,4,2,127,1,123,1,125,1,123,35,128,128,128,128,0, + 65,32,107,34,4,36,128,128,128,128,0,32,0,65,208,0,106,65,0,59,0,0,32,0,65,24,106,65,0,54,2,0,32,0,65,136,1,106,65,0,59,0,0,32,0,65,200,0,106,66,171,142,218,200,237,249,253,247,63,55,3,0,32,0,65,192,0,106, + 66,128,128,128,128,128,128,128,248,63,55,3,0,32,0,65,56,106,66,174,143,133,215,199,194,235,247,63,55,3,0,32,0,65,48,106,66,251,168,184,189,148,220,158,194,63,55,3,0,32,0,65,188,1,106,66,128,128,232,163, + 244,158,193,154,63,55,2,0,32,0,65,184,1,106,65,0,58,0,0,32,0,65,128,1,106,66,171,142,218,200,237,249,253,247,63,55,3,0,32,0,65,248,0,106,66,128,128,128,128,128,128,128,248,63,55,3,0,32,0,65,240,0,106,66, + 174,143,133,215,199,194,235,247,63,55,3,0,32,0,65,232,0,106,66,251,168,184,189,148,220,158,194,63,55,3,0,32,4,65,24,106,34,5,66,0,55,3,0,32,4,253,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,6,253,11,3,8,32,4, + 65,8,106,32,3,68,0,0,0,0,0,64,143,64,68,0,0,0,224,158,160,230,63,16,163,128,128,128,0,32,5,42,2,0,33,7,32,4,253,0,3,8,33,8,32,4,40,2,28,33,5,32,0,65,228,1,106,65,0,54,2,0,32,0,65,180,1,106,32,5,54,2,0, + 32,0,65,176,1,106,32,7,56,2,0,32,0,65,160,1,106,32,8,253,11,2,0,32,0,65,216,1,106,32,3,68,0,0,0,0,0,128,123,64,16,135,128,128,128,0,32,0,65,156,2,106,65,0,54,2,0,32,0,65,144,2,106,32,3,68,0,0,0,0,0,128, + 123,64,16,135,128,128,128,0,32,0,65,212,2,106,65,0,54,2,0,32,0,65,200,2,106,32,3,68,0,0,0,0,0,128,123,64,16,135,128,128,128,0,32,0,65,148,3,106,32,6,253,11,2,0,65,0,32,3,57,3,128,128,128,128,0,32,0,65, + 184,35,106,65,0,54,2,0,32,4,65,32,106,36,128,128,128,128,0,11,179,22,6,1,127,2,124,1,126,2,127,3,124,1,127,35,128,128,128,128,0,65,32,107,34,4,36,128,128,128,128,0,2,64,2,64,68,0,0,0,0,0,0,224,63,32,1, + 163,34,5,32,1,68,184,30,133,235,81,184,222,63,162,34,6,68,0,0,0,0,0,0,0,0,32,2,32,2,68,0,0,0,0,0,0,0,0,99,27,32,6,32,2,99,27,68,24,45,68,84,251,33,25,64,162,162,34,2,189,34,7,66,32,136,167,34,8,65,255, + 255,255,255,7,113,34,9,65,251,195,164,255,3,75,13,0,32,9,65,128,128,128,242,3,73,13,1,65,0,33,9,2,64,32,7,66,128,128,128,128,128,255,255,255,255,0,131,66,129,128,128,128,240,132,229,242,63,84,34,8,13,0, + 68,24,45,68,84,251,33,233,63,32,2,154,32,2,32,7,66,0,83,27,161,68,7,92,20,51,38,166,129,60,160,33,2,32,7,66,63,136,167,33,9,11,32,2,32,2,32,2,32,2,162,34,10,162,34,11,68,99,85,85,85,85,85,213,63,162,32, + 10,32,11,32,10,32,10,162,34,6,32,6,32,6,32,6,32,6,68,115,83,96,219,203,117,243,190,162,68,166,146,55,160,136,126,20,63,160,162,68,1,101,242,242,216,68,67,63,160,162,68,40,3,86,201,34,109,109,63,160,162, + 68,55,214,6,132,244,100,150,63,160,162,68,122,254,16,17,17,17,193,63,160,32,10,32,6,32,6,32,6,32,6,32,6,68,212,122,191,116,112,42,251,62,162,68,233,167,240,50,15,184,18,63,160,162,68,104,16,141,26,247, + 38,48,63,160,162,68,21,131,224,254,200,219,87,63,160,162,68,147,132,110,233,227,38,130,63,160,162,68,254,65,179,27,186,161,171,63,160,162,160,162,68,0,0,0,0,0,0,0,0,160,162,68,0,0,0,0,0,0,0,0,160,160,34, + 10,160,33,6,2,64,32,8,69,13,0,32,6,33,2,12,2,11,68,0,0,0,0,0,0,240,63,32,2,32,10,32,6,32,6,162,32,6,68,0,0,0,0,0,0,240,63,160,163,161,160,34,2,32,2,160,161,34,2,154,32,2,32,9,27,33,2,12,1,11,2,64,32,9, + 65,255,255,191,255,7,75,13,0,2,64,2,64,2,64,32,9,65,250,212,189,128,4,75,13,0,2,64,32,8,65,255,255,63,113,65,251,195,36,71,13,0,2,64,32,9,65,20,118,34,9,32,2,32,2,68,131,200,201,109,48,95,228,63,162,68, + 0,0,0,0,0,0,56,67,160,68,0,0,0,0,0,0,56,195,160,34,10,68,0,0,64,84,251,33,249,191,162,160,34,2,32,10,68,49,99,98,26,97,180,208,61,162,34,11,161,34,6,189,66,52,136,167,65,255,15,113,107,65,17,72,13,0,2, + 64,32,9,32,2,32,10,68,0,0,96,26,97,180,208,61,162,34,6,161,34,12,32,10,68,115,112,3,46,138,25,163,59,162,32,2,32,12,161,32,6,161,161,34,11,161,34,6,189,66,52,136,167,65,255,15,113,107,65,50,78,13,0,32, + 12,33,2,12,1,11,32,12,32,10,68,0,0,0,46,138,25,163,59,162,34,6,161,34,2,32,10,68,193,73,32,37,154,131,123,57,162,32,12,32,2,161,32,6,161,161,34,11,161,33,6,11,32,2,32,6,161,32,11,161,33,11,2,64,32,10,153, + 68,0,0,0,0,0,0,224,65,99,69,13,0,32,10,170,33,9,12,4,11,65,128,128,128,128,120,33,9,12,3,11,2,64,32,9,65,252,178,139,128,4,75,13,0,2,64,32,7,66,127,87,13,0,32,2,68,0,0,64,84,251,33,249,191,160,34,2,32, + 2,68,49,99,98,26,97,180,208,189,160,34,6,161,68,49,99,98,26,97,180,208,189,160,33,11,65,1,33,9,12,4,11,32,2,68,0,0,64,84,251,33,249,63,160,34,2,32,2,68,49,99,98,26,97,180,208,61,160,34,6,161,68,49,99,98, + 26,97,180,208,61,160,33,11,65,127,33,9,12,3,11,32,7,66,127,85,13,1,32,2,68,0,0,64,84,251,33,9,64,160,34,2,32,2,68,49,99,98,26,97,180,224,61,160,34,6,161,68,49,99,98,26,97,180,224,61,160,33,11,65,126,33, + 9,12,2,11,2,64,2,64,2,64,2,64,2,64,32,9,65,188,140,241,128,4,73,13,0,32,9,65,251,195,228,137,4,79,13,3,32,9,65,20,118,34,9,32,2,32,2,68,131,200,201,109,48,95,228,63,162,68,0,0,0,0,0,0,56,67,160,68,0,0, + 0,0,0,0,56,195,160,34,10,68,0,0,64,84,251,33,249,191,162,160,34,2,32,10,68,49,99,98,26,97,180,208,61,162,34,11,161,34,6,189,66,52,136,167,65,255,15,113,107,65,17,72,13,2,32,9,32,2,32,10,68,0,0,96,26,97, + 180,208,61,162,34,6,161,34,12,32,10,68,115,112,3,46,138,25,163,59,162,32,2,32,12,161,32,6,161,161,34,11,161,34,6,189,66,52,136,167,65,255,15,113,107,65,50,78,13,1,32,12,33,2,12,2,11,2,64,2,64,2,64,2,64, + 32,9,65,189,251,215,128,4,73,13,0,32,9,65,251,195,228,128,4,71,13,3,32,2,32,2,68,131,200,201,109,48,95,228,63,162,68,0,0,0,0,0,0,56,67,160,68,0,0,0,0,0,0,56,195,160,34,10,68,0,0,64,84,251,33,249,191,162, + 160,34,2,32,10,68,49,99,98,26,97,180,208,61,162,34,11,161,34,6,189,66,128,128,128,128,128,128,128,248,255,0,131,66,255,255,255,255,255,255,255,135,63,86,13,2,32,2,32,10,68,0,0,96,26,97,180,208,61,162,34, + 6,161,34,12,32,10,68,115,112,3,46,138,25,163,59,162,32,2,32,12,161,32,6,161,161,34,11,161,34,6,189,66,128,128,128,128,128,128,128,128,255,0,131,66,255,255,255,255,255,255,255,255,60,88,13,1,32,12,33,2, + 12,2,11,32,9,65,252,178,203,128,4,70,13,6,2,64,32,7,66,0,83,13,0,32,2,68,0,0,48,127,124,217,18,192,160,34,2,32,2,68,202,148,147,167,145,14,233,189,160,34,6,161,68,202,148,147,167,145,14,233,189,160,33, + 11,65,3,33,9,12,9,11,32,2,68,0,0,48,127,124,217,18,64,160,34,2,32,2,68,202,148,147,167,145,14,233,61,160,34,6,161,68,202,148,147,167,145,14,233,61,160,33,11,65,125,33,9,12,8,11,32,12,32,10,68,0,0,0,46, + 138,25,163,59,162,34,6,161,34,2,32,10,68,193,73,32,37,154,131,123,57,162,32,12,32,2,161,32,6,161,161,34,11,161,33,6,11,32,2,32,6,161,32,11,161,33,11,2,64,32,10,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,10, + 170,33,9,12,7,11,65,128,128,128,128,120,33,9,12,6,11,2,64,32,7,66,0,83,13,0,32,2,68,0,0,64,84,251,33,25,192,160,34,2,32,2,68,49,99,98,26,97,180,240,189,160,34,6,161,68,49,99,98,26,97,180,240,189,160,33, + 11,65,4,33,9,12,6,11,32,2,68,0,0,64,84,251,33,25,64,160,34,2,32,2,68,49,99,98,26,97,180,240,61,160,34,6,161,68,49,99,98,26,97,180,240,61,160,33,11,65,124,33,9,12,5,11,32,12,32,10,68,0,0,0,46,138,25,163, + 59,162,34,6,161,34,2,32,10,68,193,73,32,37,154,131,123,57,162,32,12,32,2,161,32,6,161,161,34,11,161,33,6,11,32,2,32,6,161,32,11,161,33,11,2,64,32,10,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,10,170,33,9, + 12,4,11,65,128,128,128,128,120,33,9,12,3,11,2,64,2,64,32,7,66,255,255,255,255,255,255,255,7,131,66,128,128,128,128,128,128,128,176,193,0,132,191,34,2,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,2,170,33,8, + 12,1,11,65,128,128,128,128,120,33,8,11,2,64,2,64,32,2,32,8,183,34,6,161,68,0,0,0,0,0,0,112,65,162,34,2,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,2,170,33,13,12,1,11,65,128,128,128,128,120,33,13,11,32,4,65, + 8,106,32,6,32,13,183,34,10,32,2,32,10,161,68,0,0,0,0,0,0,112,65,162,34,2,32,9,65,20,118,65,234,119,106,65,3,65,2,32,8,65,0,71,32,13,27,32,2,68,0,0,0,0,0,0,0,0,100,32,2,68,0,0,0,0,0,0,0,0,99,114,27,65,1, + 16,164,128,128,128,0,32,4,43,3,24,33,11,32,4,43,3,16,33,6,32,4,40,2,8,33,9,32,7,66,127,85,13,2,65,0,32,9,107,33,9,32,11,154,33,11,32,6,154,33,6,12,2,11,2,64,32,2,32,2,68,131,200,201,109,48,95,228,63,162, + 68,0,0,0,0,0,0,56,67,160,68,0,0,0,0,0,0,56,195,160,34,10,68,0,0,64,84,251,33,249,191,162,160,34,2,32,10,68,49,99,98,26,97,180,208,61,162,34,11,161,34,6,189,66,128,128,128,128,128,128,128,248,255,0,131, + 66,255,255,255,255,255,255,255,135,63,86,13,0,2,64,32,2,32,10,68,0,0,96,26,97,180,208,61,162,34,6,161,34,12,32,10,68,115,112,3,46,138,25,163,59,162,32,2,32,12,161,32,6,161,161,34,11,161,34,6,189,66,128, + 128,128,128,128,128,128,128,255,0,131,66,255,255,255,255,255,255,255,255,60,88,13,0,32,12,33,2,12,1,11,32,12,32,10,68,0,0,0,46,138,25,163,59,162,34,6,161,34,2,32,10,68,193,73,32,37,154,131,123,57,162,32, + 12,32,2,161,32,6,161,161,34,11,161,33,6,11,32,2,32,6,161,32,11,161,33,11,2,64,32,10,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,10,170,33,9,12,2,11,65,128,128,128,128,120,33,9,12,1,11,32,2,68,0,0,64,84,251, + 33,9,192,160,34,2,32,2,68,49,99,98,26,97,180,224,189,160,34,6,161,68,49,99,98,26,97,180,224,189,160,33,11,65,2,33,9,11,65,0,33,8,2,64,32,6,189,34,7,66,128,128,128,128,128,255,255,255,255,0,131,66,129,128, + 128,128,240,132,229,242,63,84,34,13,13,0,68,24,45,68,84,251,33,233,63,32,6,154,32,6,32,7,66,0,83,34,8,27,161,68,7,92,20,51,38,166,129,60,32,11,154,32,11,32,8,27,161,160,33,6,32,7,66,63,136,167,33,8,68, + 0,0,0,0,0,0,0,0,33,11,11,32,9,65,1,113,33,9,32,6,32,6,32,6,32,6,162,34,10,162,34,12,68,99,85,85,85,85,85,213,63,162,32,11,32,10,32,11,32,12,32,10,32,10,162,34,2,32,2,32,2,32,2,32,2,68,115,83,96,219,203, + 117,243,190,162,68,166,146,55,160,136,126,20,63,160,162,68,1,101,242,242,216,68,67,63,160,162,68,40,3,86,201,34,109,109,63,160,162,68,55,214,6,132,244,100,150,63,160,162,68,122,254,16,17,17,17,193,63,160, + 32,10,32,2,32,2,32,2,32,2,32,2,68,212,122,191,116,112,42,251,62,162,68,233,167,240,50,15,184,18,63,160,162,68,104,16,141,26,247,38,48,63,160,162,68,21,131,224,254,200,219,87,63,160,162,68,147,132,110,233, + 227,38,130,63,160,162,68,254,65,179,27,186,161,171,63,160,162,160,162,160,162,160,160,34,10,160,33,2,2,64,32,13,13,0,65,1,32,9,65,1,116,107,183,34,11,32,6,32,10,32,2,32,2,162,32,2,32,11,160,163,161,160, + 34,2,32,2,160,161,34,2,154,32,2,32,8,27,33,2,12,2,11,32,9,69,13,1,68,0,0,0,0,0,0,240,191,32,2,163,34,11,32,2,189,66,128,128,128,128,112,131,191,34,12,32,11,189,66,128,128,128,128,112,131,191,34,2,162,68, + 0,0,0,0,0,0,240,63,160,32,10,32,12,32,6,161,161,32,2,162,160,162,32,2,160,33,2,12,1,11,32,2,32,2,161,33,2,11,32,0,32,5,32,1,32,1,160,32,2,162,162,34,2,182,56,2,4,32,0,68,0,0,0,0,0,0,240,63,32,3,163,34, + 1,32,2,160,182,56,2,8,32,0,68,0,0,0,0,0,0,240,63,32,2,32,2,162,32,1,32,2,162,68,0,0,0,0,0,0,240,63,160,160,163,182,56,2,0,32,4,65,32,106,36,128,128,128,128,0,11,188,24,9,10,127,1,124,1,127,1,123,4,127, + 1,124,7,127,1,124,3,127,35,128,128,128,128,0,65,176,4,107,34,7,36,128,128,128,128,0,32,7,66,128,128,128,128,208,227,252,180,53,55,3,168,4,32,7,66,128,128,128,128,168,196,224,241,54,55,3,160,4,32,7,66,128, + 128,128,128,132,164,137,189,56,55,3,152,4,32,7,66,128,128,128,128,184,240,134,248,57,55,3,144,4,32,7,66,128,128,128,128,150,138,179,188,59,55,3,136,4,32,7,66,128,128,128,128,136,211,145,252,60,55,3,128, + 4,32,7,66,128,128,128,128,208,133,145,186,62,55,3,248,3,32,7,66,128,128,128,128,180,191,200,252,63,55,3,240,3,65,0,33,8,32,7,65,240,2,106,65,0,65,128,1,16,128,128,128,128,0,26,32,7,65,240,1,106,65,0,65, + 128,1,16,128,128,128,128,0,26,32,7,65,240,0,106,65,0,65,128,1,16,128,128,128,128,0,26,32,4,65,125,106,65,24,109,34,9,65,0,32,9,65,0,74,27,34,10,65,104,108,32,4,106,33,11,2,64,32,6,65,3,106,34,12,32,5,65, + 127,106,34,13,106,65,0,72,13,0,32,10,65,2,116,32,5,65,2,116,107,65,148,128,128,128,0,106,33,9,32,6,32,5,106,65,3,106,33,14,32,10,32,13,107,34,15,33,4,3,64,32,4,65,194,0,110,33,16,2,64,2,64,32,15,32,8,106, + 65,127,74,13,0,68,0,0,0,0,0,0,0,0,33,17,12,1,11,32,9,32,16,65,248,125,108,106,40,2,0,183,33,17,11,32,7,65,240,2,106,32,8,65,15,113,65,3,116,106,32,17,57,3,0,32,9,65,4,106,33,9,32,4,65,1,106,33,4,32,14, + 32,8,65,1,106,34,8,71,13,0,11,11,32,11,65,104,106,33,18,2,64,32,6,65,124,76,13,0,65,0,33,8,32,12,65,0,32,12,65,0,74,27,33,14,2,64,32,5,65,0,74,13,0,32,14,65,1,106,33,4,3,64,32,7,65,240,0,106,32,8,65,15, + 113,65,3,116,106,66,0,55,3,0,32,4,32,8,65,1,106,34,8,71,13,0,12,2,11,11,65,0,33,16,3,64,68,0,0,0,0,0,0,0,0,33,17,32,7,65,216,0,106,33,8,32,13,33,4,65,0,33,9,3,64,32,7,32,3,57,3,104,32,7,32,2,57,3,96,32, + 7,32,1,57,3,88,32,17,32,8,32,9,65,3,110,65,104,108,106,43,3,0,32,7,65,240,2,106,32,16,32,4,106,65,15,113,65,3,116,106,43,3,0,162,160,33,17,32,8,65,8,106,33,8,32,9,65,1,106,33,9,32,4,65,127,106,34,4,65, + 127,71,13,0,11,32,7,65,240,0,106,32,16,65,15,113,65,3,116,106,32,17,57,3,0,32,16,32,14,70,33,8,32,16,65,1,106,33,16,32,8,69,13,0,11,11,32,7,65,24,106,65,48,106,253,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34, + 19,253,11,3,0,32,7,65,56,106,32,19,253,11,3,0,32,7,65,40,106,32,19,253,11,3,0,32,7,32,19,253,11,3,24,68,0,0,0,0,0,0,240,127,68,0,0,0,0,0,0,224,127,32,18,65,254,15,75,34,20,27,68,0,0,0,0,0,0,0,0,68,0,0, + 0,0,0,0,96,3,32,18,65,185,112,73,34,21,27,68,0,0,0,0,0,0,240,63,32,18,65,130,120,72,34,8,27,32,18,65,255,7,74,34,4,27,32,18,65,253,23,32,18,65,253,23,72,27,65,130,112,106,32,11,65,233,119,106,32,20,27, + 34,22,32,18,65,240,104,32,18,65,240,104,74,27,65,146,15,106,32,11,65,177,7,106,32,21,27,34,23,32,18,32,8,27,32,4,27,65,255,7,106,173,66,52,134,191,162,33,24,32,6,65,2,106,33,25,65,47,32,11,107,33,26,65, + 48,32,11,107,33,27,32,18,65,128,8,72,33,28,32,11,65,103,106,33,29,32,18,65,129,120,74,33,30,32,12,33,14,2,64,3,64,32,7,65,240,0,106,32,14,34,16,65,15,113,34,31,65,3,116,106,43,3,0,33,17,2,64,32,16,65,1, + 72,34,15,13,0,32,16,65,15,106,33,8,65,0,33,4,3,64,32,4,65,15,113,65,2,116,33,9,2,64,2,64,32,17,68,0,0,0,0,0,0,112,62,162,34,32,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,32,170,33,14,12,1,11,65,128,128,128, + 128,120,33,14,11,32,7,65,24,106,32,9,106,33,9,2,64,2,64,32,17,32,14,183,34,32,68,0,0,0,0,0,0,112,193,162,160,34,17,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,17,170,33,14,12,1,11,65,128,128,128,128,120,33, + 14,11,32,9,32,14,54,2,0,32,7,65,240,0,106,32,8,65,15,113,65,3,116,106,43,3,0,32,32,160,33,17,32,4,65,1,106,33,4,32,8,65,127,106,34,8,65,15,71,13,0,11,11,2,64,2,64,32,28,13,0,32,17,68,0,0,0,0,0,0,224,127, + 162,34,17,68,0,0,0,0,0,0,224,127,162,32,17,32,20,27,33,17,32,22,33,8,12,1,11,2,64,32,30,69,13,0,32,18,33,8,12,1,11,32,17,68,0,0,0,0,0,0,96,3,162,34,17,68,0,0,0,0,0,0,96,3,162,32,17,32,21,27,33,17,32,23, + 33,8,11,2,64,2,64,32,17,32,8,65,255,7,106,173,66,52,134,191,162,34,17,32,17,68,0,0,0,0,0,0,192,63,162,156,68,0,0,0,0,0,0,32,192,162,160,34,17,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,17,170,33,13,12,1,11, + 65,128,128,128,128,120,33,13,11,32,17,32,13,183,161,33,17,2,64,2,64,2,64,2,64,32,18,65,1,72,34,33,13,0,32,7,65,24,106,32,16,65,127,106,65,15,113,65,2,116,106,34,8,32,8,40,2,0,34,8,32,8,32,27,117,34,8,32, + 27,116,107,34,4,54,2,0,32,4,32,26,117,33,34,32,8,32,13,106,33,13,12,1,11,2,64,32,18,13,0,32,7,65,24,106,32,16,65,127,106,65,15,113,65,2,116,106,40,2,0,65,23,117,33,34,12,1,11,65,2,33,34,65,0,33,35,32,17, + 68,0,0,0,0,0,0,224,63,102,69,13,2,12,1,11,32,34,65,0,74,13,0,32,34,33,35,12,1,11,2,64,2,64,32,15,69,13,0,65,0,33,14,12,1,11,65,0,33,8,65,0,33,14,3,64,32,7,65,24,106,32,8,65,15,113,65,2,116,106,34,15,40, + 2,0,33,4,65,255,255,255,7,33,9,2,64,2,64,32,14,65,1,113,13,0,65,128,128,128,8,33,9,32,4,13,0,65,0,33,14,12,1,11,32,15,32,9,32,4,107,54,2,0,65,1,33,14,11,32,16,32,8,65,1,106,34,8,71,13,0,11,11,2,64,32,33, + 13,0,65,255,255,255,3,33,8,2,64,2,64,32,29,14,2,1,0,2,11,65,255,255,255,1,33,8,11,32,7,65,24,106,32,16,65,127,106,65,15,113,65,2,116,106,34,4,32,4,40,2,0,32,8,113,54,2,0,11,32,13,65,1,106,33,13,65,2,33, + 35,32,34,65,2,71,13,0,68,0,0,0,0,0,0,240,63,32,17,161,34,17,32,24,161,32,17,32,14,27,33,17,11,2,64,32,17,68,0,0,0,0,0,0,0,0,98,13,0,2,64,32,16,65,127,106,32,12,72,13,0,65,0,33,4,32,16,33,8,3,64,32,7,65, + 24,106,32,8,65,127,106,34,8,65,15,113,65,2,116,106,40,2,0,32,4,114,33,4,32,8,32,12,74,13,0,11,32,4,69,13,0,32,18,33,11,3,64,32,11,65,104,106,33,11,32,7,65,24,106,32,16,65,127,106,34,16,65,15,113,65,2,116, + 106,40,2,0,69,13,0,12,4,11,11,32,25,33,8,32,16,33,14,3,64,32,14,65,1,106,33,14,32,8,65,15,113,33,4,32,8,65,127,106,33,8,32,7,65,24,106,32,4,65,2,116,106,40,2,0,69,13,0,11,32,16,65,1,106,34,15,32,14,74, + 13,1,3,64,32,7,65,240,2,106,32,16,32,5,106,65,15,113,65,3,116,106,32,15,32,10,106,65,194,0,111,34,8,65,194,0,106,32,8,32,8,65,0,72,27,65,2,116,65,144,128,128,128,0,106,40,2,0,183,57,3,0,68,0,0,0,0,0,0, + 0,0,33,17,2,64,32,5,65,1,72,13,0,65,0,33,8,32,7,33,4,32,5,33,9,3,64,32,7,32,3,57,3,16,32,7,32,2,57,3,8,32,7,32,1,57,3,0,32,17,32,4,32,8,65,3,110,65,104,108,106,43,3,0,32,7,65,240,2,106,32,16,32,9,106,65, + 15,113,65,3,116,106,43,3,0,162,160,33,17,32,4,65,8,106,33,4,32,8,65,1,106,33,8,32,9,65,127,106,34,9,13,0,11,11,32,7,65,240,0,106,32,15,65,15,113,65,3,116,106,32,17,57,3,0,32,16,65,1,106,33,16,32,15,65, + 1,106,34,15,32,14,74,13,2,12,0,11,11,11,2,64,2,64,2,64,65,24,32,11,107,34,8,65,128,8,72,13,0,32,17,68,0,0,0,0,0,0,224,127,162,33,17,32,8,65,254,15,75,13,1,65,153,120,32,11,107,33,8,12,2,11,32,8,65,130, + 120,78,13,1,32,17,68,0,0,0,0,0,0,96,3,162,33,17,2,64,32,8,65,184,112,77,13,0,65,225,7,32,11,107,33,8,12,2,11,32,17,68,0,0,0,0,0,0,96,3,162,33,17,32,8,65,240,104,32,8,65,240,104,74,27,65,146,15,106,33,8, + 12,1,11,32,17,68,0,0,0,0,0,0,224,127,162,33,17,32,8,65,253,23,32,8,65,253,23,72,27,65,130,112,106,33,8,11,2,64,2,64,32,17,32,8,65,255,7,106,173,66,52,134,191,162,34,17,68,0,0,0,0,0,0,112,65,102,69,13,0, + 32,31,65,2,116,33,4,2,64,2,64,32,17,68,0,0,0,0,0,0,112,62,162,34,3,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,3,170,33,8,12,1,11,65,128,128,128,128,120,33,8,11,32,7,65,24,106,32,4,106,33,4,2,64,2,64,32,17, + 32,8,183,68,0,0,0,0,0,0,112,193,162,160,34,17,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,17,170,33,9,12,1,11,65,128,128,128,128,120,33,9,11,32,4,32,9,54,2,0,32,16,65,1,106,34,16,65,15,113,33,31,12,1,11,2, + 64,2,64,32,17,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,17,170,33,8,12,1,11,65,128,128,128,128,120,33,8,11,32,18,33,11,11,32,7,65,24,106,32,31,65,2,116,106,32,8,54,2,0,11,2,64,2,64,2,64,32,11,65,128,8,72, + 13,0,32,11,65,254,15,75,13,1,32,11,65,129,120,106,33,11,68,0,0,0,0,0,0,224,127,33,17,12,2,11,68,0,0,0,0,0,0,240,63,33,17,32,11,65,130,120,78,13,1,2,64,32,11,65,184,112,77,13,0,32,11,65,201,7,106,33,11, + 68,0,0,0,0,0,0,96,3,33,17,12,2,11,32,11,65,240,104,32,11,65,240,104,74,27,65,146,15,106,33,11,68,0,0,0,0,0,0,0,0,33,17,12,1,11,32,11,65,253,23,32,11,65,253,23,72,27,65,130,112,106,33,11,68,0,0,0,0,0,0, + 240,127,33,17,11,68,0,0,0,0,0,0,0,0,33,2,68,0,0,0,0,0,0,0,0,33,3,2,64,32,16,65,0,72,13,0,32,17,32,11,65,255,7,106,173,66,52,134,191,162,33,17,32,16,33,8,3,64,32,7,65,240,0,106,32,8,65,15,113,34,4,65,3, + 116,106,32,17,32,7,65,24,106,32,4,65,2,116,106,40,2,0,183,162,57,3,0,32,17,68,0,0,0,0,0,0,112,62,162,33,17,32,8,65,127,106,34,8,65,127,71,13,0,11,68,0,0,0,0,0,0,0,0,33,3,32,16,65,0,72,13,0,32,16,33,4,3, + 64,68,0,0,0,0,0,0,0,0,33,17,2,64,32,12,32,16,32,4,107,34,14,32,12,32,14,72,27,34,9,65,0,72,13,0,65,0,33,8,3,64,32,17,32,7,65,240,3,106,32,8,65,7,113,65,3,116,106,43,3,0,32,7,65,240,0,106,32,4,32,8,106, + 65,15,113,65,3,116,106,43,3,0,162,160,33,17,32,8,65,1,106,34,8,32,9,76,13,0,11,11,32,7,65,240,1,106,32,14,65,15,113,65,3,116,106,32,17,57,3,0,32,4,65,0,74,33,8,32,4,65,127,106,33,4,32,8,13,0,11,68,0,0, + 0,0,0,0,0,0,33,3,32,16,65,0,72,13,0,32,16,33,8,3,64,32,3,32,7,65,240,1,106,32,8,65,15,113,65,3,116,106,43,3,0,160,33,3,32,8,65,127,106,34,8,65,127,71,13,0,11,11,2,64,32,6,69,13,0,32,7,43,3,240,1,32,3,161, + 33,17,2,64,32,16,65,1,72,13,0,65,1,33,8,3,64,32,17,32,7,65,240,1,106,32,8,65,15,113,65,3,116,106,43,3,0,160,33,17,32,8,65,1,106,34,8,32,16,76,13,0,11,11,32,17,154,32,17,32,35,27,33,2,11,32,0,32,2,57,3, + 16,32,0,32,13,65,7,113,54,2,0,32,0,32,3,154,32,3,32,35,27,57,3,8,32,7,65,176,4,106,36,128,128,128,128,0,11,153,30,7,1,127,2,124,7,127,2,125,1,127,5,125,1,127,35,128,128,128,128,0,65,128,31,107,34,3,36, + 128,128,128,128,0,2,64,32,0,40,2,0,32,2,70,13,0,2,64,2,64,65,0,43,3,128,128,128,128,0,34,4,68,0,0,0,0,0,0,62,64,163,34,5,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,5,170,33,6,12,1,11,65,128,128,128,128,120, + 33,6,11,32,0,65,172,3,106,33,7,32,0,65,160,1,106,33,8,32,0,65,200,2,106,33,9,32,0,65,144,2,106,33,10,32,0,65,216,1,106,33,11,3,64,2,64,32,0,40,2,44,34,12,65,127,70,13,0,2,64,32,12,65,0,74,13,0,32,0,32, + 0,42,2,28,34,13,56,2,240,1,32,11,32,4,32,13,32,0,42,2,236,1,146,32,0,42,2,244,1,146,32,0,42,2,248,1,146,16,134,128,128,128,0,187,16,135,128,128,128,0,32,0,32,13,56,2,168,2,32,10,32,4,32,13,32,0,42,2,164, + 2,146,32,0,42,2,172,2,146,32,0,42,2,176,2,146,16,134,128,128,128,0,187,16,135,128,128,128,0,32,0,32,13,56,2,224,2,32,9,32,4,32,13,32,0,42,2,220,2,146,32,0,42,2,228,2,146,32,0,42,2,232,2,146,16,134,128, + 128,128,0,187,16,135,128,128,128,0,11,2,64,32,0,40,2,40,34,12,65,1,72,13,0,32,0,32,12,65,127,106,54,2,40,32,0,32,0,42,2,28,32,0,42,2,36,146,34,13,56,2,240,1,32,0,32,13,56,2,28,32,11,32,4,32,13,32,0,42, + 2,236,1,146,32,0,42,2,244,1,146,32,0,42,2,248,1,146,16,134,128,128,128,0,187,16,135,128,128,128,0,32,0,32,13,56,2,168,2,32,10,32,4,32,13,32,0,42,2,164,2,146,32,0,42,2,172,2,146,32,0,42,2,176,2,146,16,134, + 128,128,128,0,187,16,135,128,128,128,0,32,0,32,13,56,2,224,2,32,9,32,4,32,13,32,0,42,2,220,2,146,32,0,42,2,228,2,146,32,0,42,2,232,2,146,16,134,128,128,128,0,187,16,135,128,128,128,0,11,32,0,65,1,54,2, + 44,11,67,0,0,0,0,33,13,67,0,0,0,0,33,14,2,64,32,0,40,2,96,34,12,65,127,70,13,0,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,32,12,65,0,74,13,0,32,0,66,0,55,3,88,12,1,11,32,12,65,4,73,13, + 1,11,32,0,45,0,80,13,1,32,0,43,3,88,33,5,12,7,11,32,0,45,0,80,33,15,32,12,65,127,106,14,3,1,2,4,2,11,65,0,33,15,32,0,65,0,58,0,80,11,32,0,45,0,81,33,12,32,0,43,3,88,34,5,68,0,0,0,0,0,0,240,63,99,69,13, + 1,32,12,65,1,113,69,13,1,32,15,65,1,113,13,1,32,5,32,0,43,3,48,160,34,5,68,0,0,0,0,0,0,240,63,32,5,68,0,0,0,0,0,0,240,63,99,27,33,5,65,1,33,12,12,5,11,32,0,45,0,81,33,12,32,0,43,3,88,33,5,11,32,5,32,0, + 43,3,64,102,69,13,1,32,12,65,1,113,69,13,1,32,15,65,1,113,13,1,32,5,32,0,43,3,56,162,33,5,65,2,33,12,12,3,11,32,0,43,3,88,33,5,32,0,45,0,81,33,12,11,32,12,65,1,113,69,13,0,65,3,33,12,32,15,65,1,113,69, + 13,2,11,32,5,32,0,43,3,72,162,33,5,65,4,33,12,11,32,0,32,5,57,3,88,11,32,0,32,12,54,2,96,32,5,182,67,0,0,0,0,146,33,14,11,2,64,32,0,40,2,152,1,34,12,65,127,70,13,0,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2, + 64,2,64,2,64,2,64,2,64,32,12,65,0,74,13,0,32,0,66,0,55,3,144,1,12,1,11,32,12,65,4,73,13,1,11,32,0,45,0,136,1,13,1,32,0,43,3,144,1,33,5,12,7,11,32,0,45,0,136,1,33,15,32,12,65,127,106,14,3,1,2,4,2,11,65, + 0,33,15,32,0,65,0,58,0,136,1,11,32,0,45,0,137,1,33,12,32,0,43,3,144,1,34,5,68,0,0,0,0,0,0,240,63,99,69,13,1,32,12,65,1,113,69,13,1,32,15,65,1,113,13,1,32,5,32,0,43,3,104,160,34,5,68,0,0,0,0,0,0,240,63, + 32,5,68,0,0,0,0,0,0,240,63,99,27,33,5,65,1,33,12,12,5,11,32,0,45,0,137,1,33,12,32,0,43,3,144,1,33,5,11,32,5,32,0,43,3,120,102,69,13,1,32,12,65,1,113,69,13,1,32,15,65,1,113,13,1,32,5,32,0,43,3,112,162,33, + 5,65,2,33,12,12,3,11,32,0,43,3,144,1,33,5,32,0,45,0,137,1,33,12,11,32,12,65,1,113,69,13,0,65,3,33,12,32,15,65,1,113,69,13,2,11,32,5,32,0,43,3,128,1,162,33,5,65,4,33,12,11,32,0,32,5,57,3,144,1,11,32,0,32, + 12,54,2,152,1,32,5,182,67,0,0,0,0,146,33,13,11,2,64,32,0,40,2,212,1,65,127,70,13,0,32,0,65,1,54,2,212,1,32,0,65,1,58,0,184,1,32,0,32,0,42,2,204,1,32,13,32,0,42,2,208,1,148,67,0,0,72,66,148,146,34,13,67, + 0,0,200,66,32,13,67,0,0,200,66,94,27,56,2,188,1,11,67,0,0,0,0,33,13,67,0,0,0,0,33,16,2,64,32,0,40,2,164,3,65,127,70,13,0,2,64,2,64,32,0,40,2,160,3,34,12,65,1,72,13,0,32,0,32,12,65,127,106,34,12,54,2,160, + 3,32,0,42,2,148,3,32,0,42,2,156,3,32,12,178,148,147,33,17,12,1,11,32,0,42,2,148,3,33,17,11,32,0,65,1,54,2,164,3,32,17,67,0,0,0,0,146,33,16,11,2,64,32,0,40,2,232,1,65,127,70,13,0,67,0,0,0,0,33,13,2,64,2, + 64,2,64,2,64,2,64,2,64,32,0,40,2,228,1,14,5,0,1,2,3,4,5,11,32,11,16,166,128,128,128,0,67,0,0,0,0,146,33,13,12,4,11,32,0,32,11,16,167,128,128,128,0,32,0,42,2,220,1,34,13,148,32,0,42,2,224,1,32,13,67,0,0, + 128,190,148,67,0,0,128,63,146,148,146,34,13,56,2,224,1,32,13,67,0,0,128,64,148,67,0,0,0,0,146,33,13,12,3,11,32,11,16,167,128,128,128,0,67,0,0,0,0,146,33,13,12,2,11,32,0,32,0,42,2,216,1,34,13,32,0,42,2, + 220,1,34,17,146,34,18,67,0,0,128,191,146,32,18,32,18,67,0,0,128,63,96,27,56,2,216,1,2,64,2,64,32,13,32,17,93,69,13,0,32,13,32,17,149,34,17,32,17,146,32,17,32,17,148,147,67,0,0,128,191,146,33,18,12,1,11, + 67,0,0,0,0,33,18,67,0,0,128,63,32,17,147,32,13,93,69,13,0,32,13,67,0,0,128,191,146,32,17,149,34,17,32,17,146,32,17,32,17,148,146,67,0,0,128,63,146,33,18,11,32,13,32,13,146,67,0,0,128,191,146,32,18,147, + 33,13,12,1,11,32,0,32,0,42,2,216,1,34,13,32,0,42,2,220,1,34,17,146,34,18,67,0,0,128,191,146,32,18,32,18,67,0,0,128,63,96,27,56,2,216,1,2,64,2,64,32,13,32,17,93,69,13,0,32,13,32,17,149,34,17,32,17,146,32, + 17,32,17,148,147,67,0,0,128,191,146,33,18,12,1,11,67,0,0,0,0,33,18,67,0,0,128,63,32,17,147,32,13,93,69,13,0,32,13,67,0,0,128,191,146,32,17,149,34,17,32,17,146,32,17,32,17,148,146,67,0,0,128,63,146,33,18, + 11,32,18,32,13,32,13,146,67,0,0,128,191,146,147,33,13,11,32,0,65,1,54,2,232,1,11,67,0,0,0,0,33,17,67,0,0,0,0,33,18,2,64,32,0,40,2,140,2,65,127,70,13,0,2,64,2,64,32,0,40,2,136,2,34,12,65,1,72,13,0,32,0, + 32,12,65,127,106,34,12,54,2,136,2,32,0,42,2,252,1,32,0,42,2,132,2,32,12,178,148,147,33,18,12,1,11,32,0,42,2,252,1,33,18,11,32,0,65,1,54,2,140,2,32,13,32,18,148,67,0,0,0,0,146,33,18,11,2,64,32,0,40,2,160, + 2,65,127,70,13,0,67,0,0,0,0,33,17,2,64,2,64,2,64,2,64,2,64,2,64,32,0,40,2,156,2,14,5,0,1,2,3,4,5,11,32,10,16,166,128,128,128,0,67,0,0,0,0,146,33,17,12,4,11,32,0,32,10,16,167,128,128,128,0,32,0,42,2,148, + 2,34,13,148,32,0,42,2,152,2,32,13,67,0,0,128,190,148,67,0,0,128,63,146,148,146,34,13,56,2,152,2,32,13,67,0,0,128,64,148,67,0,0,0,0,146,33,17,12,3,11,32,10,16,167,128,128,128,0,67,0,0,0,0,146,33,17,12,2, + 11,32,0,32,0,42,2,144,2,34,13,32,0,42,2,148,2,34,17,146,34,19,67,0,0,128,191,146,32,19,32,19,67,0,0,128,63,96,27,56,2,144,2,2,64,2,64,32,13,32,17,93,69,13,0,32,13,32,17,149,34,17,32,17,146,32,17,32,17, + 148,147,67,0,0,128,191,146,33,19,12,1,11,67,0,0,0,0,33,19,67,0,0,128,63,32,17,147,32,13,93,69,13,0,32,13,67,0,0,128,191,146,32,17,149,34,17,32,17,146,32,17,32,17,148,146,67,0,0,128,63,146,33,19,11,32,13, + 32,13,146,67,0,0,128,191,146,32,19,147,33,17,12,1,11,32,0,32,0,42,2,144,2,34,13,32,0,42,2,148,2,34,17,146,34,19,67,0,0,128,191,146,32,19,32,19,67,0,0,128,63,96,27,56,2,144,2,2,64,2,64,32,13,32,17,93,69, + 13,0,32,13,32,17,149,34,17,32,17,146,32,17,32,17,148,147,67,0,0,128,191,146,33,19,12,1,11,67,0,0,0,0,33,19,67,0,0,128,63,32,17,147,32,13,93,69,13,0,32,13,67,0,0,128,191,146,32,17,149,34,17,32,17,146,32, + 17,32,17,148,146,67,0,0,128,63,146,33,19,11,32,19,32,13,32,13,146,67,0,0,128,191,146,147,33,17,11,32,0,65,1,54,2,160,2,11,67,0,0,0,0,33,13,67,0,0,0,0,33,19,2,64,32,0,40,2,196,2,65,127,70,13,0,2,64,2,64, + 32,0,40,2,192,2,34,12,65,1,72,13,0,32,0,32,12,65,127,106,34,12,54,2,192,2,32,0,42,2,180,2,32,0,42,2,188,2,32,12,178,148,147,33,19,12,1,11,32,0,42,2,180,2,33,19,11,32,0,65,1,54,2,196,2,32,17,32,19,148,67, + 0,0,0,0,146,33,19,11,2,64,32,0,40,2,216,2,65,127,70,13,0,67,0,0,0,0,33,13,2,64,2,64,2,64,2,64,2,64,2,64,32,0,40,2,212,2,14,5,0,1,2,3,4,5,11,32,9,16,166,128,128,128,0,67,0,0,0,0,146,33,13,12,4,11,32,0,32, + 9,16,167,128,128,128,0,32,0,42,2,204,2,34,13,148,32,0,42,2,208,2,32,13,67,0,0,128,190,148,67,0,0,128,63,146,148,146,34,13,56,2,208,2,32,13,67,0,0,128,64,148,67,0,0,0,0,146,33,13,12,3,11,32,9,16,167,128, + 128,128,0,67,0,0,0,0,146,33,13,12,2,11,32,0,32,0,42,2,200,2,34,13,32,0,42,2,204,2,34,17,146,34,20,67,0,0,128,191,146,32,20,32,20,67,0,0,128,63,96,27,56,2,200,2,2,64,2,64,32,13,32,17,93,69,13,0,32,13,32, + 17,149,34,17,32,17,146,32,17,32,17,148,147,67,0,0,128,191,146,33,20,12,1,11,67,0,0,0,0,33,20,67,0,0,128,63,32,17,147,32,13,93,69,13,0,32,13,67,0,0,128,191,146,32,17,149,34,17,32,17,146,32,17,32,17,148, + 146,67,0,0,128,63,146,33,20,11,32,13,32,13,146,67,0,0,128,191,146,32,20,147,33,13,12,1,11,32,0,32,0,42,2,200,2,34,13,32,0,42,2,204,2,34,17,146,34,20,67,0,0,128,191,146,32,20,32,20,67,0,0,128,63,96,27,56, + 2,200,2,2,64,2,64,32,13,32,17,93,69,13,0,32,13,32,17,149,34,17,32,17,146,32,17,32,17,148,147,67,0,0,128,191,146,33,20,12,1,11,67,0,0,0,0,33,20,67,0,0,128,63,32,17,147,32,13,93,69,13,0,32,13,67,0,0,128, + 191,146,32,17,149,34,17,32,17,146,32,17,32,17,148,146,67,0,0,128,63,146,33,20,11,32,20,32,13,32,13,146,67,0,0,128,191,146,147,33,13,11,32,0,65,1,54,2,216,2,11,67,0,0,0,0,33,17,67,0,0,0,0,33,20,2,64,32, + 0,40,2,252,2,65,127,70,13,0,2,64,2,64,32,0,40,2,248,2,34,12,65,1,72,13,0,32,0,32,12,65,127,106,34,12,54,2,248,2,32,0,42,2,236,2,32,0,42,2,244,2,32,12,178,148,147,33,20,12,1,11,32,0,42,2,236,2,33,20,11, + 32,0,65,1,54,2,252,2,32,13,32,20,148,67,0,0,0,0,146,33,20,11,2,64,32,0,40,2,144,3,65,127,70,13,0,32,14,32,18,32,19,146,32,20,146,148,67,0,0,0,0,146,33,13,2,64,2,64,32,0,40,2,140,3,34,12,65,1,72,13,0,32, + 0,32,12,65,127,106,34,12,54,2,140,3,32,0,42,2,128,3,32,0,42,2,136,3,32,12,178,148,147,33,17,12,1,11,32,0,42,2,128,3,33,17,11,32,0,65,1,54,2,144,3,32,13,32,17,148,67,0,0,0,0,146,33,17,11,67,0,0,0,0,33,13, + 2,64,32,0,40,2,200,1,34,12,65,127,70,13,0,32,16,32,17,148,67,0,0,0,0,146,33,13,2,64,2,64,32,12,65,0,76,13,0,32,0,32,0,40,2,196,1,65,127,106,34,12,54,2,196,1,32,12,65,0,78,13,1,11,2,64,32,0,45,0,184,1,69, + 13,0,32,0,65,0,54,2,180,1,32,8,32,4,32,0,42,2,188,1,187,32,0,42,2,192,1,187,16,163,128,128,128,0,32,0,65,0,58,0,184,1,11,32,0,65,31,54,2,196,1,11,32,0,32,0,42,2,164,1,34,14,32,0,42,2,160,1,32,13,32,0,42, + 2,168,1,32,0,42,2,172,1,34,17,148,147,32,0,42,2,176,1,34,16,147,148,34,13,148,34,18,32,17,32,18,146,34,17,146,56,2,172,1,32,0,32,14,32,17,148,34,14,32,16,32,14,146,34,14,146,56,2,176,1,2,64,2,64,2,64,32, + 0,40,2,180,1,14,2,0,2,1,11,32,14,33,13,12,1,11,32,17,33,13,11,32,0,65,1,54,2,200,1,32,13,67,0,0,0,0,146,33,13,11,2,64,32,0,40,2,184,34,34,12,65,127,70,13,0,2,64,2,64,2,64,2,64,2,64,32,12,65,0,74,13,0,32, + 0,32,6,54,2,168,3,12,1,11,2,64,2,64,32,12,65,1,70,13,0,32,0,40,2,180,34,33,12,12,1,11,32,0,32,0,40,2,176,34,65,127,106,34,12,54,2,176,34,32,12,65,127,74,13,2,32,3,32,7,65,128,31,16,129,128,128,128,0,33, + 15,2,64,32,0,40,2,192,35,34,12,65,31,74,13,0,32,0,32,12,65,136,31,108,106,34,12,65,200,35,106,65,0,54,2,0,32,12,65,196,35,106,32,0,40,2,0,54,2,0,32,12,65,204,35,106,32,15,65,128,31,16,129,128,128,128,0, + 26,32,0,40,2,192,35,33,12,11,32,0,32,12,65,1,106,54,2,192,35,32,0,40,2,168,3,65,160,120,106,33,12,11,32,0,32,12,65,127,106,34,12,54,2,180,34,65,2,33,21,32,12,65,127,74,13,3,11,65,0,33,12,32,7,65,0,65,128, + 31,16,128,128,128,128,0,26,32,0,65,223,7,54,2,176,34,12,1,11,32,0,40,2,172,34,33,12,11,65,1,33,21,32,0,32,12,65,1,106,65,224,7,111,34,15,65,224,7,106,32,15,32,15,65,0,72,27,54,2,172,34,32,0,32,12,65,2, + 116,106,65,172,3,106,32,13,56,2,0,11,32,0,32,21,54,2,184,34,11,32,1,32,0,40,2,0,65,2,116,106,32,13,56,2,0,32,0,32,0,40,2,0,65,1,106,34,12,54,2,0,32,12,32,2,71,13,0,11,11,32,0,65,0,54,2,0,32,3,65,128,31, + 106,36,128,128,128,128,0,11,254,10,5,1,127,2,125,1,127,3,124,1,127,35,128,128,128,128,0,65,32,107,34,1,36,128,128,128,128,0,32,0,32,0,42,2,0,34,2,32,0,42,2,4,146,34,3,67,0,0,128,191,146,32,3,32,3,67,0, + 0,128,63,96,27,56,2,0,2,64,2,64,32,2,67,219,15,201,64,148,34,3,188,34,4,65,255,255,255,255,7,113,34,0,65,218,159,164,250,3,74,13,0,32,3,32,3,187,34,5,32,5,162,34,6,32,5,162,34,7,32,6,32,6,162,162,32,6, + 68,167,70,59,140,135,205,198,62,162,68,116,231,202,226,249,0,42,191,160,162,32,7,32,6,68,178,251,110,137,16,17,129,63,162,68,119,172,203,84,85,85,197,191,160,162,32,5,160,160,182,32,0,65,128,128,128,204, + 3,72,27,33,3,12,1,11,2,64,32,0,65,209,167,237,131,4,75,13,0,32,3,187,33,6,2,64,32,0,65,228,151,219,128,4,79,13,0,68,0,0,0,0,0,0,240,63,32,6,68,24,45,68,84,251,33,249,63,160,34,5,32,5,162,34,5,68,129,94, + 12,253,255,255,223,63,162,161,32,5,32,5,162,34,7,68,66,58,5,225,83,85,165,63,162,160,32,5,32,7,162,32,5,68,105,80,238,224,66,147,249,62,162,68,39,30,15,232,135,192,86,191,160,162,160,182,140,68,0,0,0,0, + 0,0,240,63,32,6,68,24,45,68,84,251,33,249,191,160,34,6,32,6,162,34,6,68,129,94,12,253,255,255,223,63,162,161,32,6,32,6,162,34,5,68,66,58,5,225,83,85,165,63,162,160,32,6,32,5,162,32,6,68,105,80,238,224, + 66,147,249,62,162,68,39,30,15,232,135,192,86,191,160,162,160,182,32,4,65,0,72,27,33,3,12,2,11,68,24,45,68,84,251,33,9,64,68,24,45,68,84,251,33,9,192,32,4,65,0,72,27,32,6,160,34,5,32,5,162,34,6,32,5,154, + 162,34,7,32,6,32,6,162,162,32,6,68,167,70,59,140,135,205,198,62,162,68,116,231,202,226,249,0,42,191,160,162,32,7,32,6,68,178,251,110,137,16,17,129,63,162,68,119,172,203,84,85,85,197,191,160,162,32,5,161, + 160,182,33,3,12,1,11,2,64,2,64,2,64,32,0,65,214,227,136,135,4,73,13,0,32,0,65,255,255,255,251,7,77,13,1,32,3,32,3,147,33,3,12,3,11,32,3,187,33,6,32,0,65,224,219,191,133,4,73,13,1,68,24,45,68,84,251,33, + 25,64,68,24,45,68,84,251,33,25,192,32,4,65,0,72,27,32,6,160,34,5,32,5,32,5,162,34,6,162,34,7,32,6,32,6,162,162,32,6,68,167,70,59,140,135,205,198,62,162,68,116,231,202,226,249,0,42,191,160,162,32,5,32,7, + 32,6,68,178,251,110,137,16,17,129,63,162,68,119,172,203,84,85,85,197,191,160,162,160,160,182,33,3,12,2,11,2,64,2,64,32,0,65,218,159,164,238,4,75,13,0,32,3,187,34,6,32,6,68,131,200,201,109,48,95,228,63, + 162,68,0,0,0,0,0,0,56,67,160,68,0,0,0,0,0,0,56,195,160,34,5,68,0,0,0,80,251,33,249,191,162,160,32,5,68,99,98,26,97,180,16,81,190,162,160,33,6,2,64,32,5,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,5,170,33, + 0,12,2,11,65,128,128,128,128,120,33,0,12,1,11,32,1,65,8,106,32,0,32,0,65,23,118,65,234,126,106,34,8,65,23,116,107,190,187,68,0,0,0,0,0,0,0,0,68,0,0,0,0,0,0,0,0,32,8,65,1,65,0,16,164,128,128,128,0,32,1, + 43,3,16,33,6,32,1,40,2,8,33,0,32,4,65,127,74,13,0,65,0,32,0,107,33,0,32,6,154,33,6,11,2,64,2,64,2,64,2,64,32,0,65,3,113,14,3,0,1,2,3,11,32,6,32,6,32,6,162,34,5,162,34,7,32,5,32,5,162,162,32,5,68,167,70, + 59,140,135,205,198,62,162,68,116,231,202,226,249,0,42,191,160,162,32,6,32,7,32,5,68,178,251,110,137,16,17,129,63,162,68,119,172,203,84,85,85,197,191,160,162,160,160,182,33,3,12,4,11,32,6,32,6,162,34,6, + 68,129,94,12,253,255,255,223,191,162,68,0,0,0,0,0,0,240,63,160,32,6,32,6,162,34,5,68,66,58,5,225,83,85,165,63,162,160,32,6,32,5,162,32,6,68,105,80,238,224,66,147,249,62,162,68,39,30,15,232,135,192,86,191, + 160,162,160,182,33,3,12,3,11,32,6,32,6,162,34,5,32,6,154,162,34,7,32,5,32,5,162,162,32,5,68,167,70,59,140,135,205,198,62,162,68,116,231,202,226,249,0,42,191,160,162,32,7,32,5,68,178,251,110,137,16,17,129, + 63,162,68,119,172,203,84,85,85,197,191,160,162,32,6,161,160,182,33,3,12,2,11,32,6,32,6,162,34,6,68,129,94,12,253,255,255,223,191,162,68,0,0,0,0,0,0,240,63,160,32,6,32,6,162,34,5,68,66,58,5,225,83,85,165, + 63,162,160,32,6,32,5,162,32,6,68,105,80,238,224,66,147,249,62,162,68,39,30,15,232,135,192,86,191,160,162,160,182,140,33,3,12,1,11,68,0,0,0,0,0,0,240,63,32,6,68,210,33,51,127,124,217,18,64,160,34,5,32,5, + 162,34,5,68,129,94,12,253,255,255,223,63,162,161,32,5,32,5,162,34,7,68,66,58,5,225,83,85,165,63,162,160,32,5,32,7,162,32,5,68,105,80,238,224,66,147,249,62,162,68,39,30,15,232,135,192,86,191,160,162,160, + 182,68,0,0,0,0,0,0,240,63,32,6,68,210,33,51,127,124,217,18,192,160,34,6,32,6,162,34,6,68,129,94,12,253,255,255,223,63,162,161,32,6,32,6,162,34,5,68,66,58,5,225,83,85,165,63,162,160,32,6,32,5,162,32,6,68, + 105,80,238,224,66,147,249,62,162,68,39,30,15,232,135,192,86,191,160,162,160,182,140,32,4,65,0,72,27,33,3,11,32,1,65,32,106,36,128,128,128,128,0,32,3,11,162,5,3,4,125,4,127,1,125,32,0,32,0,42,2,0,34,1,32, + 0,42,2,4,34,2,146,34,3,67,0,0,128,191,146,32,3,32,3,67,0,0,128,63,96,27,56,2,0,2,64,2,64,32,1,32,2,93,69,13,0,32,1,32,2,149,34,3,32,3,146,32,3,32,3,148,147,67,0,0,128,191,146,33,4,12,1,11,67,0,0,0,0,33, + 4,67,0,0,128,63,32,2,147,32,1,93,69,13,0,32,1,67,0,0,128,191,146,32,2,149,34,3,32,3,146,32,3,32,3,148,146,67,0,0,128,63,146,33,4,11,2,64,2,64,32,1,67,0,0,0,63,146,34,3,188,34,5,65,23,118,65,255,1,113,34, + 6,65,255,1,71,13,0,32,3,32,3,149,33,3,12,1,11,2,64,32,5,65,255,255,255,255,7,113,34,0,65,128,128,128,252,3,74,13,0,32,3,67,0,0,0,0,148,32,3,32,0,65,128,128,128,252,3,70,27,33,3,12,1,11,2,64,2,64,32,6,13, + 0,65,0,33,6,2,64,32,5,65,9,116,34,0,65,0,72,13,0,65,0,33,6,3,64,32,6,65,127,106,33,6,32,0,65,1,116,34,0,65,127,74,13,0,11,11,32,5,65,1,32,6,107,116,33,0,12,1,11,32,5,65,255,255,255,3,113,65,128,128,128, + 4,114,33,0,11,2,64,2,64,2,64,32,6,65,128,1,72,13,0,32,6,65,1,106,33,7,3,64,2,64,32,0,65,128,128,128,124,106,34,6,65,0,72,13,0,32,6,33,0,32,6,69,13,3,11,32,0,65,1,116,33,0,32,7,65,127,106,34,7,65,128,1, + 74,13,0,11,65,255,0,33,6,11,2,64,2,64,2,64,2,64,32,0,65,128,128,128,124,106,34,7,65,0,72,13,0,32,7,33,0,32,7,69,13,1,11,32,0,65,255,255,255,3,77,13,1,32,0,33,8,12,2,11,32,3,67,0,0,0,0,148,33,3,12,4,11, + 3,64,32,6,65,127,106,33,6,32,0,65,128,128,128,2,73,33,7,32,0,65,1,116,34,8,33,0,32,7,13,0,11,11,32,5,65,128,128,128,128,120,113,33,0,2,64,32,6,65,1,72,13,0,32,8,65,128,128,128,124,106,32,6,65,23,116,114, + 33,6,12,2,11,32,8,65,1,32,6,107,117,33,6,12,1,11,32,3,67,0,0,0,0,148,33,3,12,1,11,32,6,32,0,114,190,33,3,11,2,64,2,64,32,3,32,2,93,69,13,0,32,3,32,2,149,34,2,32,2,146,32,2,32,2,148,147,67,0,0,128,191,146, + 33,9,12,1,11,67,0,0,0,0,33,9,67,0,0,128,63,32,2,147,32,3,93,69,13,0,32,3,67,0,0,128,191,146,32,2,149,34,2,32,2,146,32,2,32,2,148,146,67,0,0,128,63,146,33,9,11,67,0,0,128,191,67,0,0,128,63,32,1,67,0,0,0, + 63,93,27,32,4,147,32,9,146,11,11,156,130,128,128,0,2,0,65,0,11,8,0,0,0,0,0,0,0,0,0,65,16,11,136,2,131,249,162,0,68,78,110,0,252,41,21,0,209,87,39,0,221,52,245,0,98,219,192,0,60,153,149,0,65,144,67,0,99, + 81,254,0,187,222,171,0,183,97,197,0,58,110,36,0,210,77,66,0,73,6,224,0,9,234,46,0,28,146,209,0,235,29,254,0,41,177,28,0,232,62,167,0,245,53,130,0,68,187,46,0,156,233,132,0,180,38,112,0,65,126,95,0,214, + 145,57,0,83,131,57,0,156,244,57,0,139,95,132,0,40,249,189,0,248,31,59,0,222,255,151,0,15,152,5,0,17,47,239,0,10,90,139,0,109,31,109,0,207,126,54,0,9,203,39,0,70,79,183,0,158,102,63,0,45,234,95,0,186,39, + 117,0,229,235,199,0,61,123,241,0,247,57,7,0,146,82,138,0,251,107,234,0,31,177,95,0,8,93,141,0,48,3,86,0,123,252,70,0,240,171,107,0,32,188,207,0,54,244,154,0,227,169,29,0,94,97,145,0,8,27,230,0,133,153, + 101,0,160,20,95,0,141,64,104,0,128,216,255,0,39,115,77,0,6,6,49,0,202,86,21,0,201,168,115,0,123,226,96,0,107,140,192,0,0,240,137,128,128,0,7,108,105,110,107,105,110,103,2,8,174,137,128,128,0,43,0,32,2, + 17,95,115,101,110,100,69,118,101,110,116,95,109,105,100,105,73,110,1,2,12,46,76,95,102,114,101,113,117,101,110,99,121,0,0,8,0,32,3,16,95,115,101,110,100,69,118,101,110,116,95,112,111,119,101,114,0,32,4, + 21,95,115,101,110,100,69,118,101,110,116,95,109,97,115,116,101,114,71,97,105,110,0,32,5,23,95,115,101,110,100,69,118,101,110,116,95,109,97,115,116,101,114,79,99,116,97,118,101,0,2,6,29,46,76,115,116,100, + 95,95,110,111,116,101,115,95,95,110,111,116,101,84,111,70,114,101,113,117,101,110,99,121,0,2,7,32,46,76,115,116,100,95,95,111,115,99,105,108,108,97,116,111,114,115,95,95,115,101,116,70,114,101,113,117, + 101,110,99,121,0,2,8,67,46,76,115,116,100,95,95,105,110,116,114,105,110,115,105,99,115,95,95,105,110,116,101,114,110,97,108,95,95,109,97,116,104,95,105,109,112,108,101,109,101,110,116,97,116,105,111,110, + 115,95,95,104,101,108,112,101,114,115,95,95,115,99,97,108,98,110,102,0,32,9,22,95,115,101,110,100,69,118,101,110,116,95,109,97,115,116,101,114,71,108,105,100,101,0,32,10,24,95,115,101,110,100,69,118,101, + 110,116,95,118,99,111,49,83,101,109,105,116,111,110,101,115,0,32,11,21,95,115,101,110,100,69,118,101,110,116,95,118,99,111,49,68,101,116,117,110,101,0,32,12,20,95,115,101,110,100,69,118,101,110,116,95, + 118,99,111,49,76,101,118,101,108,0,32,13,20,95,115,101,110,100,69,118,101,110,116,95,118,99,111,49,83,104,97,112,101,0,32,14,24,95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,83,101,109,105,116, + 111,110,101,115,0,32,15,21,95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,68,101,116,117,110,101,0,32,16,20,95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,76,101,118,101,108,0,32,17,20, + 95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,83,104,97,112,101,0,32,18,24,95,115,101,110,100,69,118,101,110,116,95,118,99,111,51,83,101,109,105,116,111,110,101,115,0,32,19,21,95,115,101,110,100, + 69,118,101,110,116,95,118,99,111,51,68,101,116,117,110,101,0,32,20,20,95,115,101,110,100,69,118,101,110,116,95,118,99,111,51,76,101,118,101,108,0,32,21,20,95,115,101,110,100,69,118,101,110,116,95,118,99, + 111,51,83,104,97,112,101,0,32,22,23,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,67,117,116,111,102,102,0,32,23,26,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,82, + 101,115,111,110,97,110,99,101,0,32,24,22,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,69,103,73,110,116,0,32,25,22,95,115,101,110,100,69,118,101,110,116,95,97,109,112,69,103,65,116, + 116,97,99,107,0,32,26,21,95,115,101,110,100,69,118,101,110,116,95,97,109,112,69,103,68,101,99,97,121,0,2,27,56,46,76,115,116,100,95,95,105,110,116,114,105,110,115,105,99,115,95,95,105,110,116,101,114,110, + 97,108,95,95,109,97,116,104,95,105,109,112,108,101,109,101,110,116,97,116,105,111,110,115,95,95,112,111,119,95,48,0,32,28,23,95,115,101,110,100,69,118,101,110,116,95,97,109,112,69,103,83,117,115,116,97, + 105,110,0,32,29,23,95,115,101,110,100,69,118,101,110,116,95,97,109,112,69,103,82,101,108,101,97,115,101,0,32,30,25,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,69,103,65,116,116,97, + 99,107,0,32,31,24,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,69,103,68,101,99,97,121,0,32,32,26,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,69,103,83,117,115, + 116,97,105,110,0,32,33,26,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,69,103,82,101,108,101,97,115,101,0,32,34,10,105,110,105,116,105,97,108,105,115,101,2,16,0,0,2,35,38,46,76,115, + 116,100,95,95,102,105,108,116,101,114,115,95,95,116,112,116,95,95,115,118,102,95,95,115,101,116,70,114,101,113,117,101,110,99,121,0,2,36,81,46,76,115,116,100,95,95,105,110,116,114,105,110,115,105,99,115, + 95,95,105,110,116,101,114,110,97,108,95,95,109,97,116,104,95,105,109,112,108,101,109,101,110,116,97,116,105,111,110,115,95,95,104,101,108,112,101,114,115,95,95,114,101,109,97,105,110,100,101,114,80,105, + 79,118,101,114,50,76,97,114,103,101,0,16,0,1,2,13,46,76,95,95,99,111,110,115,116,97,110,116,95,1,0,136,2,0,32,37,12,97,100,118,97,110,99,101,66,108,111,99,107,0,2,38,28,46,76,115,116,100,95,95,111,115, + 99,105,108,108,97,116,111,114,115,95,95,110,101,120,116,83,105,110,101,0,2,39,30,46,76,115,116,100,95,95,111,115,99,105,108,108,97,116,111,114,115,95,95,110,101,120,116,83,113,117,97,114,101,0,16,1,5,173, + 128,128,128,0,2,17,46,98,115,115,46,46,76,95,102,114,101,113,117,101,110,99,121,3,0,21,46,114,111,100,97,116,97,46,46,76,95,95,99,111,110,115,116,97,110,116,95,4,0,0,161,131,128,128,0,10,114,101,108,111, + 99,46,67,79,68,69,5,95,3,166,4,1,0,3,206,5,1,0,3,238,6,1,0,3,242,7,1,0,0,154,8,5,0,161,8,6,0,218,8,5,0,225,8,6,0,154,9,5,0,161,9,6,0,153,14,7,3,241,19,1,0,0,151,20,5,0,158,20,6,3,195,20,1,0,0,233,20,5, + 0,240,20,6,3,180,21,1,0,3,233,22,1,0,0,143,23,5,0,150,23,6,3,187,23,1,0,0,225,23,5,0,232,23,6,3,172,24,1,0,3,225,25,1,0,0,135,26,5,0,142,26,6,3,179,26,1,0,0,217,26,5,0,224,26,6,3,164,27,1,0,3,151,29,1, + 0,3,199,29,1,0,0,224,29,26,3,227,37,1,0,0,252,37,26,3,154,38,1,0,3,203,38,1,0,0,228,38,26,3,155,39,1,0,0,180,39,26,7,201,39,34,7,212,39,34,0,237,41,35,0,199,42,6,0,233,42,6,0,139,43,6,3,162,43,1,0,7,184, + 43,34,7,206,43,34,7,217,43,34,0,236,58,36,7,237,65,34,7,137,66,34,7,149,66,34,0,170,67,37,0,188,67,37,0,206,67,37,4,146,68,38,4,4,132,81,38,0,7,171,90,34,7,195,90,34,7,207,90,34,3,232,90,1,0,0,132,92,5, + 0,139,92,6,0,180,92,5,0,187,92,6,0,228,92,5,0,235,92,6,0,191,93,5,0,198,93,6,0,239,93,5,0,246,93,6,0,159,94,5,0,166,94,6,0,204,101,40,0,225,101,41,0,161,102,41,0,136,106,40,0,157,106,41,0,221,106,41,0, + 196,110,40,0,217,110,41,0,153,111,41,0,174,116,35,0,169,118,42,0,237,118,42,0,185,119,37,7,198,120,34,7,218,120,34,7,229,120,34,0,145,127,36,7,196,131,1,34,0,181,128,128,128,0,15,116,97,114,103,101,116, + 95,102,101,97,116,117,114,101,115,3,43,15,109,117,116,97,98,108,101,45,103,108,111,98,97,108,115,43,8,115,105,103,110,45,101,120,116,43,7,115,105,109,100,49,50,56,]); + } + + /** @access private */ + _getWasmBytesNonSIMD() + { + return new Uint8Array([0,97,115,109,1,0,0,0,1,203,128,128,128,0,12,96,2,127,127,0,96,2,127,125,0,96,1,125,1,125,96,3,127,124,124,0,96,2,125,127,1,125,96,1,124,1,124,96,4,127,127,127,124,0,96,4,127,124, + 124,124,0,96,7,127,124,124,124,127,127,127,0,96,3,127,127,127,1,127,96,3,127,127,127,0,96,1,127,1,125,2,201,128,128,128,0,4,3,101,110,118,15,95,95,108,105,110,101,97,114,95,109,101,109,111,114,121,2,0, + 1,3,101,110,118,15,95,95,115,116,97,99,107,95,112,111,105,110,116,101,114,3,127,1,3,101,110,118,6,109,101,109,115,101,116,0,9,3,101,110,118,6,109,101,109,99,112,121,0,9,3,167,128,128,128,0,38,0,1,1,1,2, + 3,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,1,1,1,1,1,1,6,7,8,10,11,11,7,216,133,128,128,0,30,17,95,115,101,110,100,69,118,101,110,116,95,109,105,100,105,73,110,0,2,16,95,115,101,110,100,69,118,101,110,116, + 95,112,111,119,101,114,0,3,21,95,115,101,110,100,69,118,101,110,116,95,109,97,115,116,101,114,71,97,105,110,0,4,23,95,115,101,110,100,69,118,101,110,116,95,109,97,115,116,101,114,79,99,116,97,118,101,0, + 5,22,95,115,101,110,100,69,118,101,110,116,95,109,97,115,116,101,114,71,108,105,100,101,0,9,24,95,115,101,110,100,69,118,101,110,116,95,118,99,111,49,83,101,109,105,116,111,110,101,115,0,10,21,95,115,101, + 110,100,69,118,101,110,116,95,118,99,111,49,68,101,116,117,110,101,0,11,20,95,115,101,110,100,69,118,101,110,116,95,118,99,111,49,76,101,118,101,108,0,12,20,95,115,101,110,100,69,118,101,110,116,95,118, + 99,111,49,83,104,97,112,101,0,13,24,95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,83,101,109,105,116,111,110,101,115,0,14,21,95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,68,101,116,117, + 110,101,0,15,20,95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,76,101,118,101,108,0,16,20,95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,83,104,97,112,101,0,17,24,95,115,101,110,100,69, + 118,101,110,116,95,118,99,111,51,83,101,109,105,116,111,110,101,115,0,18,21,95,115,101,110,100,69,118,101,110,116,95,118,99,111,51,68,101,116,117,110,101,0,19,20,95,115,101,110,100,69,118,101,110,116,95, + 118,99,111,51,76,101,118,101,108,0,20,20,95,115,101,110,100,69,118,101,110,116,95,118,99,111,51,83,104,97,112,101,0,21,23,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,67,117,116,111, + 102,102,0,22,26,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,82,101,115,111,110,97,110,99,101,0,23,22,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,69,103,73,110, + 116,0,24,22,95,115,101,110,100,69,118,101,110,116,95,97,109,112,69,103,65,116,116,97,99,107,0,25,21,95,115,101,110,100,69,118,101,110,116,95,97,109,112,69,103,68,101,99,97,121,0,26,23,95,115,101,110,100, + 69,118,101,110,116,95,97,109,112,69,103,83,117,115,116,97,105,110,0,28,23,95,115,101,110,100,69,118,101,110,116,95,97,109,112,69,103,82,101,108,101,97,115,101,0,29,25,95,115,101,110,100,69,118,101,110, + 116,95,102,105,108,116,101,114,69,103,65,116,116,97,99,107,0,30,24,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,69,103,68,101,99,97,121,0,31,26,95,115,101,110,100,69,118,101,110,116, + 95,102,105,108,116,101,114,69,103,83,117,115,116,97,105,110,0,32,26,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,69,103,82,101,108,101,97,115,101,0,33,10,105,110,105,116,105,97,108, + 105,115,101,0,34,12,97,100,118,97,110,99,101,66,108,111,99,107,0,37,12,129,128,128,128,0,2,10,150,137,129,128,0,38,141,5,6,3,127,1,125,2,127,1,125,1,127,1,124,32,0,65,188,34,106,33,2,2,64,2,64,2,64,2,64, + 32,1,40,2,0,34,1,65,128,128,192,7,113,34,3,65,128,128,192,4,71,13,0,32,1,65,255,1,113,69,13,0,32,2,32,0,65,180,35,106,34,3,40,2,0,65,12,108,106,34,4,32,1,65,8,118,65,255,0,113,178,34,5,56,2,4,32,4,32,1, + 65,16,118,65,15,113,54,2,0,32,4,32,1,65,255,0,113,178,67,4,2,1,60,148,56,2,8,32,0,65,184,35,106,34,1,32,1,40,2,0,65,1,106,54,2,0,32,3,32,3,40,2,0,65,1,106,65,10,111,34,1,65,10,106,32,1,32,1,65,0,72,27, + 54,2,0,65,204,94,33,1,65,149,94,33,3,12,1,11,2,64,32,3,65,128,128,128,4,70,13,0,32,1,65,255,129,192,7,113,65,128,128,192,4,71,13,3,11,65,0,33,6,65,0,33,7,2,64,32,0,65,180,35,106,40,2,0,34,4,65,127,106, + 65,0,72,13,0,32,1,65,8,118,65,255,0,113,178,33,8,65,0,33,7,65,0,33,1,3,64,2,64,2,64,32,2,32,1,65,12,108,106,34,3,42,2,4,34,5,32,8,94,32,5,32,8,93,114,65,1,71,13,0,32,2,32,7,65,12,108,106,34,9,32,5,56,2, + 4,32,9,32,3,42,2,8,56,2,8,32,9,32,3,40,2,0,54,2,0,32,7,65,1,106,65,10,111,34,3,65,10,106,32,3,32,3,65,0,72,27,33,7,12,1,11,32,0,32,0,40,2,184,35,65,127,106,54,2,184,35,11,32,1,65,1,106,65,10,111,34,1,65, + 10,106,32,1,32,1,65,0,72,27,33,1,32,4,65,127,106,34,4,65,1,78,13,0,11,11,32,0,32,7,54,2,180,35,2,64,32,0,65,184,35,106,40,2,0,13,0,65,149,94,33,1,12,2,11,32,2,32,7,65,127,106,65,10,111,34,1,65,10,106,32, + 1,32,1,65,0,72,27,65,12,108,106,42,2,4,33,5,65,149,94,33,1,65,204,94,33,3,11,65,1,33,6,32,0,65,208,0,106,65,1,58,0,0,32,0,65,32,106,32,5,56,2,0,32,2,32,3,106,65,1,58,0,0,32,0,65,24,106,42,2,0,34,8,67,0, + 0,0,0,94,33,3,2,64,2,64,65,0,43,3,128,128,128,128,0,32,8,187,162,34,10,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,10,170,33,4,12,1,11,65,128,128,128,128,120,33,4,11,32,0,65,40,106,32,4,65,1,32,3,27,34,3,54, + 2,0,32,0,65,36,106,32,5,32,0,65,28,106,42,2,0,147,32,3,178,149,56,2,0,11,32,2,32,1,106,32,6,58,0,0,32,0,65,137,1,106,32,6,58,0,0,11,11,158,1,3,1,127,2,125,2,127,32,0,65,152,3,106,32,1,56,2,0,32,0,65,148, + 3,106,34,2,42,2,0,33,3,32,2,32,1,56,2,0,2,64,2,64,67,10,215,163,60,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,163,182,149,34,4,139,67,0,0,0,79,93,69,13,0,32,4,168,33,2,12,1,11,65,128,128,128,128, + 120,33,2,11,32,0,65,160,3,106,34,5,40,2,0,33,6,32,5,32,2,65,1,32,2,65,1,74,27,34,2,54,2,0,32,0,65,156,3,106,34,0,32,1,32,3,32,0,42,2,0,32,6,178,148,147,147,32,2,178,149,56,2,0,11,158,1,3,1,127,2,125,2, + 127,32,0,65,132,3,106,32,1,56,2,0,32,0,65,128,3,106,34,2,42,2,0,33,3,32,2,32,1,56,2,0,2,64,2,64,67,10,215,163,60,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,163,182,149,34,4,139,67,0,0,0,79,93,69, + 13,0,32,4,168,33,2,12,1,11,65,128,128,128,128,120,33,2,11,32,0,65,140,3,106,34,5,40,2,0,33,6,32,5,32,2,65,1,32,2,65,1,74,27,34,2,54,2,0,32,0,65,136,3,106,34,0,32,1,32,3,32,0,42,2,0,32,6,178,148,147,147, + 32,2,178,149,56,2,0,11,213,1,1,1,124,32,0,65,236,1,106,32,1,67,0,0,64,65,148,34,1,56,2,0,32,0,65,216,1,106,65,0,43,3,128,128,128,128,0,34,2,32,1,32,0,65,240,1,106,42,2,0,146,32,0,65,244,1,106,42,2,0,146, + 32,0,65,248,1,106,42,2,0,146,16,134,128,128,128,0,187,16,135,128,128,128,0,32,0,65,164,2,106,32,1,56,2,0,32,0,65,144,2,106,32,2,32,1,32,0,65,168,2,106,42,2,0,146,32,0,65,172,2,106,42,2,0,146,32,0,65,176, + 2,106,42,2,0,146,16,134,128,128,128,0,187,16,135,128,128,128,0,32,0,65,220,2,106,32,1,56,2,0,32,0,65,200,2,106,32,2,32,1,32,0,65,224,2,106,42,2,0,146,32,0,65,228,2,106,42,2,0,146,32,0,65,232,2,106,42,2, + 0,146,16,134,128,128,128,0,187,16,135,128,128,128,0,11,147,5,5,1,125,2,127,2,125,2,127,1,125,2,64,2,64,32,0,67,0,0,138,194,146,67,171,170,170,61,148,34,1,188,34,2,65,255,255,255,255,7,113,34,3,13,0,67, + 0,0,128,63,33,0,12,1,11,2,64,32,3,65,129,128,128,252,7,72,13,0,32,1,67,0,0,0,64,146,33,0,12,1,11,2,64,2,64,32,3,65,128,128,128,252,3,70,13,0,32,3,65,128,128,128,252,7,71,13,1,32,1,67,0,0,0,0,32,2,65,127, + 74,27,33,0,12,2,11,67,0,0,0,64,67,0,0,0,63,32,2,65,127,74,27,33,0,12,1,11,2,64,32,2,65,128,128,128,248,3,70,13,0,67,0,0,128,64,33,0,32,2,65,128,128,128,128,4,70,13,1,2,64,32,3,65,129,128,128,232,4,72,13, + 0,67,0,0,128,127,67,0,0,0,0,32,2,65,0,74,27,33,0,12,2,11,67,0,0,128,127,33,0,32,1,67,0,0,0,0,148,32,1,32,2,65,128,96,113,190,34,4,147,146,34,5,32,4,146,34,1,188,34,3,65,128,128,128,152,4,74,13,1,2,64,2, + 64,32,3,65,128,128,128,152,4,71,13,0,32,5,67,60,170,56,51,146,32,1,32,4,147,94,13,3,32,1,188,65,255,255,255,255,7,113,33,2,12,1,11,67,0,0,0,0,33,0,32,1,188,65,255,255,255,255,7,113,34,2,65,128,128,216, + 152,4,74,13,2,32,3,65,128,128,216,152,124,71,13,0,32,5,32,1,32,4,147,95,13,2,11,65,0,33,6,2,64,32,2,65,128,128,128,248,3,76,13,0,65,0,65,128,128,128,4,32,2,65,23,118,65,130,127,106,118,32,3,106,34,2,65, + 255,255,255,3,113,65,128,128,128,4,114,65,150,1,32,2,65,23,118,65,255,1,113,34,7,107,118,34,6,107,32,6,32,3,65,0,72,27,33,6,32,5,32,4,65,128,128,128,124,32,7,65,129,127,106,117,32,2,113,190,147,34,4,146, + 188,33,3,11,2,64,32,6,65,23,116,32,3,65,128,128,126,113,190,34,0,67,0,114,49,63,148,34,8,32,0,67,140,190,191,53,148,32,5,32,0,32,4,147,147,67,24,114,49,63,148,146,34,4,146,34,0,32,0,32,0,32,0,32,0,148, + 34,1,32,1,32,1,32,1,32,1,67,76,187,49,51,148,67,14,234,221,181,146,148,67,85,179,138,56,146,148,67,97,11,54,187,146,148,67,171,170,42,62,146,148,147,34,1,148,32,1,67,0,0,0,192,146,149,32,4,32,0,32,8,147, + 147,34,1,32,0,32,1,148,146,147,147,67,0,0,128,63,146,34,0,188,106,34,3,65,255,255,255,3,74,13,0,32,0,32,6,16,136,128,128,128,0,33,0,12,2,11,32,3,190,33,0,12,1,11,67,243,4,181,63,33,0,11,32,0,67,0,0,220, + 67,148,11,237,3,4,1,126,1,127,2,126,1,127,2,64,2,64,32,2,32,1,163,34,1,189,34,3,66,52,136,167,65,255,15,113,34,4,65,255,15,71,13,0,32,1,32,1,163,33,1,12,1,11,2,64,32,3,66,255,255,255,255,255,255,255,255, + 255,0,131,34,5,66,128,128,128,128,128,128,128,248,63,85,13,0,32,1,68,0,0,0,0,0,0,0,0,162,32,1,32,5,66,128,128,128,128,128,128,128,248,63,81,27,33,1,12,1,11,2,64,2,64,32,4,13,0,65,0,33,4,2,64,32,3,66,12, + 134,34,5,66,0,83,13,0,3,64,32,4,65,127,106,33,4,32,5,66,1,134,34,5,66,127,85,13,0,11,11,32,3,65,1,32,4,107,173,134,33,5,12,1,11,32,3,66,255,255,255,255,255,255,255,7,131,66,128,128,128,128,128,128,128, + 8,132,33,5,11,2,64,2,64,2,64,32,4,65,128,8,72,13,0,32,4,65,1,106,33,4,3,64,2,64,32,5,66,128,128,128,128,128,128,128,120,124,34,6,66,0,83,13,0,32,6,33,5,32,6,80,13,3,11,32,5,66,1,134,33,5,32,4,65,127,106, + 34,4,65,128,8,74,13,0,11,65,255,7,33,4,11,2,64,2,64,2,64,2,64,32,5,66,128,128,128,128,128,128,128,120,124,34,6,66,0,83,13,0,32,6,33,5,32,6,80,13,1,11,32,5,66,255,255,255,255,255,255,255,7,88,13,1,32,5, + 33,6,12,2,11,32,1,68,0,0,0,0,0,0,0,0,162,33,1,12,4,11,3,64,32,4,65,127,106,33,4,32,5,66,128,128,128,128,128,128,128,4,84,33,7,32,5,66,1,134,34,6,33,5,32,7,13,0,11,11,32,3,66,128,128,128,128,128,128,128, + 128,128,127,131,33,5,2,64,32,4,65,1,72,13,0,32,6,66,128,128,128,128,128,128,128,120,124,32,4,173,66,52,134,132,33,6,12,2,11,32,6,65,1,32,4,107,173,135,33,6,12,1,11,32,1,68,0,0,0,0,0,0,0,0,162,33,1,12,1, + 11,32,6,32,5,132,191,33,1,11,32,0,32,1,182,56,2,4,11,160,1,0,2,64,2,64,2,64,32,1,65,128,1,72,13,0,32,0,67,0,0,0,127,148,33,0,32,1,65,254,1,75,13,1,32,1,65,129,127,106,33,1,12,2,11,32,1,65,130,127,78,13, + 1,32,0,67,0,0,128,12,148,33,0,2,64,32,1,65,155,126,77,13,0,32,1,65,230,0,106,33,1,12,2,11,32,0,67,0,0,128,12,148,33,0,32,1,65,182,125,32,1,65,182,125,74,27,65,204,1,106,33,1,12,1,11,32,0,67,0,0,0,127,148, + 33,0,32,1,65,253,2,32,1,65,253,2,72,27,65,130,126,106,33,1,11,32,0,32,1,65,23,116,65,128,128,128,252,3,106,190,148,11,12,0,32,0,65,24,106,32,1,56,2,0,11,73,0,32,0,65,244,1,106,32,1,56,2,0,32,0,65,216,1, + 106,65,0,43,3,128,128,128,128,0,32,0,65,248,1,106,42,2,0,32,0,65,236,1,106,42,2,0,32,0,65,240,1,106,42,2,0,146,32,1,146,146,16,134,128,128,128,0,187,16,135,128,128,128,0,11,81,0,32,0,65,248,1,106,32,1, + 67,10,215,35,60,148,34,1,56,2,0,32,0,65,216,1,106,65,0,43,3,128,128,128,128,0,32,1,32,0,65,236,1,106,42,2,0,32,0,65,240,1,106,42,2,0,146,32,0,65,244,1,106,42,2,0,146,146,16,134,128,128,128,0,187,16,135, + 128,128,128,0,11,158,1,3,1,127,2,125,2,127,32,0,65,128,2,106,32,1,56,2,0,32,0,65,252,1,106,34,2,42,2,0,33,3,32,2,32,1,56,2,0,2,64,2,64,67,10,215,163,60,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0, + 163,182,149,34,4,139,67,0,0,0,79,93,69,13,0,32,4,168,33,2,12,1,11,65,128,128,128,128,120,33,2,11,32,0,65,136,2,106,34,5,40,2,0,33,6,32,5,32,2,65,1,32,2,65,1,74,27,34,2,54,2,0,32,0,65,132,2,106,34,0,32, + 1,32,3,32,0,42,2,0,32,6,178,148,147,147,32,2,178,149,56,2,0,11,59,1,1,127,2,64,2,64,32,1,142,34,1,139,67,0,0,0,79,93,69,13,0,32,1,168,33,2,12,1,11,65,128,128,128,128,120,33,2,11,32,0,65,228,1,106,32,2, + 65,4,32,2,65,4,73,27,54,2,0,11,73,0,32,0,65,172,2,106,32,1,56,2,0,32,0,65,144,2,106,65,0,43,3,128,128,128,128,0,32,0,65,176,2,106,42,2,0,32,0,65,164,2,106,42,2,0,32,0,65,168,2,106,42,2,0,146,32,1,146,146, + 16,134,128,128,128,0,187,16,135,128,128,128,0,11,81,0,32,0,65,176,2,106,32,1,67,10,215,35,60,148,34,1,56,2,0,32,0,65,144,2,106,65,0,43,3,128,128,128,128,0,32,1,32,0,65,164,2,106,42,2,0,32,0,65,168,2,106, + 42,2,0,146,32,0,65,172,2,106,42,2,0,146,146,16,134,128,128,128,0,187,16,135,128,128,128,0,11,158,1,3,1,127,2,125,2,127,32,0,65,184,2,106,32,1,56,2,0,32,0,65,180,2,106,34,2,42,2,0,33,3,32,2,32,1,56,2,0, + 2,64,2,64,67,10,215,163,60,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,163,182,149,34,4,139,67,0,0,0,79,93,69,13,0,32,4,168,33,2,12,1,11,65,128,128,128,128,120,33,2,11,32,0,65,192,2,106,34,5,40,2, + 0,33,6,32,5,32,2,65,1,32,2,65,1,74,27,34,2,54,2,0,32,0,65,188,2,106,34,0,32,1,32,3,32,0,42,2,0,32,6,178,148,147,147,32,2,178,149,56,2,0,11,59,1,1,127,2,64,2,64,32,1,142,34,1,139,67,0,0,0,79,93,69,13,0, + 32,1,168,33,2,12,1,11,65,128,128,128,128,120,33,2,11,32,0,65,156,2,106,32,2,65,4,32,2,65,4,73,27,54,2,0,11,73,0,32,0,65,228,2,106,32,1,56,2,0,32,0,65,200,2,106,65,0,43,3,128,128,128,128,0,32,0,65,232,2, + 106,42,2,0,32,0,65,220,2,106,42,2,0,32,0,65,224,2,106,42,2,0,146,32,1,146,146,16,134,128,128,128,0,187,16,135,128,128,128,0,11,81,0,32,0,65,232,2,106,32,1,67,10,215,35,60,148,34,1,56,2,0,32,0,65,200,2, + 106,65,0,43,3,128,128,128,128,0,32,1,32,0,65,220,2,106,42,2,0,32,0,65,224,2,106,42,2,0,146,32,0,65,228,2,106,42,2,0,146,146,16,134,128,128,128,0,187,16,135,128,128,128,0,11,158,1,3,1,127,2,125,2,127,32, + 0,65,240,2,106,32,1,56,2,0,32,0,65,236,2,106,34,2,42,2,0,33,3,32,2,32,1,56,2,0,2,64,2,64,67,10,215,163,60,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,163,182,149,34,4,139,67,0,0,0,79,93,69,13,0,32, + 4,168,33,2,12,1,11,65,128,128,128,128,120,33,2,11,32,0,65,248,2,106,34,5,40,2,0,33,6,32,5,32,2,65,1,32,2,65,1,74,27,34,2,54,2,0,32,0,65,244,2,106,34,0,32,1,32,3,32,0,42,2,0,32,6,178,148,147,147,32,2,178, + 149,56,2,0,11,59,1,1,127,2,64,2,64,32,1,142,34,1,139,67,0,0,0,79,93,69,13,0,32,1,168,33,2,12,1,11,65,128,128,128,128,120,33,2,11,32,0,65,212,2,106,32,2,65,4,32,2,65,4,73,27,54,2,0,11,13,0,32,0,65,204,1, + 106,32,1,56,2,0,11,36,0,32,0,65,184,1,106,65,1,58,0,0,32,0,65,192,1,106,32,1,67,205,204,76,61,148,67,0,0,0,63,146,56,2,0,11,13,0,32,0,65,208,1,106,32,1,56,2,0,11,47,0,32,0,65,48,106,68,0,0,0,0,0,0,240, + 63,65,0,43,3,128,128,128,128,0,67,111,18,131,58,32,1,32,1,67,111,18,131,58,93,27,187,162,163,57,3,0,11,53,0,32,0,65,56,106,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,67,111,18,131,58,32,1,32,1,67, + 111,18,131,58,93,27,187,162,163,16,155,128,128,128,0,57,3,0,11,202,7,3,1,126,3,127,3,124,2,64,32,0,189,34,1,66,32,136,167,34,2,65,255,255,255,255,7,113,34,3,32,1,167,34,4,114,13,0,68,0,0,0,0,0,0,240,63, + 15,11,2,64,2,64,32,3,65,128,128,192,255,7,75,13,0,32,4,65,0,71,32,3,65,128,128,192,255,7,70,113,69,13,1,11,32,0,68,45,67,28,235,226,54,26,63,160,15,11,2,64,2,64,2,64,2,64,2,64,32,4,13,0,32,3,65,128,128, + 192,255,7,70,13,1,2,64,32,3,65,128,128,192,255,3,71,13,0,68,45,67,28,235,226,54,26,63,68,0,0,0,0,0,136,195,64,32,1,66,127,85,27,15,11,32,2,65,128,128,128,255,3,70,13,3,68,58,140,48,226,142,121,69,62,33, + 5,32,2,65,128,128,128,128,4,70,13,4,11,2,64,32,3,65,129,128,128,143,4,73,13,0,68,0,0,0,0,0,0,240,127,68,0,0,0,0,0,0,0,0,32,1,66,0,83,27,15,11,32,1,66,128,128,128,128,112,131,191,34,5,68,0,0,0,0,79,147, + 42,192,162,34,6,32,0,68,235,164,171,226,70,243,146,190,162,32,0,32,5,161,68,0,0,0,0,79,147,42,192,162,160,34,0,160,34,7,189,34,1,167,33,4,2,64,32,1,66,32,136,167,34,3,65,128,128,192,132,4,72,13,0,68,0, + 0,0,0,0,0,240,127,33,5,32,3,65,128,128,192,251,123,106,32,4,114,13,4,32,0,68,254,130,43,101,71,21,151,60,160,32,7,32,6,161,100,13,4,12,2,11,32,3,65,128,248,255,255,7,113,65,255,151,195,132,4,77,13,1,68, + 0,0,0,0,0,0,0,0,33,5,32,0,32,7,32,6,161,101,13,3,32,3,65,128,232,188,251,3,106,32,4,114,13,3,12,1,11,68,0,0,0,0,0,0,0,0,32,0,154,32,1,66,127,85,27,15,11,65,0,33,4,2,64,32,3,65,255,255,255,255,7,113,34, + 2,65,128,128,128,255,3,77,13,0,65,0,65,128,128,192,0,32,2,65,20,118,65,130,120,106,118,32,3,106,34,3,65,255,255,63,113,65,128,128,192,0,114,65,147,8,32,3,65,20,118,65,255,15,113,34,2,107,118,34,4,107,32, + 4,32,1,66,0,83,27,33,4,32,0,32,6,65,128,128,64,32,2,65,129,120,106,117,32,3,113,173,66,32,134,191,161,34,6,160,189,33,1,11,2,64,2,64,2,64,32,4,65,20,116,32,1,66,128,128,128,128,112,131,191,34,5,68,0,0, + 0,0,67,46,230,63,162,34,7,32,0,32,5,32,6,161,161,68,239,57,250,254,66,46,230,63,162,32,5,68,57,108,168,12,97,92,32,190,162,160,34,5,160,34,0,32,0,32,0,32,0,32,0,162,34,6,32,6,32,6,32,6,32,6,68,208,164, + 190,114,105,55,102,62,162,68,241,107,210,197,65,189,187,190,160,162,68,44,222,37,175,106,86,17,63,160,162,68,147,189,190,22,108,193,102,191,160,162,68,62,85,85,85,85,85,197,63,160,162,161,34,6,162,32,6, + 68,0,0,0,0,0,0,0,192,160,163,32,5,32,0,32,7,161,161,34,6,32,0,32,6,162,160,161,161,68,0,0,0,0,0,0,240,63,160,34,0,189,34,1,66,32,136,167,106,34,3,65,255,255,63,74,13,0,2,64,32,4,65,128,8,72,13,0,32,0,68, + 0,0,0,0,0,0,224,127,162,33,0,32,4,65,254,15,75,13,2,32,4,65,129,120,106,33,4,12,3,11,32,4,65,130,120,78,13,2,32,0,68,0,0,0,0,0,0,96,3,162,33,0,2,64,32,4,65,184,112,77,13,0,32,4,65,201,7,106,33,4,12,3,11, + 32,0,68,0,0,0,0,0,0,96,3,162,33,0,32,4,65,240,104,32,4,65,240,104,74,27,65,146,15,106,33,4,12,2,11,32,3,173,66,32,134,32,1,66,255,255,255,255,15,131,132,191,15,11,32,0,68,0,0,0,0,0,0,224,127,162,33,0,32, + 4,65,253,23,32,4,65,253,23,72,27,65,130,112,106,33,4,11,32,0,32,4,65,255,7,106,173,66,52,134,191,162,15,11,68,123,20,174,71,225,122,132,63,33,5,11,32,5,11,24,0,32,0,65,192,0,106,32,1,187,68,123,20,174, + 71,225,122,132,63,162,57,3,0,11,54,0,32,0,65,200,0,106,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,67,111,18,131,58,32,1,32,1,67,111,18,131,58,93,27,187,162,163,16,155,128,128,128,0,57,3,0,11,48, + 0,32,0,65,232,0,106,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,67,111,18,131,58,32,1,32,1,67,111,18,131,58,93,27,187,162,163,57,3,0,11,54,0,32,0,65,240,0,106,68,0,0,0,0,0,0,240,63,65,0,43,3,128, + 128,128,128,0,67,111,18,131,58,32,1,32,1,67,111,18,131,58,93,27,187,162,163,16,155,128,128,128,0,57,3,0,11,24,0,32,0,65,248,0,106,32,1,187,68,123,20,174,71,225,122,132,63,162,57,3,0,11,54,0,32,0,65,128, + 1,106,68,0,0,0,0,0,0,240,63,65,0,43,3,128,128,128,128,0,67,111,18,131,58,32,1,32,1,67,111,18,131,58,93,27,187,162,163,16,155,128,128,128,0,57,3,0,11,146,4,4,3,127,1,126,1,125,1,126,35,128,128,128,128,0, + 65,32,107,34,4,36,128,128,128,128,0,32,0,65,208,0,106,65,0,59,0,0,32,0,65,24,106,65,0,54,2,0,32,0,65,136,1,106,65,0,59,0,0,32,0,65,200,0,106,66,171,142,218,200,237,249,253,247,63,55,3,0,32,0,65,192,0,106, + 66,128,128,128,128,128,128,128,248,63,55,3,0,32,0,65,56,106,66,174,143,133,215,199,194,235,247,63,55,3,0,32,0,65,48,106,66,251,168,184,189,148,220,158,194,63,55,3,0,32,0,65,188,1,106,66,128,128,232,163, + 244,158,193,154,63,55,2,0,32,0,65,184,1,106,65,0,58,0,0,32,0,65,128,1,106,66,171,142,218,200,237,249,253,247,63,55,3,0,32,0,65,248,0,106,66,128,128,128,128,128,128,128,248,63,55,3,0,32,0,65,240,0,106,66, + 174,143,133,215,199,194,235,247,63,55,3,0,32,0,65,232,0,106,66,251,168,184,189,148,220,158,194,63,55,3,0,32,4,65,24,106,34,5,66,0,55,3,0,32,4,65,16,106,34,6,66,0,55,3,0,32,4,66,0,55,3,8,32,4,65,8,106,32, + 3,68,0,0,0,0,0,64,143,64,68,0,0,0,224,158,160,230,63,16,163,128,128,128,0,32,6,41,3,0,33,7,32,5,42,2,0,33,8,32,4,41,3,8,33,9,32,4,40,2,28,33,5,32,0,65,228,1,106,65,0,54,2,0,32,0,65,180,1,106,32,5,54,2, + 0,32,0,65,176,1,106,32,8,56,2,0,32,0,65,168,1,106,32,7,55,2,0,32,0,65,160,1,106,32,9,55,2,0,32,0,65,216,1,106,32,3,68,0,0,0,0,0,128,123,64,16,135,128,128,128,0,32,0,65,156,2,106,65,0,54,2,0,32,0,65,144, + 2,106,32,3,68,0,0,0,0,0,128,123,64,16,135,128,128,128,0,32,0,65,212,2,106,65,0,54,2,0,32,0,65,200,2,106,32,3,68,0,0,0,0,0,128,123,64,16,135,128,128,128,0,32,0,65,156,3,106,66,0,55,2,0,32,0,65,148,3,106, + 66,0,55,2,0,65,0,32,3,57,3,128,128,128,128,0,32,0,65,184,35,106,65,0,54,2,0,32,4,65,32,106,36,128,128,128,128,0,11,179,22,6,1,127,2,124,1,126,2,127,3,124,1,127,35,128,128,128,128,0,65,32,107,34,4,36,128, + 128,128,128,0,2,64,2,64,68,0,0,0,0,0,0,224,63,32,1,163,34,5,32,1,68,184,30,133,235,81,184,222,63,162,34,6,68,0,0,0,0,0,0,0,0,32,2,32,2,68,0,0,0,0,0,0,0,0,99,27,32,6,32,2,99,27,68,24,45,68,84,251,33,25, + 64,162,162,34,2,189,34,7,66,32,136,167,34,8,65,255,255,255,255,7,113,34,9,65,251,195,164,255,3,75,13,0,32,9,65,128,128,128,242,3,73,13,1,65,0,33,9,2,64,32,7,66,128,128,128,128,128,255,255,255,255,0,131, + 66,129,128,128,128,240,132,229,242,63,84,34,8,13,0,68,24,45,68,84,251,33,233,63,32,2,154,32,2,32,7,66,0,83,27,161,68,7,92,20,51,38,166,129,60,160,33,2,32,7,66,63,136,167,33,9,11,32,2,32,2,32,2,32,2,162, + 34,10,162,34,11,68,99,85,85,85,85,85,213,63,162,32,10,32,11,32,10,32,10,162,34,6,32,6,32,6,32,6,32,6,68,115,83,96,219,203,117,243,190,162,68,166,146,55,160,136,126,20,63,160,162,68,1,101,242,242,216,68, + 67,63,160,162,68,40,3,86,201,34,109,109,63,160,162,68,55,214,6,132,244,100,150,63,160,162,68,122,254,16,17,17,17,193,63,160,32,10,32,6,32,6,32,6,32,6,32,6,68,212,122,191,116,112,42,251,62,162,68,233,167, + 240,50,15,184,18,63,160,162,68,104,16,141,26,247,38,48,63,160,162,68,21,131,224,254,200,219,87,63,160,162,68,147,132,110,233,227,38,130,63,160,162,68,254,65,179,27,186,161,171,63,160,162,160,162,68,0,0, + 0,0,0,0,0,0,160,162,68,0,0,0,0,0,0,0,0,160,160,34,10,160,33,6,2,64,32,8,69,13,0,32,6,33,2,12,2,11,68,0,0,0,0,0,0,240,63,32,2,32,10,32,6,32,6,162,32,6,68,0,0,0,0,0,0,240,63,160,163,161,160,34,2,32,2,160, + 161,34,2,154,32,2,32,9,27,33,2,12,1,11,2,64,32,9,65,255,255,191,255,7,75,13,0,2,64,2,64,2,64,32,9,65,250,212,189,128,4,75,13,0,2,64,32,8,65,255,255,63,113,65,251,195,36,71,13,0,2,64,32,9,65,20,118,34,9, + 32,2,32,2,68,131,200,201,109,48,95,228,63,162,68,0,0,0,0,0,0,56,67,160,68,0,0,0,0,0,0,56,195,160,34,10,68,0,0,64,84,251,33,249,191,162,160,34,2,32,10,68,49,99,98,26,97,180,208,61,162,34,11,161,34,6,189, + 66,52,136,167,65,255,15,113,107,65,17,72,13,0,2,64,32,9,32,2,32,10,68,0,0,96,26,97,180,208,61,162,34,6,161,34,12,32,10,68,115,112,3,46,138,25,163,59,162,32,2,32,12,161,32,6,161,161,34,11,161,34,6,189,66, + 52,136,167,65,255,15,113,107,65,50,78,13,0,32,12,33,2,12,1,11,32,12,32,10,68,0,0,0,46,138,25,163,59,162,34,6,161,34,2,32,10,68,193,73,32,37,154,131,123,57,162,32,12,32,2,161,32,6,161,161,34,11,161,33,6, + 11,32,2,32,6,161,32,11,161,33,11,2,64,32,10,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,10,170,33,9,12,4,11,65,128,128,128,128,120,33,9,12,3,11,2,64,32,9,65,252,178,139,128,4,75,13,0,2,64,32,7,66,127,87,13, + 0,32,2,68,0,0,64,84,251,33,249,191,160,34,2,32,2,68,49,99,98,26,97,180,208,189,160,34,6,161,68,49,99,98,26,97,180,208,189,160,33,11,65,1,33,9,12,4,11,32,2,68,0,0,64,84,251,33,249,63,160,34,2,32,2,68,49, + 99,98,26,97,180,208,61,160,34,6,161,68,49,99,98,26,97,180,208,61,160,33,11,65,127,33,9,12,3,11,32,7,66,127,85,13,1,32,2,68,0,0,64,84,251,33,9,64,160,34,2,32,2,68,49,99,98,26,97,180,224,61,160,34,6,161, + 68,49,99,98,26,97,180,224,61,160,33,11,65,126,33,9,12,2,11,2,64,2,64,2,64,2,64,2,64,32,9,65,188,140,241,128,4,73,13,0,32,9,65,251,195,228,137,4,79,13,3,32,9,65,20,118,34,9,32,2,32,2,68,131,200,201,109, + 48,95,228,63,162,68,0,0,0,0,0,0,56,67,160,68,0,0,0,0,0,0,56,195,160,34,10,68,0,0,64,84,251,33,249,191,162,160,34,2,32,10,68,49,99,98,26,97,180,208,61,162,34,11,161,34,6,189,66,52,136,167,65,255,15,113, + 107,65,17,72,13,2,32,9,32,2,32,10,68,0,0,96,26,97,180,208,61,162,34,6,161,34,12,32,10,68,115,112,3,46,138,25,163,59,162,32,2,32,12,161,32,6,161,161,34,11,161,34,6,189,66,52,136,167,65,255,15,113,107,65, + 50,78,13,1,32,12,33,2,12,2,11,2,64,2,64,2,64,2,64,32,9,65,189,251,215,128,4,73,13,0,32,9,65,251,195,228,128,4,71,13,3,32,2,32,2,68,131,200,201,109,48,95,228,63,162,68,0,0,0,0,0,0,56,67,160,68,0,0,0,0,0, + 0,56,195,160,34,10,68,0,0,64,84,251,33,249,191,162,160,34,2,32,10,68,49,99,98,26,97,180,208,61,162,34,11,161,34,6,189,66,128,128,128,128,128,128,128,248,255,0,131,66,255,255,255,255,255,255,255,135,63, + 86,13,2,32,2,32,10,68,0,0,96,26,97,180,208,61,162,34,6,161,34,12,32,10,68,115,112,3,46,138,25,163,59,162,32,2,32,12,161,32,6,161,161,34,11,161,34,6,189,66,128,128,128,128,128,128,128,128,255,0,131,66,255, + 255,255,255,255,255,255,255,60,88,13,1,32,12,33,2,12,2,11,32,9,65,252,178,203,128,4,70,13,6,2,64,32,7,66,0,83,13,0,32,2,68,0,0,48,127,124,217,18,192,160,34,2,32,2,68,202,148,147,167,145,14,233,189,160, + 34,6,161,68,202,148,147,167,145,14,233,189,160,33,11,65,3,33,9,12,9,11,32,2,68,0,0,48,127,124,217,18,64,160,34,2,32,2,68,202,148,147,167,145,14,233,61,160,34,6,161,68,202,148,147,167,145,14,233,61,160, + 33,11,65,125,33,9,12,8,11,32,12,32,10,68,0,0,0,46,138,25,163,59,162,34,6,161,34,2,32,10,68,193,73,32,37,154,131,123,57,162,32,12,32,2,161,32,6,161,161,34,11,161,33,6,11,32,2,32,6,161,32,11,161,33,11,2, + 64,32,10,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,10,170,33,9,12,7,11,65,128,128,128,128,120,33,9,12,6,11,2,64,32,7,66,0,83,13,0,32,2,68,0,0,64,84,251,33,25,192,160,34,2,32,2,68,49,99,98,26,97,180,240,189, + 160,34,6,161,68,49,99,98,26,97,180,240,189,160,33,11,65,4,33,9,12,6,11,32,2,68,0,0,64,84,251,33,25,64,160,34,2,32,2,68,49,99,98,26,97,180,240,61,160,34,6,161,68,49,99,98,26,97,180,240,61,160,33,11,65,124, + 33,9,12,5,11,32,12,32,10,68,0,0,0,46,138,25,163,59,162,34,6,161,34,2,32,10,68,193,73,32,37,154,131,123,57,162,32,12,32,2,161,32,6,161,161,34,11,161,33,6,11,32,2,32,6,161,32,11,161,33,11,2,64,32,10,153, + 68,0,0,0,0,0,0,224,65,99,69,13,0,32,10,170,33,9,12,4,11,65,128,128,128,128,120,33,9,12,3,11,2,64,2,64,32,7,66,255,255,255,255,255,255,255,7,131,66,128,128,128,128,128,128,128,176,193,0,132,191,34,2,153, + 68,0,0,0,0,0,0,224,65,99,69,13,0,32,2,170,33,8,12,1,11,65,128,128,128,128,120,33,8,11,2,64,2,64,32,2,32,8,183,34,6,161,68,0,0,0,0,0,0,112,65,162,34,2,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,2,170,33,13, + 12,1,11,65,128,128,128,128,120,33,13,11,32,4,65,8,106,32,6,32,13,183,34,10,32,2,32,10,161,68,0,0,0,0,0,0,112,65,162,34,2,32,9,65,20,118,65,234,119,106,65,3,65,2,32,8,65,0,71,32,13,27,32,2,68,0,0,0,0,0, + 0,0,0,100,32,2,68,0,0,0,0,0,0,0,0,99,114,27,65,1,16,164,128,128,128,0,32,4,43,3,24,33,11,32,4,43,3,16,33,6,32,4,40,2,8,33,9,32,7,66,127,85,13,2,65,0,32,9,107,33,9,32,11,154,33,11,32,6,154,33,6,12,2,11, + 2,64,32,2,32,2,68,131,200,201,109,48,95,228,63,162,68,0,0,0,0,0,0,56,67,160,68,0,0,0,0,0,0,56,195,160,34,10,68,0,0,64,84,251,33,249,191,162,160,34,2,32,10,68,49,99,98,26,97,180,208,61,162,34,11,161,34, + 6,189,66,128,128,128,128,128,128,128,248,255,0,131,66,255,255,255,255,255,255,255,135,63,86,13,0,2,64,32,2,32,10,68,0,0,96,26,97,180,208,61,162,34,6,161,34,12,32,10,68,115,112,3,46,138,25,163,59,162,32, + 2,32,12,161,32,6,161,161,34,11,161,34,6,189,66,128,128,128,128,128,128,128,128,255,0,131,66,255,255,255,255,255,255,255,255,60,88,13,0,32,12,33,2,12,1,11,32,12,32,10,68,0,0,0,46,138,25,163,59,162,34,6, + 161,34,2,32,10,68,193,73,32,37,154,131,123,57,162,32,12,32,2,161,32,6,161,161,34,11,161,33,6,11,32,2,32,6,161,32,11,161,33,11,2,64,32,10,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,10,170,33,9,12,2,11,65,128, + 128,128,128,120,33,9,12,1,11,32,2,68,0,0,64,84,251,33,9,192,160,34,2,32,2,68,49,99,98,26,97,180,224,189,160,34,6,161,68,49,99,98,26,97,180,224,189,160,33,11,65,2,33,9,11,65,0,33,8,2,64,32,6,189,34,7,66, + 128,128,128,128,128,255,255,255,255,0,131,66,129,128,128,128,240,132,229,242,63,84,34,13,13,0,68,24,45,68,84,251,33,233,63,32,6,154,32,6,32,7,66,0,83,34,8,27,161,68,7,92,20,51,38,166,129,60,32,11,154,32, + 11,32,8,27,161,160,33,6,32,7,66,63,136,167,33,8,68,0,0,0,0,0,0,0,0,33,11,11,32,9,65,1,113,33,9,32,6,32,6,32,6,32,6,162,34,10,162,34,12,68,99,85,85,85,85,85,213,63,162,32,11,32,10,32,11,32,12,32,10,32,10, + 162,34,2,32,2,32,2,32,2,32,2,68,115,83,96,219,203,117,243,190,162,68,166,146,55,160,136,126,20,63,160,162,68,1,101,242,242,216,68,67,63,160,162,68,40,3,86,201,34,109,109,63,160,162,68,55,214,6,132,244, + 100,150,63,160,162,68,122,254,16,17,17,17,193,63,160,32,10,32,2,32,2,32,2,32,2,32,2,68,212,122,191,116,112,42,251,62,162,68,233,167,240,50,15,184,18,63,160,162,68,104,16,141,26,247,38,48,63,160,162,68, + 21,131,224,254,200,219,87,63,160,162,68,147,132,110,233,227,38,130,63,160,162,68,254,65,179,27,186,161,171,63,160,162,160,162,160,162,160,160,34,10,160,33,2,2,64,32,13,13,0,65,1,32,9,65,1,116,107,183,34, + 11,32,6,32,10,32,2,32,2,162,32,2,32,11,160,163,161,160,34,2,32,2,160,161,34,2,154,32,2,32,8,27,33,2,12,2,11,32,9,69,13,1,68,0,0,0,0,0,0,240,191,32,2,163,34,11,32,2,189,66,128,128,128,128,112,131,191,34, + 12,32,11,189,66,128,128,128,128,112,131,191,34,2,162,68,0,0,0,0,0,0,240,63,160,32,10,32,12,32,6,161,161,32,2,162,160,162,32,2,160,33,2,12,1,11,32,2,32,2,161,33,2,11,32,0,32,5,32,1,32,1,160,32,2,162,162, + 34,2,182,56,2,4,32,0,68,0,0,0,0,0,0,240,63,32,3,163,34,1,32,2,160,182,56,2,8,32,0,68,0,0,0,0,0,0,240,63,32,2,32,2,162,32,1,32,2,162,68,0,0,0,0,0,0,240,63,160,160,163,182,56,2,0,32,4,65,32,106,36,128,128, + 128,128,0,11,207,24,7,10,127,1,124,5,127,1,124,7,127,1,124,3,127,35,128,128,128,128,0,65,176,4,107,34,7,36,128,128,128,128,0,32,7,66,128,128,128,128,208,227,252,180,53,55,3,168,4,32,7,66,128,128,128,128, + 168,196,224,241,54,55,3,160,4,32,7,66,128,128,128,128,132,164,137,189,56,55,3,152,4,32,7,66,128,128,128,128,184,240,134,248,57,55,3,144,4,32,7,66,128,128,128,128,150,138,179,188,59,55,3,136,4,32,7,66,128, + 128,128,128,136,211,145,252,60,55,3,128,4,32,7,66,128,128,128,128,208,133,145,186,62,55,3,248,3,32,7,66,128,128,128,128,180,191,200,252,63,55,3,240,3,65,0,33,8,32,7,65,240,2,106,65,0,65,128,1,16,128,128, + 128,128,0,26,32,7,65,240,1,106,65,0,65,128,1,16,128,128,128,128,0,26,32,7,65,240,0,106,65,0,65,128,1,16,128,128,128,128,0,26,32,4,65,125,106,65,24,109,34,9,65,0,32,9,65,0,74,27,34,10,65,104,108,32,4,106, + 33,11,2,64,32,6,65,3,106,34,12,32,5,65,127,106,34,13,106,65,0,72,13,0,32,10,65,2,116,32,5,65,2,116,107,65,148,128,128,128,0,106,33,9,32,6,32,5,106,65,3,106,33,14,32,10,32,13,107,34,15,33,4,3,64,32,4,65, + 194,0,110,33,16,2,64,2,64,32,15,32,8,106,65,127,74,13,0,68,0,0,0,0,0,0,0,0,33,17,12,1,11,32,9,32,16,65,248,125,108,106,40,2,0,183,33,17,11,32,7,65,240,2,106,32,8,65,15,113,65,3,116,106,32,17,57,3,0,32, + 9,65,4,106,33,9,32,4,65,1,106,33,4,32,14,32,8,65,1,106,34,8,71,13,0,11,11,32,11,65,104,106,33,18,2,64,32,6,65,124,76,13,0,65,0,33,8,32,12,65,0,32,12,65,0,74,27,33,14,2,64,32,5,65,0,74,13,0,32,14,65,1,106, + 33,4,3,64,32,7,65,240,0,106,32,8,65,15,113,65,3,116,106,66,0,55,3,0,32,4,32,8,65,1,106,34,8,71,13,0,12,2,11,11,65,0,33,16,3,64,68,0,0,0,0,0,0,0,0,33,17,32,7,65,216,0,106,33,8,32,13,33,4,65,0,33,9,3,64, + 32,7,32,3,57,3,104,32,7,32,2,57,3,96,32,7,32,1,57,3,88,32,17,32,8,32,9,65,3,110,65,104,108,106,43,3,0,32,7,65,240,2,106,32,16,32,4,106,65,15,113,65,3,116,106,43,3,0,162,160,33,17,32,8,65,8,106,33,8,32, + 9,65,1,106,33,9,32,4,65,127,106,34,4,65,127,71,13,0,11,32,7,65,240,0,106,32,16,65,15,113,65,3,116,106,32,17,57,3,0,32,16,32,14,70,33,8,32,16,65,1,106,33,16,32,8,69,13,0,11,11,32,7,65,208,0,106,66,0,55, + 3,0,32,7,65,24,106,65,48,106,66,0,55,3,0,32,7,65,192,0,106,66,0,55,3,0,32,7,65,56,106,66,0,55,3,0,32,7,65,48,106,66,0,55,3,0,32,7,65,40,106,66,0,55,3,0,32,7,65,24,106,65,8,106,66,0,55,3,0,32,7,66,0,55, + 3,24,68,0,0,0,0,0,0,240,127,68,0,0,0,0,0,0,224,127,32,18,65,254,15,75,34,19,27,68,0,0,0,0,0,0,0,0,68,0,0,0,0,0,0,96,3,32,18,65,185,112,73,34,20,27,68,0,0,0,0,0,0,240,63,32,18,65,130,120,72,34,8,27,32,18, + 65,255,7,74,34,4,27,32,18,65,253,23,32,18,65,253,23,72,27,65,130,112,106,32,11,65,233,119,106,32,19,27,34,21,32,18,65,240,104,32,18,65,240,104,74,27,65,146,15,106,32,11,65,177,7,106,32,20,27,34,22,32,18, + 32,8,27,32,4,27,65,255,7,106,173,66,52,134,191,162,33,23,32,6,65,2,106,33,24,65,47,32,11,107,33,25,65,48,32,11,107,33,26,32,18,65,128,8,72,33,27,32,11,65,103,106,33,28,32,18,65,129,120,74,33,29,32,12,33, + 14,2,64,3,64,32,7,65,240,0,106,32,14,34,16,65,15,113,34,30,65,3,116,106,43,3,0,33,17,2,64,32,16,65,1,72,34,15,13,0,32,16,65,15,106,33,8,65,0,33,4,3,64,32,4,65,15,113,65,2,116,33,9,2,64,2,64,32,17,68,0, + 0,0,0,0,0,112,62,162,34,31,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,31,170,33,14,12,1,11,65,128,128,128,128,120,33,14,11,32,7,65,24,106,32,9,106,33,9,2,64,2,64,32,17,32,14,183,34,31,68,0,0,0,0,0,0,112,193, + 162,160,34,17,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,17,170,33,14,12,1,11,65,128,128,128,128,120,33,14,11,32,9,32,14,54,2,0,32,7,65,240,0,106,32,8,65,15,113,65,3,116,106,43,3,0,32,31,160,33,17,32,4,65, + 1,106,33,4,32,8,65,127,106,34,8,65,15,71,13,0,11,11,2,64,2,64,32,27,13,0,32,17,68,0,0,0,0,0,0,224,127,162,34,17,68,0,0,0,0,0,0,224,127,162,32,17,32,19,27,33,17,32,21,33,8,12,1,11,2,64,32,29,69,13,0,32, + 18,33,8,12,1,11,32,17,68,0,0,0,0,0,0,96,3,162,34,17,68,0,0,0,0,0,0,96,3,162,32,17,32,20,27,33,17,32,22,33,8,11,2,64,2,64,32,17,32,8,65,255,7,106,173,66,52,134,191,162,34,17,32,17,68,0,0,0,0,0,0,192,63, + 162,156,68,0,0,0,0,0,0,32,192,162,160,34,17,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,17,170,33,13,12,1,11,65,128,128,128,128,120,33,13,11,32,17,32,13,183,161,33,17,2,64,2,64,2,64,2,64,32,18,65,1,72,34,32, + 13,0,32,7,65,24,106,32,16,65,127,106,65,15,113,65,2,116,106,34,8,32,8,40,2,0,34,8,32,8,32,26,117,34,8,32,26,116,107,34,4,54,2,0,32,4,32,25,117,33,33,32,8,32,13,106,33,13,12,1,11,2,64,32,18,13,0,32,7,65, + 24,106,32,16,65,127,106,65,15,113,65,2,116,106,40,2,0,65,23,117,33,33,12,1,11,65,2,33,33,65,0,33,34,32,17,68,0,0,0,0,0,0,224,63,102,69,13,2,12,1,11,32,33,65,0,74,13,0,32,33,33,34,12,1,11,2,64,2,64,32,15, + 69,13,0,65,0,33,14,12,1,11,65,0,33,8,65,0,33,14,3,64,32,7,65,24,106,32,8,65,15,113,65,2,116,106,34,15,40,2,0,33,4,65,255,255,255,7,33,9,2,64,2,64,32,14,65,1,113,13,0,65,128,128,128,8,33,9,32,4,13,0,65, + 0,33,14,12,1,11,32,15,32,9,32,4,107,54,2,0,65,1,33,14,11,32,16,32,8,65,1,106,34,8,71,13,0,11,11,2,64,32,32,13,0,65,255,255,255,3,33,8,2,64,2,64,32,28,14,2,1,0,2,11,65,255,255,255,1,33,8,11,32,7,65,24,106, + 32,16,65,127,106,65,15,113,65,2,116,106,34,4,32,4,40,2,0,32,8,113,54,2,0,11,32,13,65,1,106,33,13,65,2,33,34,32,33,65,2,71,13,0,68,0,0,0,0,0,0,240,63,32,17,161,34,17,32,23,161,32,17,32,14,27,33,17,11,2, + 64,32,17,68,0,0,0,0,0,0,0,0,98,13,0,2,64,32,16,65,127,106,32,12,72,13,0,65,0,33,4,32,16,33,8,3,64,32,7,65,24,106,32,8,65,127,106,34,8,65,15,113,65,2,116,106,40,2,0,32,4,114,33,4,32,8,32,12,74,13,0,11,32, + 4,69,13,0,32,18,33,11,3,64,32,11,65,104,106,33,11,32,7,65,24,106,32,16,65,127,106,34,16,65,15,113,65,2,116,106,40,2,0,69,13,0,12,4,11,11,32,24,33,8,32,16,33,14,3,64,32,14,65,1,106,33,14,32,8,65,15,113, + 33,4,32,8,65,127,106,33,8,32,7,65,24,106,32,4,65,2,116,106,40,2,0,69,13,0,11,32,16,65,1,106,34,15,32,14,74,13,1,3,64,32,7,65,240,2,106,32,16,32,5,106,65,15,113,65,3,116,106,32,15,32,10,106,65,194,0,111, + 34,8,65,194,0,106,32,8,32,8,65,0,72,27,65,2,116,65,144,128,128,128,0,106,40,2,0,183,57,3,0,68,0,0,0,0,0,0,0,0,33,17,2,64,32,5,65,1,72,13,0,65,0,33,8,32,7,33,4,32,5,33,9,3,64,32,7,32,3,57,3,16,32,7,32,2, + 57,3,8,32,7,32,1,57,3,0,32,17,32,4,32,8,65,3,110,65,104,108,106,43,3,0,32,7,65,240,2,106,32,16,32,9,106,65,15,113,65,3,116,106,43,3,0,162,160,33,17,32,4,65,8,106,33,4,32,8,65,1,106,33,8,32,9,65,127,106, + 34,9,13,0,11,11,32,7,65,240,0,106,32,15,65,15,113,65,3,116,106,32,17,57,3,0,32,16,65,1,106,33,16,32,15,65,1,106,34,15,32,14,74,13,2,12,0,11,11,11,2,64,2,64,2,64,65,24,32,11,107,34,8,65,128,8,72,13,0,32, + 17,68,0,0,0,0,0,0,224,127,162,33,17,32,8,65,254,15,75,13,1,65,153,120,32,11,107,33,8,12,2,11,32,8,65,130,120,78,13,1,32,17,68,0,0,0,0,0,0,96,3,162,33,17,2,64,32,8,65,184,112,77,13,0,65,225,7,32,11,107, + 33,8,12,2,11,32,17,68,0,0,0,0,0,0,96,3,162,33,17,32,8,65,240,104,32,8,65,240,104,74,27,65,146,15,106,33,8,12,1,11,32,17,68,0,0,0,0,0,0,224,127,162,33,17,32,8,65,253,23,32,8,65,253,23,72,27,65,130,112,106, + 33,8,11,2,64,2,64,32,17,32,8,65,255,7,106,173,66,52,134,191,162,34,17,68,0,0,0,0,0,0,112,65,102,69,13,0,32,30,65,2,116,33,4,2,64,2,64,32,17,68,0,0,0,0,0,0,112,62,162,34,3,153,68,0,0,0,0,0,0,224,65,99,69, + 13,0,32,3,170,33,8,12,1,11,65,128,128,128,128,120,33,8,11,32,7,65,24,106,32,4,106,33,4,2,64,2,64,32,17,32,8,183,68,0,0,0,0,0,0,112,193,162,160,34,17,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,17,170,33,9, + 12,1,11,65,128,128,128,128,120,33,9,11,32,4,32,9,54,2,0,32,16,65,1,106,34,16,65,15,113,33,30,12,1,11,2,64,2,64,32,17,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,17,170,33,8,12,1,11,65,128,128,128,128,120,33, + 8,11,32,18,33,11,11,32,7,65,24,106,32,30,65,2,116,106,32,8,54,2,0,11,2,64,2,64,2,64,32,11,65,128,8,72,13,0,32,11,65,254,15,75,13,1,32,11,65,129,120,106,33,11,68,0,0,0,0,0,0,224,127,33,17,12,2,11,68,0,0, + 0,0,0,0,240,63,33,17,32,11,65,130,120,78,13,1,2,64,32,11,65,184,112,77,13,0,32,11,65,201,7,106,33,11,68,0,0,0,0,0,0,96,3,33,17,12,2,11,32,11,65,240,104,32,11,65,240,104,74,27,65,146,15,106,33,11,68,0,0, + 0,0,0,0,0,0,33,17,12,1,11,32,11,65,253,23,32,11,65,253,23,72,27,65,130,112,106,33,11,68,0,0,0,0,0,0,240,127,33,17,11,68,0,0,0,0,0,0,0,0,33,2,68,0,0,0,0,0,0,0,0,33,3,2,64,32,16,65,0,72,13,0,32,17,32,11, + 65,255,7,106,173,66,52,134,191,162,33,17,32,16,33,8,3,64,32,7,65,240,0,106,32,8,65,15,113,34,4,65,3,116,106,32,17,32,7,65,24,106,32,4,65,2,116,106,40,2,0,183,162,57,3,0,32,17,68,0,0,0,0,0,0,112,62,162, + 33,17,32,8,65,127,106,34,8,65,127,71,13,0,11,68,0,0,0,0,0,0,0,0,33,3,32,16,65,0,72,13,0,32,16,33,4,3,64,68,0,0,0,0,0,0,0,0,33,17,2,64,32,12,32,16,32,4,107,34,14,32,12,32,14,72,27,34,9,65,0,72,13,0,65,0, + 33,8,3,64,32,17,32,7,65,240,3,106,32,8,65,7,113,65,3,116,106,43,3,0,32,7,65,240,0,106,32,4,32,8,106,65,15,113,65,3,116,106,43,3,0,162,160,33,17,32,8,65,1,106,34,8,32,9,76,13,0,11,11,32,7,65,240,1,106,32, + 14,65,15,113,65,3,116,106,32,17,57,3,0,32,4,65,0,74,33,8,32,4,65,127,106,33,4,32,8,13,0,11,68,0,0,0,0,0,0,0,0,33,3,32,16,65,0,72,13,0,32,16,33,8,3,64,32,3,32,7,65,240,1,106,32,8,65,15,113,65,3,116,106, + 43,3,0,160,33,3,32,8,65,127,106,34,8,65,127,71,13,0,11,11,2,64,32,6,69,13,0,32,7,43,3,240,1,32,3,161,33,17,2,64,32,16,65,1,72,13,0,65,1,33,8,3,64,32,17,32,7,65,240,1,106,32,8,65,15,113,65,3,116,106,43, + 3,0,160,33,17,32,8,65,1,106,34,8,32,16,76,13,0,11,11,32,17,154,32,17,32,34,27,33,2,11,32,0,32,2,57,3,16,32,0,32,13,65,7,113,54,2,0,32,0,32,3,154,32,3,32,34,27,57,3,8,32,7,65,176,4,106,36,128,128,128,128, + 0,11,153,30,7,1,127,2,124,7,127,2,125,1,127,5,125,1,127,35,128,128,128,128,0,65,128,31,107,34,3,36,128,128,128,128,0,2,64,32,0,40,2,0,32,2,70,13,0,2,64,2,64,65,0,43,3,128,128,128,128,0,34,4,68,0,0,0,0, + 0,0,62,64,163,34,5,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,5,170,33,6,12,1,11,65,128,128,128,128,120,33,6,11,32,0,65,172,3,106,33,7,32,0,65,160,1,106,33,8,32,0,65,200,2,106,33,9,32,0,65,144,2,106,33,10, + 32,0,65,216,1,106,33,11,3,64,2,64,32,0,40,2,44,34,12,65,127,70,13,0,2,64,32,12,65,0,74,13,0,32,0,32,0,42,2,28,34,13,56,2,240,1,32,11,32,4,32,13,32,0,42,2,236,1,146,32,0,42,2,244,1,146,32,0,42,2,248,1,146, + 16,134,128,128,128,0,187,16,135,128,128,128,0,32,0,32,13,56,2,168,2,32,10,32,4,32,13,32,0,42,2,164,2,146,32,0,42,2,172,2,146,32,0,42,2,176,2,146,16,134,128,128,128,0,187,16,135,128,128,128,0,32,0,32,13, + 56,2,224,2,32,9,32,4,32,13,32,0,42,2,220,2,146,32,0,42,2,228,2,146,32,0,42,2,232,2,146,16,134,128,128,128,0,187,16,135,128,128,128,0,11,2,64,32,0,40,2,40,34,12,65,1,72,13,0,32,0,32,12,65,127,106,54,2,40, + 32,0,32,0,42,2,28,32,0,42,2,36,146,34,13,56,2,240,1,32,0,32,13,56,2,28,32,11,32,4,32,13,32,0,42,2,236,1,146,32,0,42,2,244,1,146,32,0,42,2,248,1,146,16,134,128,128,128,0,187,16,135,128,128,128,0,32,0,32, + 13,56,2,168,2,32,10,32,4,32,13,32,0,42,2,164,2,146,32,0,42,2,172,2,146,32,0,42,2,176,2,146,16,134,128,128,128,0,187,16,135,128,128,128,0,32,0,32,13,56,2,224,2,32,9,32,4,32,13,32,0,42,2,220,2,146,32,0,42, + 2,228,2,146,32,0,42,2,232,2,146,16,134,128,128,128,0,187,16,135,128,128,128,0,11,32,0,65,1,54,2,44,11,67,0,0,0,0,33,13,67,0,0,0,0,33,14,2,64,32,0,40,2,96,34,12,65,127,70,13,0,2,64,2,64,2,64,2,64,2,64,2, + 64,2,64,2,64,2,64,2,64,2,64,2,64,32,12,65,0,74,13,0,32,0,66,0,55,3,88,12,1,11,32,12,65,4,73,13,1,11,32,0,45,0,80,13,1,32,0,43,3,88,33,5,12,7,11,32,0,45,0,80,33,15,32,12,65,127,106,14,3,1,2,4,2,11,65,0, + 33,15,32,0,65,0,58,0,80,11,32,0,45,0,81,33,12,32,0,43,3,88,34,5,68,0,0,0,0,0,0,240,63,99,69,13,1,32,12,65,1,113,69,13,1,32,15,65,1,113,13,1,32,5,32,0,43,3,48,160,34,5,68,0,0,0,0,0,0,240,63,32,5,68,0,0, + 0,0,0,0,240,63,99,27,33,5,65,1,33,12,12,5,11,32,0,45,0,81,33,12,32,0,43,3,88,33,5,11,32,5,32,0,43,3,64,102,69,13,1,32,12,65,1,113,69,13,1,32,15,65,1,113,13,1,32,5,32,0,43,3,56,162,33,5,65,2,33,12,12,3, + 11,32,0,43,3,88,33,5,32,0,45,0,81,33,12,11,32,12,65,1,113,69,13,0,65,3,33,12,32,15,65,1,113,69,13,2,11,32,5,32,0,43,3,72,162,33,5,65,4,33,12,11,32,0,32,5,57,3,88,11,32,0,32,12,54,2,96,32,5,182,67,0,0,0, + 0,146,33,14,11,2,64,32,0,40,2,152,1,34,12,65,127,70,13,0,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,32,12,65,0,74,13,0,32,0,66,0,55,3,144,1,12,1,11,32,12,65,4,73,13,1,11,32,0,45,0,136, + 1,13,1,32,0,43,3,144,1,33,5,12,7,11,32,0,45,0,136,1,33,15,32,12,65,127,106,14,3,1,2,4,2,11,65,0,33,15,32,0,65,0,58,0,136,1,11,32,0,45,0,137,1,33,12,32,0,43,3,144,1,34,5,68,0,0,0,0,0,0,240,63,99,69,13,1, + 32,12,65,1,113,69,13,1,32,15,65,1,113,13,1,32,5,32,0,43,3,104,160,34,5,68,0,0,0,0,0,0,240,63,32,5,68,0,0,0,0,0,0,240,63,99,27,33,5,65,1,33,12,12,5,11,32,0,45,0,137,1,33,12,32,0,43,3,144,1,33,5,11,32,5, + 32,0,43,3,120,102,69,13,1,32,12,65,1,113,69,13,1,32,15,65,1,113,13,1,32,5,32,0,43,3,112,162,33,5,65,2,33,12,12,3,11,32,0,43,3,144,1,33,5,32,0,45,0,137,1,33,12,11,32,12,65,1,113,69,13,0,65,3,33,12,32,15, + 65,1,113,69,13,2,11,32,5,32,0,43,3,128,1,162,33,5,65,4,33,12,11,32,0,32,5,57,3,144,1,11,32,0,32,12,54,2,152,1,32,5,182,67,0,0,0,0,146,33,13,11,2,64,32,0,40,2,212,1,65,127,70,13,0,32,0,65,1,54,2,212,1,32, + 0,65,1,58,0,184,1,32,0,32,0,42,2,204,1,32,13,32,0,42,2,208,1,148,67,0,0,72,66,148,146,34,13,67,0,0,200,66,32,13,67,0,0,200,66,94,27,56,2,188,1,11,67,0,0,0,0,33,13,67,0,0,0,0,33,16,2,64,32,0,40,2,164,3, + 65,127,70,13,0,2,64,2,64,32,0,40,2,160,3,34,12,65,1,72,13,0,32,0,32,12,65,127,106,34,12,54,2,160,3,32,0,42,2,148,3,32,0,42,2,156,3,32,12,178,148,147,33,17,12,1,11,32,0,42,2,148,3,33,17,11,32,0,65,1,54, + 2,164,3,32,17,67,0,0,0,0,146,33,16,11,2,64,32,0,40,2,232,1,65,127,70,13,0,67,0,0,0,0,33,13,2,64,2,64,2,64,2,64,2,64,2,64,32,0,40,2,228,1,14,5,0,1,2,3,4,5,11,32,11,16,166,128,128,128,0,67,0,0,0,0,146,33, + 13,12,4,11,32,0,32,11,16,167,128,128,128,0,32,0,42,2,220,1,34,13,148,32,0,42,2,224,1,32,13,67,0,0,128,190,148,67,0,0,128,63,146,148,146,34,13,56,2,224,1,32,13,67,0,0,128,64,148,67,0,0,0,0,146,33,13,12, + 3,11,32,11,16,167,128,128,128,0,67,0,0,0,0,146,33,13,12,2,11,32,0,32,0,42,2,216,1,34,13,32,0,42,2,220,1,34,17,146,34,18,67,0,0,128,191,146,32,18,32,18,67,0,0,128,63,96,27,56,2,216,1,2,64,2,64,32,13,32, + 17,93,69,13,0,32,13,32,17,149,34,17,32,17,146,32,17,32,17,148,147,67,0,0,128,191,146,33,18,12,1,11,67,0,0,0,0,33,18,67,0,0,128,63,32,17,147,32,13,93,69,13,0,32,13,67,0,0,128,191,146,32,17,149,34,17,32, + 17,146,32,17,32,17,148,146,67,0,0,128,63,146,33,18,11,32,13,32,13,146,67,0,0,128,191,146,32,18,147,33,13,12,1,11,32,0,32,0,42,2,216,1,34,13,32,0,42,2,220,1,34,17,146,34,18,67,0,0,128,191,146,32,18,32,18, + 67,0,0,128,63,96,27,56,2,216,1,2,64,2,64,32,13,32,17,93,69,13,0,32,13,32,17,149,34,17,32,17,146,32,17,32,17,148,147,67,0,0,128,191,146,33,18,12,1,11,67,0,0,0,0,33,18,67,0,0,128,63,32,17,147,32,13,93,69, + 13,0,32,13,67,0,0,128,191,146,32,17,149,34,17,32,17,146,32,17,32,17,148,146,67,0,0,128,63,146,33,18,11,32,18,32,13,32,13,146,67,0,0,128,191,146,147,33,13,11,32,0,65,1,54,2,232,1,11,67,0,0,0,0,33,17,67, + 0,0,0,0,33,18,2,64,32,0,40,2,140,2,65,127,70,13,0,2,64,2,64,32,0,40,2,136,2,34,12,65,1,72,13,0,32,0,32,12,65,127,106,34,12,54,2,136,2,32,0,42,2,252,1,32,0,42,2,132,2,32,12,178,148,147,33,18,12,1,11,32, + 0,42,2,252,1,33,18,11,32,0,65,1,54,2,140,2,32,13,32,18,148,67,0,0,0,0,146,33,18,11,2,64,32,0,40,2,160,2,65,127,70,13,0,67,0,0,0,0,33,17,2,64,2,64,2,64,2,64,2,64,2,64,32,0,40,2,156,2,14,5,0,1,2,3,4,5,11, + 32,10,16,166,128,128,128,0,67,0,0,0,0,146,33,17,12,4,11,32,0,32,10,16,167,128,128,128,0,32,0,42,2,148,2,34,13,148,32,0,42,2,152,2,32,13,67,0,0,128,190,148,67,0,0,128,63,146,148,146,34,13,56,2,152,2,32, + 13,67,0,0,128,64,148,67,0,0,0,0,146,33,17,12,3,11,32,10,16,167,128,128,128,0,67,0,0,0,0,146,33,17,12,2,11,32,0,32,0,42,2,144,2,34,13,32,0,42,2,148,2,34,17,146,34,19,67,0,0,128,191,146,32,19,32,19,67,0, + 0,128,63,96,27,56,2,144,2,2,64,2,64,32,13,32,17,93,69,13,0,32,13,32,17,149,34,17,32,17,146,32,17,32,17,148,147,67,0,0,128,191,146,33,19,12,1,11,67,0,0,0,0,33,19,67,0,0,128,63,32,17,147,32,13,93,69,13,0, + 32,13,67,0,0,128,191,146,32,17,149,34,17,32,17,146,32,17,32,17,148,146,67,0,0,128,63,146,33,19,11,32,13,32,13,146,67,0,0,128,191,146,32,19,147,33,17,12,1,11,32,0,32,0,42,2,144,2,34,13,32,0,42,2,148,2,34, + 17,146,34,19,67,0,0,128,191,146,32,19,32,19,67,0,0,128,63,96,27,56,2,144,2,2,64,2,64,32,13,32,17,93,69,13,0,32,13,32,17,149,34,17,32,17,146,32,17,32,17,148,147,67,0,0,128,191,146,33,19,12,1,11,67,0,0,0, + 0,33,19,67,0,0,128,63,32,17,147,32,13,93,69,13,0,32,13,67,0,0,128,191,146,32,17,149,34,17,32,17,146,32,17,32,17,148,146,67,0,0,128,63,146,33,19,11,32,19,32,13,32,13,146,67,0,0,128,191,146,147,33,17,11, + 32,0,65,1,54,2,160,2,11,67,0,0,0,0,33,13,67,0,0,0,0,33,19,2,64,32,0,40,2,196,2,65,127,70,13,0,2,64,2,64,32,0,40,2,192,2,34,12,65,1,72,13,0,32,0,32,12,65,127,106,34,12,54,2,192,2,32,0,42,2,180,2,32,0,42, + 2,188,2,32,12,178,148,147,33,19,12,1,11,32,0,42,2,180,2,33,19,11,32,0,65,1,54,2,196,2,32,17,32,19,148,67,0,0,0,0,146,33,19,11,2,64,32,0,40,2,216,2,65,127,70,13,0,67,0,0,0,0,33,13,2,64,2,64,2,64,2,64,2, + 64,2,64,32,0,40,2,212,2,14,5,0,1,2,3,4,5,11,32,9,16,166,128,128,128,0,67,0,0,0,0,146,33,13,12,4,11,32,0,32,9,16,167,128,128,128,0,32,0,42,2,204,2,34,13,148,32,0,42,2,208,2,32,13,67,0,0,128,190,148,67,0, + 0,128,63,146,148,146,34,13,56,2,208,2,32,13,67,0,0,128,64,148,67,0,0,0,0,146,33,13,12,3,11,32,9,16,167,128,128,128,0,67,0,0,0,0,146,33,13,12,2,11,32,0,32,0,42,2,200,2,34,13,32,0,42,2,204,2,34,17,146,34, + 20,67,0,0,128,191,146,32,20,32,20,67,0,0,128,63,96,27,56,2,200,2,2,64,2,64,32,13,32,17,93,69,13,0,32,13,32,17,149,34,17,32,17,146,32,17,32,17,148,147,67,0,0,128,191,146,33,20,12,1,11,67,0,0,0,0,33,20,67, + 0,0,128,63,32,17,147,32,13,93,69,13,0,32,13,67,0,0,128,191,146,32,17,149,34,17,32,17,146,32,17,32,17,148,146,67,0,0,128,63,146,33,20,11,32,13,32,13,146,67,0,0,128,191,146,32,20,147,33,13,12,1,11,32,0,32, + 0,42,2,200,2,34,13,32,0,42,2,204,2,34,17,146,34,20,67,0,0,128,191,146,32,20,32,20,67,0,0,128,63,96,27,56,2,200,2,2,64,2,64,32,13,32,17,93,69,13,0,32,13,32,17,149,34,17,32,17,146,32,17,32,17,148,147,67, + 0,0,128,191,146,33,20,12,1,11,67,0,0,0,0,33,20,67,0,0,128,63,32,17,147,32,13,93,69,13,0,32,13,67,0,0,128,191,146,32,17,149,34,17,32,17,146,32,17,32,17,148,146,67,0,0,128,63,146,33,20,11,32,20,32,13,32, + 13,146,67,0,0,128,191,146,147,33,13,11,32,0,65,1,54,2,216,2,11,67,0,0,0,0,33,17,67,0,0,0,0,33,20,2,64,32,0,40,2,252,2,65,127,70,13,0,2,64,2,64,32,0,40,2,248,2,34,12,65,1,72,13,0,32,0,32,12,65,127,106,34, + 12,54,2,248,2,32,0,42,2,236,2,32,0,42,2,244,2,32,12,178,148,147,33,20,12,1,11,32,0,42,2,236,2,33,20,11,32,0,65,1,54,2,252,2,32,13,32,20,148,67,0,0,0,0,146,33,20,11,2,64,32,0,40,2,144,3,65,127,70,13,0,32, + 14,32,18,32,19,146,32,20,146,148,67,0,0,0,0,146,33,13,2,64,2,64,32,0,40,2,140,3,34,12,65,1,72,13,0,32,0,32,12,65,127,106,34,12,54,2,140,3,32,0,42,2,128,3,32,0,42,2,136,3,32,12,178,148,147,33,17,12,1,11, + 32,0,42,2,128,3,33,17,11,32,0,65,1,54,2,144,3,32,13,32,17,148,67,0,0,0,0,146,33,17,11,67,0,0,0,0,33,13,2,64,32,0,40,2,200,1,34,12,65,127,70,13,0,32,16,32,17,148,67,0,0,0,0,146,33,13,2,64,2,64,32,12,65, + 0,76,13,0,32,0,32,0,40,2,196,1,65,127,106,34,12,54,2,196,1,32,12,65,0,78,13,1,11,2,64,32,0,45,0,184,1,69,13,0,32,0,65,0,54,2,180,1,32,8,32,4,32,0,42,2,188,1,187,32,0,42,2,192,1,187,16,163,128,128,128,0, + 32,0,65,0,58,0,184,1,11,32,0,65,31,54,2,196,1,11,32,0,32,0,42,2,164,1,34,14,32,0,42,2,160,1,32,13,32,0,42,2,168,1,32,0,42,2,172,1,34,17,148,147,32,0,42,2,176,1,34,16,147,148,34,13,148,34,18,32,17,32,18, + 146,34,17,146,56,2,172,1,32,0,32,14,32,17,148,34,14,32,16,32,14,146,34,14,146,56,2,176,1,2,64,2,64,2,64,32,0,40,2,180,1,14,2,0,2,1,11,32,14,33,13,12,1,11,32,17,33,13,11,32,0,65,1,54,2,200,1,32,13,67,0, + 0,0,0,146,33,13,11,2,64,32,0,40,2,184,34,34,12,65,127,70,13,0,2,64,2,64,2,64,2,64,2,64,32,12,65,0,74,13,0,32,0,32,6,54,2,168,3,12,1,11,2,64,2,64,32,12,65,1,70,13,0,32,0,40,2,180,34,33,12,12,1,11,32,0,32, + 0,40,2,176,34,65,127,106,34,12,54,2,176,34,32,12,65,127,74,13,2,32,3,32,7,65,128,31,16,129,128,128,128,0,33,15,2,64,32,0,40,2,192,35,34,12,65,31,74,13,0,32,0,32,12,65,136,31,108,106,34,12,65,200,35,106, + 65,0,54,2,0,32,12,65,196,35,106,32,0,40,2,0,54,2,0,32,12,65,204,35,106,32,15,65,128,31,16,129,128,128,128,0,26,32,0,40,2,192,35,33,12,11,32,0,32,12,65,1,106,54,2,192,35,32,0,40,2,168,3,65,160,120,106,33, + 12,11,32,0,32,12,65,127,106,34,12,54,2,180,34,65,2,33,21,32,12,65,127,74,13,3,11,65,0,33,12,32,7,65,0,65,128,31,16,128,128,128,128,0,26,32,0,65,223,7,54,2,176,34,12,1,11,32,0,40,2,172,34,33,12,11,65,1, + 33,21,32,0,32,12,65,1,106,65,224,7,111,34,15,65,224,7,106,32,15,32,15,65,0,72,27,54,2,172,34,32,0,32,12,65,2,116,106,65,172,3,106,32,13,56,2,0,11,32,0,32,21,54,2,184,34,11,32,1,32,0,40,2,0,65,2,116,106, + 32,13,56,2,0,32,0,32,0,40,2,0,65,1,106,34,12,54,2,0,32,12,32,2,71,13,0,11,11,32,0,65,0,54,2,0,32,3,65,128,31,106,36,128,128,128,128,0,11,254,10,5,1,127,2,125,1,127,3,124,1,127,35,128,128,128,128,0,65,32, + 107,34,1,36,128,128,128,128,0,32,0,32,0,42,2,0,34,2,32,0,42,2,4,146,34,3,67,0,0,128,191,146,32,3,32,3,67,0,0,128,63,96,27,56,2,0,2,64,2,64,32,2,67,219,15,201,64,148,34,3,188,34,4,65,255,255,255,255,7,113, + 34,0,65,218,159,164,250,3,74,13,0,32,3,32,3,187,34,5,32,5,162,34,6,32,5,162,34,7,32,6,32,6,162,162,32,6,68,167,70,59,140,135,205,198,62,162,68,116,231,202,226,249,0,42,191,160,162,32,7,32,6,68,178,251, + 110,137,16,17,129,63,162,68,119,172,203,84,85,85,197,191,160,162,32,5,160,160,182,32,0,65,128,128,128,204,3,72,27,33,3,12,1,11,2,64,32,0,65,209,167,237,131,4,75,13,0,32,3,187,33,6,2,64,32,0,65,228,151, + 219,128,4,79,13,0,68,0,0,0,0,0,0,240,63,32,6,68,24,45,68,84,251,33,249,63,160,34,5,32,5,162,34,5,68,129,94,12,253,255,255,223,63,162,161,32,5,32,5,162,34,7,68,66,58,5,225,83,85,165,63,162,160,32,5,32,7, + 162,32,5,68,105,80,238,224,66,147,249,62,162,68,39,30,15,232,135,192,86,191,160,162,160,182,140,68,0,0,0,0,0,0,240,63,32,6,68,24,45,68,84,251,33,249,191,160,34,6,32,6,162,34,6,68,129,94,12,253,255,255, + 223,63,162,161,32,6,32,6,162,34,5,68,66,58,5,225,83,85,165,63,162,160,32,6,32,5,162,32,6,68,105,80,238,224,66,147,249,62,162,68,39,30,15,232,135,192,86,191,160,162,160,182,32,4,65,0,72,27,33,3,12,2,11, + 68,24,45,68,84,251,33,9,64,68,24,45,68,84,251,33,9,192,32,4,65,0,72,27,32,6,160,34,5,32,5,162,34,6,32,5,154,162,34,7,32,6,32,6,162,162,32,6,68,167,70,59,140,135,205,198,62,162,68,116,231,202,226,249,0, + 42,191,160,162,32,7,32,6,68,178,251,110,137,16,17,129,63,162,68,119,172,203,84,85,85,197,191,160,162,32,5,161,160,182,33,3,12,1,11,2,64,2,64,2,64,32,0,65,214,227,136,135,4,73,13,0,32,0,65,255,255,255,251, + 7,77,13,1,32,3,32,3,147,33,3,12,3,11,32,3,187,33,6,32,0,65,224,219,191,133,4,73,13,1,68,24,45,68,84,251,33,25,64,68,24,45,68,84,251,33,25,192,32,4,65,0,72,27,32,6,160,34,5,32,5,32,5,162,34,6,162,34,7,32, + 6,32,6,162,162,32,6,68,167,70,59,140,135,205,198,62,162,68,116,231,202,226,249,0,42,191,160,162,32,5,32,7,32,6,68,178,251,110,137,16,17,129,63,162,68,119,172,203,84,85,85,197,191,160,162,160,160,182,33, + 3,12,2,11,2,64,2,64,32,0,65,218,159,164,238,4,75,13,0,32,3,187,34,6,32,6,68,131,200,201,109,48,95,228,63,162,68,0,0,0,0,0,0,56,67,160,68,0,0,0,0,0,0,56,195,160,34,5,68,0,0,0,80,251,33,249,191,162,160,32, + 5,68,99,98,26,97,180,16,81,190,162,160,33,6,2,64,32,5,153,68,0,0,0,0,0,0,224,65,99,69,13,0,32,5,170,33,0,12,2,11,65,128,128,128,128,120,33,0,12,1,11,32,1,65,8,106,32,0,32,0,65,23,118,65,234,126,106,34, + 8,65,23,116,107,190,187,68,0,0,0,0,0,0,0,0,68,0,0,0,0,0,0,0,0,32,8,65,1,65,0,16,164,128,128,128,0,32,1,43,3,16,33,6,32,1,40,2,8,33,0,32,4,65,127,74,13,0,65,0,32,0,107,33,0,32,6,154,33,6,11,2,64,2,64,2, + 64,2,64,32,0,65,3,113,14,3,0,1,2,3,11,32,6,32,6,32,6,162,34,5,162,34,7,32,5,32,5,162,162,32,5,68,167,70,59,140,135,205,198,62,162,68,116,231,202,226,249,0,42,191,160,162,32,6,32,7,32,5,68,178,251,110,137, + 16,17,129,63,162,68,119,172,203,84,85,85,197,191,160,162,160,160,182,33,3,12,4,11,32,6,32,6,162,34,6,68,129,94,12,253,255,255,223,191,162,68,0,0,0,0,0,0,240,63,160,32,6,32,6,162,34,5,68,66,58,5,225,83, + 85,165,63,162,160,32,6,32,5,162,32,6,68,105,80,238,224,66,147,249,62,162,68,39,30,15,232,135,192,86,191,160,162,160,182,33,3,12,3,11,32,6,32,6,162,34,5,32,6,154,162,34,7,32,5,32,5,162,162,32,5,68,167,70, + 59,140,135,205,198,62,162,68,116,231,202,226,249,0,42,191,160,162,32,7,32,5,68,178,251,110,137,16,17,129,63,162,68,119,172,203,84,85,85,197,191,160,162,32,6,161,160,182,33,3,12,2,11,32,6,32,6,162,34,6, + 68,129,94,12,253,255,255,223,191,162,68,0,0,0,0,0,0,240,63,160,32,6,32,6,162,34,5,68,66,58,5,225,83,85,165,63,162,160,32,6,32,5,162,32,6,68,105,80,238,224,66,147,249,62,162,68,39,30,15,232,135,192,86,191, + 160,162,160,182,140,33,3,12,1,11,68,0,0,0,0,0,0,240,63,32,6,68,210,33,51,127,124,217,18,64,160,34,5,32,5,162,34,5,68,129,94,12,253,255,255,223,63,162,161,32,5,32,5,162,34,7,68,66,58,5,225,83,85,165,63, + 162,160,32,5,32,7,162,32,5,68,105,80,238,224,66,147,249,62,162,68,39,30,15,232,135,192,86,191,160,162,160,182,68,0,0,0,0,0,0,240,63,32,6,68,210,33,51,127,124,217,18,192,160,34,6,32,6,162,34,6,68,129,94, + 12,253,255,255,223,63,162,161,32,6,32,6,162,34,5,68,66,58,5,225,83,85,165,63,162,160,32,6,32,5,162,32,6,68,105,80,238,224,66,147,249,62,162,68,39,30,15,232,135,192,86,191,160,162,160,182,140,32,4,65,0, + 72,27,33,3,11,32,1,65,32,106,36,128,128,128,128,0,32,3,11,162,5,3,4,125,4,127,1,125,32,0,32,0,42,2,0,34,1,32,0,42,2,4,34,2,146,34,3,67,0,0,128,191,146,32,3,32,3,67,0,0,128,63,96,27,56,2,0,2,64,2,64,32, + 1,32,2,93,69,13,0,32,1,32,2,149,34,3,32,3,146,32,3,32,3,148,147,67,0,0,128,191,146,33,4,12,1,11,67,0,0,0,0,33,4,67,0,0,128,63,32,2,147,32,1,93,69,13,0,32,1,67,0,0,128,191,146,32,2,149,34,3,32,3,146,32, + 3,32,3,148,146,67,0,0,128,63,146,33,4,11,2,64,2,64,32,1,67,0,0,0,63,146,34,3,188,34,5,65,23,118,65,255,1,113,34,6,65,255,1,71,13,0,32,3,32,3,149,33,3,12,1,11,2,64,32,5,65,255,255,255,255,7,113,34,0,65, + 128,128,128,252,3,74,13,0,32,3,67,0,0,0,0,148,32,3,32,0,65,128,128,128,252,3,70,27,33,3,12,1,11,2,64,2,64,32,6,13,0,65,0,33,6,2,64,32,5,65,9,116,34,0,65,0,72,13,0,65,0,33,6,3,64,32,6,65,127,106,33,6,32, + 0,65,1,116,34,0,65,127,74,13,0,11,11,32,5,65,1,32,6,107,116,33,0,12,1,11,32,5,65,255,255,255,3,113,65,128,128,128,4,114,33,0,11,2,64,2,64,2,64,32,6,65,128,1,72,13,0,32,6,65,1,106,33,7,3,64,2,64,32,0,65, + 128,128,128,124,106,34,6,65,0,72,13,0,32,6,33,0,32,6,69,13,3,11,32,0,65,1,116,33,0,32,7,65,127,106,34,7,65,128,1,74,13,0,11,65,255,0,33,6,11,2,64,2,64,2,64,2,64,32,0,65,128,128,128,124,106,34,7,65,0,72, + 13,0,32,7,33,0,32,7,69,13,1,11,32,0,65,255,255,255,3,77,13,1,32,0,33,8,12,2,11,32,3,67,0,0,0,0,148,33,3,12,4,11,3,64,32,6,65,127,106,33,6,32,0,65,128,128,128,2,73,33,7,32,0,65,1,116,34,8,33,0,32,7,13,0, + 11,11,32,5,65,128,128,128,128,120,113,33,0,2,64,32,6,65,1,72,13,0,32,8,65,128,128,128,124,106,32,6,65,23,116,114,33,6,12,2,11,32,8,65,1,32,6,107,117,33,6,12,1,11,32,3,67,0,0,0,0,148,33,3,12,1,11,32,6,32, + 0,114,190,33,3,11,2,64,2,64,32,3,32,2,93,69,13,0,32,3,32,2,149,34,2,32,2,146,32,2,32,2,148,147,67,0,0,128,191,146,33,9,12,1,11,67,0,0,0,0,33,9,67,0,0,128,63,32,2,147,32,3,93,69,13,0,32,3,67,0,0,128,191, + 146,32,2,149,34,2,32,2,146,32,2,32,2,148,146,67,0,0,128,63,146,33,9,11,67,0,0,128,191,67,0,0,128,63,32,1,67,0,0,0,63,93,27,32,4,147,32,9,146,11,11,156,130,128,128,0,2,0,65,0,11,8,0,0,0,0,0,0,0,0,0,65,16, + 11,136,2,131,249,162,0,68,78,110,0,252,41,21,0,209,87,39,0,221,52,245,0,98,219,192,0,60,153,149,0,65,144,67,0,99,81,254,0,187,222,171,0,183,97,197,0,58,110,36,0,210,77,66,0,73,6,224,0,9,234,46,0,28,146, + 209,0,235,29,254,0,41,177,28,0,232,62,167,0,245,53,130,0,68,187,46,0,156,233,132,0,180,38,112,0,65,126,95,0,214,145,57,0,83,131,57,0,156,244,57,0,139,95,132,0,40,249,189,0,248,31,59,0,222,255,151,0,15, + 152,5,0,17,47,239,0,10,90,139,0,109,31,109,0,207,126,54,0,9,203,39,0,70,79,183,0,158,102,63,0,45,234,95,0,186,39,117,0,229,235,199,0,61,123,241,0,247,57,7,0,146,82,138,0,251,107,234,0,31,177,95,0,8,93, + 141,0,48,3,86,0,123,252,70,0,240,171,107,0,32,188,207,0,54,244,154,0,227,169,29,0,94,97,145,0,8,27,230,0,133,153,101,0,160,20,95,0,141,64,104,0,128,216,255,0,39,115,77,0,6,6,49,0,202,86,21,0,201,168,115, + 0,123,226,96,0,107,140,192,0,0,240,137,128,128,0,7,108,105,110,107,105,110,103,2,8,174,137,128,128,0,43,0,32,2,17,95,115,101,110,100,69,118,101,110,116,95,109,105,100,105,73,110,1,2,12,46,76,95,102,114, + 101,113,117,101,110,99,121,0,0,8,0,32,3,16,95,115,101,110,100,69,118,101,110,116,95,112,111,119,101,114,0,32,4,21,95,115,101,110,100,69,118,101,110,116,95,109,97,115,116,101,114,71,97,105,110,0,32,5,23, + 95,115,101,110,100,69,118,101,110,116,95,109,97,115,116,101,114,79,99,116,97,118,101,0,2,6,29,46,76,115,116,100,95,95,110,111,116,101,115,95,95,110,111,116,101,84,111,70,114,101,113,117,101,110,99,121, + 0,2,7,32,46,76,115,116,100,95,95,111,115,99,105,108,108,97,116,111,114,115,95,95,115,101,116,70,114,101,113,117,101,110,99,121,0,2,8,67,46,76,115,116,100,95,95,105,110,116,114,105,110,115,105,99,115,95, + 95,105,110,116,101,114,110,97,108,95,95,109,97,116,104,95,105,109,112,108,101,109,101,110,116,97,116,105,111,110,115,95,95,104,101,108,112,101,114,115,95,95,115,99,97,108,98,110,102,0,32,9,22,95,115,101, + 110,100,69,118,101,110,116,95,109,97,115,116,101,114,71,108,105,100,101,0,32,10,24,95,115,101,110,100,69,118,101,110,116,95,118,99,111,49,83,101,109,105,116,111,110,101,115,0,32,11,21,95,115,101,110,100, + 69,118,101,110,116,95,118,99,111,49,68,101,116,117,110,101,0,32,12,20,95,115,101,110,100,69,118,101,110,116,95,118,99,111,49,76,101,118,101,108,0,32,13,20,95,115,101,110,100,69,118,101,110,116,95,118,99, + 111,49,83,104,97,112,101,0,32,14,24,95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,83,101,109,105,116,111,110,101,115,0,32,15,21,95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,68,101,116, + 117,110,101,0,32,16,20,95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,76,101,118,101,108,0,32,17,20,95,115,101,110,100,69,118,101,110,116,95,118,99,111,50,83,104,97,112,101,0,32,18,24,95,115,101, + 110,100,69,118,101,110,116,95,118,99,111,51,83,101,109,105,116,111,110,101,115,0,32,19,21,95,115,101,110,100,69,118,101,110,116,95,118,99,111,51,68,101,116,117,110,101,0,32,20,20,95,115,101,110,100,69, + 118,101,110,116,95,118,99,111,51,76,101,118,101,108,0,32,21,20,95,115,101,110,100,69,118,101,110,116,95,118,99,111,51,83,104,97,112,101,0,32,22,23,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116, + 101,114,67,117,116,111,102,102,0,32,23,26,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,82,101,115,111,110,97,110,99,101,0,32,24,22,95,115,101,110,100,69,118,101,110,116,95,102,105,108, + 116,101,114,69,103,73,110,116,0,32,25,22,95,115,101,110,100,69,118,101,110,116,95,97,109,112,69,103,65,116,116,97,99,107,0,32,26,21,95,115,101,110,100,69,118,101,110,116,95,97,109,112,69,103,68,101,99, + 97,121,0,2,27,56,46,76,115,116,100,95,95,105,110,116,114,105,110,115,105,99,115,95,95,105,110,116,101,114,110,97,108,95,95,109,97,116,104,95,105,109,112,108,101,109,101,110,116,97,116,105,111,110,115,95, + 95,112,111,119,95,48,0,32,28,23,95,115,101,110,100,69,118,101,110,116,95,97,109,112,69,103,83,117,115,116,97,105,110,0,32,29,23,95,115,101,110,100,69,118,101,110,116,95,97,109,112,69,103,82,101,108,101, + 97,115,101,0,32,30,25,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,69,103,65,116,116,97,99,107,0,32,31,24,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,69,103,68, + 101,99,97,121,0,32,32,26,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,69,103,83,117,115,116,97,105,110,0,32,33,26,95,115,101,110,100,69,118,101,110,116,95,102,105,108,116,101,114,69, + 103,82,101,108,101,97,115,101,0,32,34,10,105,110,105,116,105,97,108,105,115,101,2,16,0,0,2,35,38,46,76,115,116,100,95,95,102,105,108,116,101,114,115,95,95,116,112,116,95,95,115,118,102,95,95,115,101,116, + 70,114,101,113,117,101,110,99,121,0,2,36,81,46,76,115,116,100,95,95,105,110,116,114,105,110,115,105,99,115,95,95,105,110,116,101,114,110,97,108,95,95,109,97,116,104,95,105,109,112,108,101,109,101,110,116, + 97,116,105,111,110,115,95,95,104,101,108,112,101,114,115,95,95,114,101,109,97,105,110,100,101,114,80,105,79,118,101,114,50,76,97,114,103,101,0,16,0,1,2,13,46,76,95,95,99,111,110,115,116,97,110,116,95,1, + 0,136,2,0,32,37,12,97,100,118,97,110,99,101,66,108,111,99,107,0,2,38,28,46,76,115,116,100,95,95,111,115,99,105,108,108,97,116,111,114,115,95,95,110,101,120,116,83,105,110,101,0,2,39,30,46,76,115,116,100, + 95,95,111,115,99,105,108,108,97,116,111,114,115,95,95,110,101,120,116,83,113,117,97,114,101,0,16,1,5,173,128,128,128,0,2,17,46,98,115,115,46,46,76,95,102,114,101,113,117,101,110,99,121,3,0,21,46,114,111, + 100,97,116,97,46,46,76,95,95,99,111,110,115,116,97,110,116,95,4,0,0,161,131,128,128,0,10,114,101,108,111,99,46,67,79,68,69,5,95,3,166,4,1,0,3,206,5,1,0,3,238,6,1,0,3,242,7,1,0,0,154,8,5,0,161,8,6,0,218, + 8,5,0,225,8,6,0,154,9,5,0,161,9,6,0,153,14,7,3,241,19,1,0,0,151,20,5,0,158,20,6,3,195,20,1,0,0,233,20,5,0,240,20,6,3,180,21,1,0,3,233,22,1,0,0,143,23,5,0,150,23,6,3,187,23,1,0,0,225,23,5,0,232,23,6,3,172, + 24,1,0,3,225,25,1,0,0,135,26,5,0,142,26,6,3,179,26,1,0,0,217,26,5,0,224,26,6,3,164,27,1,0,3,151,29,1,0,3,199,29,1,0,0,224,29,26,3,227,37,1,0,0,252,37,26,3,154,38,1,0,3,203,38,1,0,0,228,38,26,3,155,39,1, + 0,0,180,39,26,7,201,39,34,7,212,39,34,0,230,41,35,0,208,42,6,0,242,42,6,0,148,43,6,3,181,43,1,0,7,203,43,34,7,225,43,34,7,236,43,34,0,255,58,36,7,128,66,34,7,152,66,34,7,164,66,34,0,185,67,37,0,203,67, + 37,0,221,67,37,4,161,68,38,4,4,170,81,38,0,7,209,90,34,7,233,90,34,7,245,90,34,3,142,91,1,0,0,170,92,5,0,177,92,6,0,218,92,5,0,225,92,6,0,138,93,5,0,145,93,6,0,229,93,5,0,236,93,6,0,149,94,5,0,156,94,6, + 0,197,94,5,0,204,94,6,0,242,101,40,0,135,102,41,0,199,102,41,0,174,106,40,0,195,106,41,0,131,107,41,0,234,110,40,0,255,110,41,0,191,111,41,0,212,116,35,0,207,118,42,0,147,119,42,0,223,119,37,7,236,120, + 34,7,128,121,34,7,139,121,34,0,183,127,36,7,234,131,1,34,0,172,128,128,128,0,15,116,97,114,103,101,116,95,102,101,97,116,117,114,101,115,2,43,15,109,117,116,97,98,108,101,45,103,108,111,98,97,108,115,43, + 8,115,105,103,110,45,101,120,116,]); + } +} diff --git a/assets/example_patches/SubtractOne/cmaj_api/assets/cmajor-logo.svg b/assets/example_patches/SubtractOne/cmaj_api/assets/cmajor-logo.svg new file mode 100644 index 00000000..70685d54 --- /dev/null +++ b/assets/example_patches/SubtractOne/cmaj_api/assets/cmajor-logo.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/assets/example_patches/SubtractOne/cmaj_api/cmaj-audio-worklet-helper.js b/assets/example_patches/SubtractOne/cmaj_api/cmaj-audio-worklet-helper.js new file mode 100644 index 00000000..362eab3f --- /dev/null +++ b/assets/example_patches/SubtractOne/cmaj_api/cmaj-audio-worklet-helper.js @@ -0,0 +1,758 @@ +// +// ,ad888ba, 88 +// d8"' "8b +// d8 88,dba,,adba, ,aPP8A.A8 88 +// Y8, 88 88 88 88 88 88 +// Y8a. .a8P 88 88 88 88, ,88 88 (C)2024 Cmajor Software Ltd +// '"Y888Y"' 88 88 88 '"8bbP"Y8 88 https://cmajor.dev +// ,88 +// 888P" +// +// This file may be used under the terms of the ISC license: +// +// Permission to use, copy, modify, and/or distribute this software for any purpose with or +// without fee is hereby granted, provided that the above copyright notice and this permission +// notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import { PatchConnection } from "./cmaj-patch-connection.js" + +//============================================================================== +// N.B. code will be serialised to a string, so all `registerWorkletProcessor`s +// dependencies must be self contained and not capture things in the outer scope +async function serialiseWorkletProcessorFactoryToDataURI (CmajorClass, workletName, hostDescription) +{ + const serialisedInvocation = `(${registerWorkletProcessor.toString()}) ("${workletName}", ${CmajorClass.toString()}, "${hostDescription}");` + + let reader = new FileReader(); + reader.readAsDataURL (new Blob ([serialisedInvocation], { type: "text/javascript" })); + + return await new Promise (res => { reader.onloadend = () => res (reader.result); }); +} + +function registerWorkletProcessor (workletName, CmajorClass, hostDescription) +{ + function makeConsumeOutputEvents ({ wrapper, eventOutputs, dispatchOutputEvent }) + { + const outputEventHandlers = eventOutputs.map (({ endpointID }) => + { + const readCount = wrapper[`getOutputEventCount_${endpointID}`]?.bind (wrapper); + const reset = wrapper[`resetOutputEventCount_${endpointID}`]?.bind (wrapper); + const readEventAtIndex = wrapper[`getOutputEvent_${endpointID}`]?.bind (wrapper); + + return () => + { + const count = readCount(); + + for (let i = 0; i < count; ++i) + dispatchOutputEvent (endpointID, readEventAtIndex (i)); + + reset(); + }; + }); + + return () => outputEventHandlers.forEach ((consume) => consume() ); + } + + function setInitialParameterValues (parametersMap) + { + for (const { initialise } of Object.values (parametersMap)) + initialise(); + } + + function makeEndpointMap (wrapper, endpoints, initialValueOverrides) + { + const toKey = ({ endpointType, endpointID }) => + { + switch (endpointType) + { + case "event": return `sendInputEvent_${endpointID}`; + case "value": return `setInputValue_${endpointID}`; + } + + throw "Unhandled endpoint type"; + }; + + const lookup = {}; + + for (const { endpointID, endpointType, annotation, purpose } of endpoints) + { + const key = toKey ({ endpointType, endpointID }); + const wrapperUpdate = wrapper[key]?.bind (wrapper); + + const snapAndConstrainValue = (value) => + { + if (annotation.step != null) + value = Math.round (value / annotation.step) * annotation.step; + + if (annotation.min != null && annotation.max != null) + value = Math.min (Math.max (value, annotation.min), annotation.max); + + return value; + }; + + const update = (value, rampFrames) => + { + // N.B. value clamping and rampFrames from annotations not currently applied + const entry = lookup[endpointID]; + entry.cachedValue = value; + wrapperUpdate (value, rampFrames); + }; + + if (update) + { + const initialValue = initialValueOverrides[endpointID] ?? annotation?.init; + + lookup[endpointID] = { + snapAndConstrainValue, + update, + initialise: initialValue != null ? () => update (initialValue) : () => {}, + purpose, + cachedValue: undefined, + }; + } + } + + return lookup; + } + + function makeStreamEndpointHandler ({ wrapper, toEndpoints, wrapperMethodNamePrefix }) + { + const endpoints = toEndpoints (wrapper); + if (endpoints.length === 0) + return () => {}; + + let handlers = []; + let targetChannels = []; + let channelCount = 0; + + for (const endpoint of endpoints) + { + const handleFrames = wrapper[`${wrapperMethodNamePrefix}_${endpoint.endpointID}`]?.bind (wrapper); + + if (! handleFrames) + return () => {}; + + handlers.push (handleFrames); + targetChannels.push (channelCount); + channelCount += endpoint.numAudioChannels; + } + + return (channels, blockSize) => + { + for (let i = 0; i < handlers.length; i++) + handlers[i] (channels, blockSize, targetChannels[i]); + } + } + + function makeInputStreamEndpointHandler (wrapper) + { + return makeStreamEndpointHandler ({ + wrapper, + toEndpoints: wrapper => wrapper.getInputEndpoints().filter (({ purpose }) => purpose === "audio in"), + wrapperMethodNamePrefix: "setInputStreamFrames", + }); + } + + function makeOutputStreamEndpointHandler (wrapper) + { + return makeStreamEndpointHandler ({ + wrapper, + toEndpoints: wrapper => wrapper.getOutputEndpoints().filter (({ purpose }) => purpose === "audio out"), + wrapperMethodNamePrefix: "getOutputFrames", + }); + } + + class WorkletProcessor extends AudioWorkletProcessor + { + static get parameterDescriptors() + { + return []; + } + + constructor ({ processorOptions, ...options }) + { + super (options); + + this.processImpl = undefined; + this.consumeOutputEvents = undefined; + + const { sessionID = Date.now() & 0x7fffffff, initialValueOverrides = {} } = processorOptions; + + const wrapper = new CmajorClass(); + + wrapper.initialise (sessionID, sampleRate) + .then (() => this.initialisePatch (wrapper, initialValueOverrides)) + .catch (error => { throw new Error (error)}); + } + + process (inputs, outputs) + { + const input = inputs[0]; + const output = outputs[0]; + + this.processImpl?.(input, output); + this.consumeOutputEvents?.(); + + return true; + } + + sendPatchMessage (payload) + { + this.port.postMessage ({ type: "patch", payload }); + } + + sendParameterValueChanged (endpointID, value) + { + this.sendPatchMessage ({ + type: "param_value", + message: { endpointID, value } + }); + } + + initialisePatch (wrapper, initialValueOverrides) + { + try + { + const inputParameters = wrapper.getInputEndpoints().filter (({ purpose }) => purpose === "parameter"); + const parametersMap = makeEndpointMap (wrapper, inputParameters, initialValueOverrides); + + setInitialParameterValues (parametersMap); + + const toParameterValuesWithKey = (endpointKey, parametersMap) => + { + const toValue = ([endpoint, { cachedValue }]) => ({ [endpointKey]: endpoint, value: cachedValue }); + return Object.entries (parametersMap).map (toValue); + }; + + const initialValues = toParameterValuesWithKey ("endpointID", parametersMap); + const initialState = wrapper.getState(); + + const resetState = () => + { + wrapper.restoreState (initialState); + + // N.B. update cache used for `req_param_value` messages (we don't currently read from the wasm heap) + setInitialParameterValues (parametersMap); + }; + + const isNonAudioOrParameterEndpoint = ({ purpose }) => ! ["audio in", "parameter"].includes (purpose); + const otherInputs = wrapper.getInputEndpoints().filter (isNonAudioOrParameterEndpoint); + const otherInputEndpointsMap = makeEndpointMap (wrapper, otherInputs, initialValueOverrides); + + const isEvent = ({ endpointType }) => endpointType === "event"; + const eventInputs = wrapper.getInputEndpoints().filter (isEvent); + const eventOutputs = wrapper.getOutputEndpoints().filter (isEvent); + + const makeEndpointListenerMap = (eventEndpoints) => + { + const listeners = {}; + + for (const { endpointID } of eventEndpoints) + listeners[endpointID] = []; + + return listeners; + }; + + const inputEventListeners = makeEndpointListenerMap (eventInputs); + const outputEventListeners = makeEndpointListenerMap (eventOutputs); + + this.consumeOutputEvents = makeConsumeOutputEvents ({ + eventOutputs, + wrapper, + dispatchOutputEvent: (endpointID, event) => + { + for (const { replyType } of outputEventListeners[endpointID] ?? []) + { + this.sendPatchMessage ({ + type: replyType, + message: event.event, // N.B. chucking away frame and typeIndex info for now + }); + } + }, + }); + + const blockSize = 128; + const prepareInputFrames = makeInputStreamEndpointHandler (wrapper); + const processOutputFrames = makeOutputStreamEndpointHandler (wrapper); + + this.processImpl = (input, output) => + { + prepareInputFrames (input, blockSize); + wrapper.advance (blockSize); + processOutputFrames (output, blockSize); + }; + + // N.B. the message port makes things straightforward, but it allocates (when sending + receiving). + // so, we aren't doing ourselves any favours. we probably ought to marshal raw bytes over to the gui in + // a pre-allocated lock-free message queue (using `SharedArrayBuffer` + `Atomic`s) and transform the raw + // messages there. + this.port.addEventListener ("message", e => + { + if (e.data.type !== "patch") + return; + + const msg = e.data.payload; + + switch (msg.type) + { + case "req_status": + { + this.sendPatchMessage ({ + type: "status", + message: { + details: { + inputs: wrapper.getInputEndpoints(), + outputs: wrapper.getOutputEndpoints(), + }, + sampleRate, + host: hostDescription ? hostDescription : "WebAudio" + }, + }); + break; + } + + case "req_reset": + { + resetState(); + initialValues.forEach (v => this.sendParameterValueChanged (v.endpointID, v.value)); + break; + } + + case "req_param_value": + { + // N.B. keep a local cache here so that we can send the values back when requested. + // we could instead have accessors into the wasm heap. + const endpointID = msg.id; + const parameter = parametersMap[endpointID]; + if (! parameter) + return; + + const value = parameter.cachedValue; + this.sendParameterValueChanged (endpointID, value); + break; + } + + case "send_value": + { + const endpointID = msg.id; + const parameter = parametersMap[endpointID]; + + if (parameter) + { + const newValue = parameter.snapAndConstrainValue (msg.value); + parameter.update (newValue, msg.rampFrames); + + this.sendParameterValueChanged (endpointID, newValue); + return; + } + + const inputEndpoint = otherInputEndpointsMap[endpointID]; + + if (inputEndpoint) + { + inputEndpoint.update (msg.value); + + for (const { replyType } of inputEventListeners[endpointID] ?? []) + { + this.sendPatchMessage ({ + type: replyType, + message: inputEndpoint.cachedValue, + }); + } + } + break; + } + + case "send_gesture_start": break; + case "send_gesture_end": break; + + case "req_full_state": + this.sendPatchMessage ({ + type: msg?.replyType, + message: { + parameters: toParameterValuesWithKey ("name", parametersMap), + }, + }); + break; + + case "send_full_state": + { + const { parameters = [] } = e.data.payload?.value || []; + + for (const [endpointID, parameter] of Object.entries (parametersMap)) + { + const namedNextValue = parameters.find (({ name }) => name === endpointID); + + if (namedNextValue) + parameter.update (namedNextValue.value); + else + parameter.initialise(); + + this.sendParameterValueChanged (endpointID, parameter.cachedValue); + } + break; + } + + case "add_endpoint_listener": + { + const insertIfValidEndpoint = (lookup, msg) => + { + const endpointID = msg?.endpoint; + const listeners = lookup[endpointID] + + if (! listeners) + return false; + + return listeners.push ({ replyType: msg?.replyType }) > 0; + }; + + if (! insertIfValidEndpoint (inputEventListeners, msg)) + insertIfValidEndpoint (outputEventListeners, msg) + + break; + } + + case "remove_endpoint_listener": + { + const removeIfValidReplyType = (lookup, msg) => + { + const endpointID = msg?.endpoint; + const listeners = lookup[endpointID]; + + if (! listeners) + return false; + + const index = listeners.indexOf (msg?.replyType); + + if (index === -1) + return false; + + return listeners.splice (index, 1).length === 1; + }; + + if (! removeIfValidReplyType (inputEventListeners, msg)) + removeIfValidReplyType (outputEventListeners, msg) + + break; + } + + default: + break; + } + }); + + this.port.postMessage ({ type: "initialised" }); + this.port.start(); + } + catch (e) + { + this.port.postMessage (e.toString()); + } + } + } + + registerProcessor (workletName, WorkletProcessor); +} + +//============================================================================== +async function connectToAudioIn (audioContext, node) +{ + try + { + const input = await navigator.mediaDevices.getUserMedia ({ + audio: { + echoCancellation: false, + noiseSuppression: false, + autoGainControl: false, + }}); + + if (! input) + throw new Error(); + + const source = audioContext.createMediaStreamSource (input); + + if (! source) + throw new Error(); + + source.connect (node); + } + catch (e) + { + console.warn (`Could not open audio input`); + } +} + +async function connectToMIDI (connection, midiEndpointID) +{ + try + { + if (! navigator.requestMIDIAccess) + throw new Error ("Web MIDI API not supported."); + + const midiAccess = await navigator.requestMIDIAccess ({ sysex: true, software: true }); + + for (const input of midiAccess.inputs.values()) + { + input.onmidimessage = ({ data }) => + connection.sendMIDIInputEvent (midiEndpointID, data[2] | (data[1] << 8) | (data[0] << 16)); + } + } + catch (e) + { + console.warn (`Could not open MIDI devices: ${e}`); + } +} + + +//============================================================================== +/** This class provides a PatchConnection that controls a Cmajor audio worklet + * node. + */ +export class AudioWorkletPatchConnection extends PatchConnection +{ + constructor (manifest) + { + super(); + + this.manifest = manifest; + this.cachedState = {}; + } + + //============================================================================== + /** Initialises this connection to load and control the given Cmajor class. + * + * @param {Object} parameters - the parameters to use + * @param {Object} parameters.CmajorClass - the generated Cmajor class + * @param {AudioContext} parameters.audioContext - a web audio AudioContext object + * @param {string} parameters.workletName - the name to give the new worklet that is created + * @param {string} parameters.hostDescription - a description of the host that is using the patch + * @param {number} [parameters.sessionID] - an integer to use for the session ID, or undefined to use a default + * @param {Object} [parameters.initialValueOverrides] - optional initial values for parameter endpoints + * @param {string} [parameters.rootResourcePath] - optionally, a root to use when resolving resource paths + */ + async initialise ({ CmajorClass, + audioContext, + workletName, + hostDescription, + sessionID, + initialValueOverrides, + rootResourcePath }) + { + this.audioContext = audioContext; + + if (rootResourcePath) + { + this.rootResourcePath = rootResourcePath.toString(); + + if (! this.rootResourcePath.endsWith ("/")) + this.rootResourcePath += "/"; + } + else + { + this.rootResourcePath = window.location.href; + + if (! this.rootResourcePath.endsWith ("/")) + this.rootResourcePath += "/../"; + } + + const dataURI = await serialiseWorkletProcessorFactoryToDataURI (CmajorClass, workletName, hostDescription); + await audioContext.audioWorklet.addModule (dataURI); + + this.inputEndpoints = CmajorClass.prototype.getInputEndpoints(); + this.outputEndpoints = CmajorClass.prototype.getOutputEndpoints(); + + const audioInputEndpoints = this.inputEndpoints.filter (({ purpose }) => purpose === "audio in"); + const audioOutputEndpoints = this.outputEndpoints.filter (({ purpose }) => purpose === "audio out"); + + let inputChannelCount = 0; + let outputChannelCount = 0; + + audioInputEndpoints.forEach ((endpoint) => { inputChannelCount = inputChannelCount + endpoint.numAudioChannels; }); + audioOutputEndpoints.forEach ((endpoint) => { outputChannelCount = outputChannelCount + endpoint.numAudioChannels; }); + + const hasInput = inputChannelCount > 0; + const hasOutput = outputChannelCount > 0; + + const node = new AudioWorkletNode (audioContext, workletName, { + numberOfInputs: +hasInput, + numberOfOutputs: +hasOutput, + channelCountMode: "explicit", + channelCount: hasInput ? inputChannelCount : undefined, + outputChannelCount: hasOutput ? [outputChannelCount] : [], + + processorOptions: + { + sessionID, + initialValueOverrides + } + }); + + const waitUntilWorkletInitialised = async () => + { + return new Promise ((resolve) => + { + const filterForInitialised = (e) => + { + if (e.data.type === "initialised") + { + node.port.removeEventListener ("message", filterForInitialised); + resolve(); + } + }; + + node.port.addEventListener ("message", filterForInitialised); + }); + }; + + node.port.start(); + + await waitUntilWorkletInitialised(); + + this.audioNode = node; + + node.port.addEventListener ("message", e => + { + if (e.data.type === "patch") + { + const msg = e.data.payload; + + if (msg?.type === "status") + msg.message = { manifest: this.manifest, ...msg.message }; + + this.deliverMessageFromServer (msg) + } + }); + + await this.startPatchWorker(); + } + + //============================================================================== + /** Attempts to connect this connection to the default audio and MIDI channels. + * This must only be called once initialise() has completed successfully. + * + * @param {AudioContext} audioContext - a web audio AudioContext object + */ + async connectDefaultAudioAndMIDI (audioContext) + { + if (! this.audioNode) + throw new Error ("AudioWorkletPatchConnection.initialise() must have been successfully completed before calling connectDefaultAudioAndMIDI()"); + + const getInputWithPurpose = (purpose) => + { + for (const i of this.inputEndpoints) + if (i.purpose === purpose) + return i.endpointID; + } + + const midiEndpointID = getInputWithPurpose ("midi in"); + + if (midiEndpointID) + connectToMIDI (this, midiEndpointID); + + if (getInputWithPurpose ("audio in")) + connectToAudioIn (audioContext, this.audioNode); + + this.audioNode.connect (audioContext.destination); + } + + //============================================================================== + sendMessageToServer (msg) + { + this.audioNode.port.postMessage ({ type: "patch", payload: msg }); + } + + requestStoredStateValue (key) + { + this.dispatchEvent ("state_key_value", { key, value: this.cachedState[key] }); + } + + sendStoredStateValue (key, newValue) + { + const changed = this.cachedState[key] != newValue; + + if (changed) + { + const shouldRemove = newValue == null; + if (shouldRemove) + { + delete this.cachedState[key]; + return; + } + + this.cachedState[key] = newValue; + // N.B. notifying the client only when updating matches behaviour of the patch player + this.dispatchEvent ("state_key_value", { key, value: newValue }); + } + } + + sendFullStoredState (fullState) + { + const currentStateCleared = (() => + { + const out = {}; + Object.keys (this.cachedState).forEach (k => out[k] = undefined); + return out; + })(); + + const incomingStateValues = fullState.values ?? {}; + const nextStateValues = { ...currentStateCleared, ...incomingStateValues }; + + Object.entries (nextStateValues).forEach (([key, value]) => this.sendStoredStateValue (key, value)); + + // N.B. worklet will handle the `parameters` part + super.sendFullStoredState (fullState); + } + + requestFullStoredState (callback) + { + // N.B. the worklet only handles the `parameters` part, so we patch the key-value state in here + super.requestFullStoredState (msg => callback ({ values: { ...this.cachedState }, ...msg })); + } + + getResourceAddress (path) + { + return this.rootResourcePath + path; + } + + async readResource (path) + { + return fetch (path); + } + + async readResourceAsAudioData (path) + { + const response = await this.readResource (path); + const buffer = await this.audioContext.decodeAudioData (await response.arrayBuffer()); + + let frames = []; + + for (let i = 0; i < buffer.length; ++i) + frames.push ([]); + + for (let chan = 0; chan < buffer.numberOfChannels; ++chan) + { + const src = buffer.getChannelData (chan); + + for (let i = 0; i < buffer.length; ++i) + frames[i].push (src[i]); + } + + return { frames, sampleRate: buffer.sampleRate }; + } + + //============================================================================== + /** @private */ + async startPatchWorker() + { + if (this.manifest.worker?.length > 0) + { + const module = await import (this.getResourceAddress (this.manifest.worker)); + module.default (this); + } + } +} diff --git a/assets/example_patches/SubtractOne/cmaj_api/cmaj-event-listener-list.js b/assets/example_patches/SubtractOne/cmaj_api/cmaj-event-listener-list.js new file mode 100644 index 00000000..0c13ea9e --- /dev/null +++ b/assets/example_patches/SubtractOne/cmaj_api/cmaj-event-listener-list.js @@ -0,0 +1,112 @@ +// +// ,ad888ba, 88 +// d8"' "8b +// d8 88,dba,,adba, ,aPP8A.A8 88 +// Y8, 88 88 88 88 88 88 +// Y8a. .a8P 88 88 88 88, ,88 88 (C)2024 Cmajor Software Ltd +// '"Y888Y"' 88 88 88 '"8bbP"Y8 88 https://cmajor.dev +// ,88 +// 888P" +// +// This file may be used under the terms of the ISC license: +// +// Permission to use, copy, modify, and/or distribute this software for any purpose with or +// without fee is hereby granted, provided that the above copyright notice and this permission +// notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +/** This event listener management class allows listeners to be attached and + * removed from named event types. + */ +export class EventListenerList +{ + constructor() + { + this.listenersPerType = {}; + } + + /** Adds a listener for a specifc event type. + * If the listener is already registered, this will simply add it again. + * Each call to addEventListener() must be paired with a removeventListener() + * call to remove it. + * + * @param {string} type + */ + addEventListener (type, listener) + { + if (type && listener) + { + const list = this.listenersPerType[type]; + + if (list) + list.push (listener); + else + this.listenersPerType[type] = [listener]; + } + } + + /** Removes a listener that was previously added for the given event type. + * @param {string} type + */ + removeEventListener (type, listener) + { + if (type && listener) + { + const list = this.listenersPerType[type]; + + if (list) + { + const i = list.indexOf (listener); + + if (i >= 0) + list.splice (i, 1); + } + } + } + + /** Attaches a callback function that will be automatically unregistered + * the first time it is invoked. + * + * @param {string} type + */ + addSingleUseListener (type, listener) + { + const l = message => + { + this.removeEventListener (type, l); + listener?.(message); + }; + + this.addEventListener (type, l); + } + + /** Synchronously dispatches an event object to all listeners + * that are registered for the given type. + * + * @param {string} type + */ + dispatchEvent (type, event) + { + const list = this.listenersPerType[type]; + + if (list) + for (const listener of list) + listener?.(event); + } + + /** Returns the number of listeners that are currently registered + * for the given type of event. + * + * @param {string} type + */ + getNumListenersForType (type) + { + const list = this.listenersPerType[type]; + return list ? list.length : 0; + } +} diff --git a/assets/example_patches/SubtractOne/cmaj_api/cmaj-generic-patch-view.js b/assets/example_patches/SubtractOne/cmaj_api/cmaj-generic-patch-view.js new file mode 100644 index 00000000..e30389b2 --- /dev/null +++ b/assets/example_patches/SubtractOne/cmaj_api/cmaj-generic-patch-view.js @@ -0,0 +1,189 @@ +// +// ,ad888ba, 88 +// d8"' "8b +// d8 88,dba,,adba, ,aPP8A.A8 88 +// Y8, 88 88 88 88 88 88 +// Y8a. .a8P 88 88 88 88, ,88 88 (C)2024 Cmajor Software Ltd +// '"Y888Y"' 88 88 88 '"8bbP"Y8 88 https://cmajor.dev +// ,88 +// 888P" +// +// This file may be used under the terms of the ISC license: +// +// Permission to use, copy, modify, and/or distribute this software for any purpose with or +// without fee is hereby granted, provided that the above copyright notice and this permission +// notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import * as Controls from "./cmaj-parameter-controls.js" + +//============================================================================== +/** A simple, generic view which can control any type of patch */ +class GenericPatchView extends HTMLElement +{ + /** Creates a view for a patch. + * @param {PatchConnection} patchConnection - the connection to the target patch + */ + constructor (patchConnection) + { + super(); + + this.patchConnection = patchConnection; + + this.statusListener = status => + { + this.status = status; + this.createControlElements(); + }; + + this.attachShadow ({ mode: "open" }); + this.shadowRoot.innerHTML = this.getHTML(); + + this.titleElement = this.shadowRoot.getElementById ("patch-title"); + this.parametersElement = this.shadowRoot.getElementById ("patch-parameters"); + } + + /** This is picked up by some of our wrapper code to know whether it makes + * sense to put a title bar/logo above the GUI. + */ + hasOwnTitleBar() + { + return true; + } + + //============================================================================== + /** @private */ + connectedCallback() + { + this.patchConnection.addStatusListener (this.statusListener); + this.patchConnection.requestStatusUpdate(); + } + + /** @private */ + disconnectedCallback() + { + this.patchConnection.removeStatusListener (this.statusListener); + } + + /** @private */ + createControlElements() + { + this.parametersElement.innerHTML = ""; + this.titleElement.innerText = this.status?.manifest?.name ?? "Cmajor"; + + if (this.status?.details?.inputs) + { + for (const endpointInfo of this.status.details.inputs) + { + if (! endpointInfo.annotation?.hidden) + { + const control = Controls.createLabelledControl (this.patchConnection, endpointInfo); + + if (control) + this.parametersElement.appendChild (control); + } + } + } + } + + /** @private */ + getHTML() + { + return ` + + +
+
+ +

+
+
+
+
`; + } +} + +window.customElements.define ("cmaj-generic-patch-view", GenericPatchView); + +//============================================================================== +/** Creates a generic view element which can be used to control any patch. + * @param {PatchConnection} patchConnection - the connection to the target patch + */ +export default function createPatchView (patchConnection) +{ + return new GenericPatchView (patchConnection); +} diff --git a/assets/example_patches/SubtractOne/cmaj_api/cmaj-midi-helpers.js b/assets/example_patches/SubtractOne/cmaj_api/cmaj-midi-helpers.js new file mode 100644 index 00000000..1cc4933b --- /dev/null +++ b/assets/example_patches/SubtractOne/cmaj_api/cmaj-midi-helpers.js @@ -0,0 +1,181 @@ +// +// ,ad888ba, 88 +// d8"' "8b +// d8 88,dba,,adba, ,aPP8A.A8 88 +// Y8, 88 88 88 88 88 88 +// Y8a. .a8P 88 88 88 88, ,88 88 (C)2024 Cmajor Software Ltd +// '"Y888Y"' 88 88 88 '"8bbP"Y8 88 https://cmajor.dev +// ,88 +// 888P" +// +// This file may be used under the terms of the ISC license: +// +// Permission to use, copy, modify, and/or distribute this software for any purpose with or +// without fee is hereby granted, provided that the above copyright notice and this permission +// notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +export function getByte0 (message) { return (message >> 16) & 0xff; } +export function getByte1 (message) { return (message >> 8) & 0xff; } +export function getByte2 (message) { return message & 0xff; } + +function isVoiceMessage (message, type) { return ((message >> 16) & 0xf0) == type; } +function get14BitValue (message) { return getByte1 (message) | (getByte2 (message) << 7); } + +export function getChannel0to15 (message) { return getByte0 (message) & 0x0f; } +export function getChannel1to16 (message) { return getChannel0to15 (message) + 1; } + +export function getMessageSize (message) +{ + const mainGroupLengths = (3 << 0) | (3 << 2) | (3 << 4) | (3 << 6) + | (2 << 8) | (2 << 10) | (3 << 12); + + const lastGroupLengths = (1 << 0) | (2 << 2) | (3 << 4) | (2 << 6) + | (1 << 8) | (1 << 10) | (1 << 12) | (1 << 14) + | (1 << 16) | (1 << 18) | (1 << 20) | (1 << 22) + | (1 << 24) | (1 << 26) | (1 << 28) | (1 << 30); + + const firstByte = getByte0 (message); + const group = (firstByte >> 4) & 7; + + return (group != 7 ? (mainGroupLengths >> (2 * group)) + : (lastGroupLengths >> (2 * (firstByte & 15)))) & 3; +} + +export function isNoteOn (message) { return isVoiceMessage (message, 0x90) && getVelocity (message) != 0; } +export function isNoteOff (message) { return isVoiceMessage (message, 0x80) || (isVoiceMessage (message, 0x90) && getVelocity (message) == 0); } + +export function getNoteNumber (message) { return getByte1 (message); } +export function getVelocity (message) { return getByte2 (message); } + +export function isProgramChange (message) { return isVoiceMessage (message, 0xc0); } +export function getProgramChangeNumber (message) { return getByte1 (message); } +export function isPitchWheel (message) { return isVoiceMessage (message, 0xe0); } +export function getPitchWheelValue (message) { return get14BitValue (message); } +export function isAftertouch (message) { return isVoiceMessage (message, 0xa0); } +export function getAfterTouchValue (message) { return getByte2 (message); } +export function isChannelPressure (message) { return isVoiceMessage (message, 0xd0); } +export function getChannelPressureValue (message) { return getByte1 (message); } +export function isController (message) { return isVoiceMessage (message, 0xb0); } +export function getControllerNumber (message) { return getByte1 (message); } +export function getControllerValue (message) { return getByte2 (message); } +export function isControllerNumber (message, number) { return getByte1 (message) == number && isController (message); } +export function isAllNotesOff (message) { return isControllerNumber (message, 123); } +export function isAllSoundOff (message) { return isControllerNumber (message, 120); } +export function isQuarterFrame (message) { return getByte0 (message) == 0xf1; } +export function isClock (message) { return getByte0 (message) == 0xf8; } +export function isStart (message) { return getByte0 (message) == 0xfa; } +export function isContinue (message) { return getByte0 (message) == 0xfb; } +export function isStop (message) { return getByte0 (message) == 0xfc; } +export function isActiveSense (message) { return getByte0 (message) == 0xfe; } +export function isMetaEvent (message) { return getByte0 (message) == 0xff; } +export function isSongPositionPointer (message) { return getByte0 (message) == 0xf2; } +export function getSongPositionPointerValue (message) { return get14BitValue (message); } + +export function getChromaticScaleIndex (note) { return (note % 12) & 0xf; } +export function getOctaveNumber (note, octaveForMiddleC) { return ((Math.floor (note / 12) + (octaveForMiddleC ? octaveForMiddleC : 3)) & 0xff) - 5; } +export function getNoteName (note) { const names = ["C", "C#", "D", "Eb", "E", "F", "F#", "G", "G#", "A", "Bb", "B"]; return names[getChromaticScaleIndex (note)]; } +export function getNoteNameWithSharps (note) { const names = ["C", "C#", "D", "Eb", "E", "F", "F#", "G", "G#", "A", "Bb", "B"]; return names[getChromaticScaleIndex (note)]; } +export function getNoteNameWithFlats (note) { const names = ["C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"]; return names[getChromaticScaleIndex (note)]; } +export function getNoteNameWithOctaveNumber (note) { return getNoteName (note) + getOctaveNumber (note); } +export function isNatural (note) { const nats = [true, false, true, false, true, true, false, true, false, true, false, true]; return nats[getChromaticScaleIndex (note)]; } +export function isAccidental (note) { return ! isNatural (note); } + +export function printHexMIDIData (message) +{ + const numBytes = getMessageSize (message); + + if (numBytes == 0) + return "[empty]"; + + let s = ""; + + for (let i = 0; i < numBytes; ++i) + { + if (i != 0) s += ' '; + + const byte = message >> (16 - 8 * i) & 0xff; + s += "0123456789abcdef"[byte >> 4]; + s += "0123456789abcdef"[byte & 15]; + } + + return s; +} + +export function getMIDIDescription (message) +{ + const channelText = " Channel " + getChannel1to16 (message); + function getNote (m) { const s = getNoteNameWithOctaveNumber (getNoteNumber (message)); return s.length < 4 ? s + " " : s; }; + + if (isNoteOn (message)) return "Note-On: " + getNote (message) + channelText + " Velocity " + getVelocity (message); + if (isNoteOff (message)) return "Note-Off: " + getNote (message) + channelText + " Velocity " + getVelocity (message); + if (isAftertouch (message)) return "Aftertouch: " + getNote (message) + channelText + ": " + getAfterTouchValue (message); + if (isPitchWheel (message)) return "Pitch wheel: " + getPitchWheelValue (message) + ' ' + channelText; + if (isChannelPressure (message)) return "Channel pressure: " + getChannelPressureValue (message) + ' ' + channelText; + if (isController (message)) return "Controller:" + channelText + ": " + getControllerName (getControllerNumber (message)) + " = " + getControllerValue (message); + if (isProgramChange (message)) return "Program change: " + getProgramChangeNumber (message) + ' ' + channelText; + if (isAllNotesOff (message)) return "All notes off:" + channelText; + if (isAllSoundOff (message)) return "All sound off:" + channelText; + if (isQuarterFrame (message)) return "Quarter-frame"; + if (isClock (message)) return "Clock"; + if (isStart (message)) return "Start"; + if (isContinue (message)) return "Continue"; + if (isStop (message)) return "Stop"; + if (isMetaEvent (message)) return "Meta-event: type " + getByte1 (message); + if (isSongPositionPointer (message)) return "Song Position: " + getSongPositionPointerValue (message); + + return printHexMIDIData (message); +} + +export function getControllerName (controllerNumber) +{ + if (controllerNumber < 128) + { + const controllerNames = [ + "Bank Select", "Modulation Wheel (coarse)", "Breath controller (coarse)", undefined, + "Foot Pedal (coarse)", "Portamento Time (coarse)", "Data Entry (coarse)", "Volume (coarse)", + "Balance (coarse)", undefined, "Pan position (coarse)", "Expression (coarse)", + "Effect Control 1 (coarse)", "Effect Control 2 (coarse)", undefined, undefined, + "General Purpose Slider 1", "General Purpose Slider 2", "General Purpose Slider 3", "General Purpose Slider 4", + undefined, undefined, undefined, undefined, + undefined, undefined, undefined, undefined, + undefined, undefined, undefined, undefined, + "Bank Select (fine)", "Modulation Wheel (fine)", "Breath controller (fine)", undefined, + "Foot Pedal (fine)", "Portamento Time (fine)", "Data Entry (fine)", "Volume (fine)", + "Balance (fine)", undefined, "Pan position (fine)", "Expression (fine)", + "Effect Control 1 (fine)", "Effect Control 2 (fine)", undefined, undefined, + undefined, undefined, undefined, undefined, + undefined, undefined, undefined, undefined, + undefined, undefined, undefined, undefined, + undefined, undefined, undefined, undefined, + "Hold Pedal", "Portamento", "Sustenuto Pedal", "Soft Pedal", + "Legato Pedal", "Hold 2 Pedal", "Sound Variation", "Sound Timbre", + "Sound Release Time", "Sound Attack Time", "Sound Brightness", "Sound Control 6", + "Sound Control 7", "Sound Control 8", "Sound Control 9", "Sound Control 10", + "General Purpose Button 1", "General Purpose Button 2", "General Purpose Button 3", "General Purpose Button 4", + undefined, undefined, undefined, undefined, + undefined, undefined, undefined, "Reverb Level", + "Tremolo Level", "Chorus Level", "Celeste Level", "Phaser Level", + "Data Button increment", "Data Button decrement", "Non-registered Parameter (fine)", "Non-registered Parameter (coarse)", + "Registered Parameter (fine)", "Registered Parameter (coarse)", undefined, undefined, + undefined, undefined, undefined, undefined, + undefined, undefined, undefined, undefined, + undefined, undefined, undefined, undefined, + undefined, undefined, undefined, undefined, + "All Sound Off", "All Controllers Off", "Local Keyboard", "All Notes Off", + "Omni Mode Off", "Omni Mode On", "Mono Operation", "Poly Operation" + ]; + + const name = controllerNames[controllerNumber]; + + if (name) + return name; + } + + return controllerNumber.toString(); +} diff --git a/assets/example_patches/SubtractOne/cmaj_api/cmaj-parameter-controls.js b/assets/example_patches/SubtractOne/cmaj_api/cmaj-parameter-controls.js new file mode 100644 index 00000000..f0f28e47 --- /dev/null +++ b/assets/example_patches/SubtractOne/cmaj_api/cmaj-parameter-controls.js @@ -0,0 +1,875 @@ +// +// ,ad888ba, 88 +// d8"' "8b +// d8 88,dba,,adba, ,aPP8A.A8 88 +// Y8, 88 88 88 88 88 88 +// Y8a. .a8P 88 88 88 88, ,88 88 (C)2024 Cmajor Software Ltd +// '"Y888Y"' 88 88 88 '"8bbP"Y8 88 https://cmajor.dev +// ,88 +// 888P" +// +// This file may be used under the terms of the ISC license: +// +// Permission to use, copy, modify, and/or distribute this software for any purpose with or +// without fee is hereby granted, provided that the above copyright notice and this permission +// notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import { PatchConnection } from "./cmaj-patch-connection.js"; + + +//============================================================================== +/** A base class for parameter controls, which automatically connects to a + * PatchConnection to monitor a parameter and provides methods to modify it. + */ +export class ParameterControlBase extends HTMLElement +{ + constructor() + { + super(); + + // prevent any clicks from focusing on this element + this.onmousedown = e => e.stopPropagation(); + } + + /** Attaches the control to a given PatchConnection and endpoint. + * + * @param {PatchConnection} patchConnection - the connection to connect to, or pass + * undefined to disconnect the control. + * @param {Object} endpointInfo - the endpoint details, as provided by a PatchConnection + * in its status callback. + */ + setEndpoint (patchConnection, endpointInfo) + { + this.detachListener(); + + this.patchConnection = patchConnection; + this.endpointInfo = endpointInfo; + this.defaultValue = endpointInfo.annotation?.init || endpointInfo.defaultValue || 0; + + if (this.isConnected) + this.attachListener(); + } + + /** Override this method in a child class, and it will be called when the parameter value changes, + * so you can update the GUI appropriately. + */ + valueChanged (newValue) {} + + /** Your GUI can call this when it wants to change the parameter value. */ + setValue (value) { this.patchConnection?.sendEventOrValue (this.endpointInfo.endpointID, value); } + + /** Call this before your GUI begins a modification gesture. + * You might for example call this if the user begins a mouse-drag operation. + */ + beginGesture() { this.patchConnection?.sendParameterGestureStart (this.endpointInfo.endpointID); } + + /** Call this after your GUI finishes a modification gesture */ + endGesture() { this.patchConnection?.sendParameterGestureEnd (this.endpointInfo.endpointID); } + + /** This calls setValue(), but sandwiches it between some start/end gesture calls. + * You should use this to make sure a DAW correctly records automatiion for individual value changes + * that are not part of a gesture. + */ + setValueAsGesture (value) + { + this.beginGesture(); + this.setValue (value); + this.endGesture(); + } + + /** Resets the parameter to its default value */ + resetToDefault() + { + if (this.defaultValue !== null) + this.setValueAsGesture (this.defaultValue); + } + + //============================================================================== + /** @private */ + connectedCallback() + { + this.attachListener(); + } + + /** @protected */ + disconnectedCallback() + { + this.detachListener(); + } + + /** @private */ + detachListener() + { + if (this.listener) + { + this.patchConnection?.removeParameterListener?.(this.listener.endpointID, this.listener); + this.listener = undefined; + } + } + + /** @private */ + attachListener() + { + if (this.patchConnection && this.endpointInfo) + { + this.detachListener(); + + this.listener = newValue => this.valueChanged (newValue); + this.listener.endpointID = this.endpointInfo.endpointID; + + this.patchConnection.addParameterListener (this.endpointInfo.endpointID, this.listener); + this.patchConnection.requestParameterValue (this.endpointInfo.endpointID); + } + } +} + +//============================================================================== +/** A simple rotary parameter knob control. */ +export class Knob extends ParameterControlBase +{ + constructor (patchConnection, endpointInfo) + { + super(); + this.setEndpoint (patchConnection, endpointInfo); + } + + setEndpoint (patchConnection, endpointInfo) + { + super.setEndpoint (patchConnection, endpointInfo); + + this.innerHTML = ""; + this.className = "knob-container"; + const min = endpointInfo?.annotation?.min || 0; + const max = endpointInfo?.annotation?.max || 1; + const mid = endpointInfo?.annotation?.mid || undefined; + + const createSvgElement = tag => window.document.createElementNS ("http://www.w3.org/2000/svg", tag); + + const svg = createSvgElement ("svg"); + svg.setAttribute ("viewBox", "0 0 100 100"); + + const trackBackground = createSvgElement ("path"); + trackBackground.setAttribute ("d", "M20,76 A 40 40 0 1 1 80 76"); + trackBackground.classList.add ("knob-path"); + trackBackground.classList.add ("knob-track-background"); + + const maxKnobRotation = 132; + const isBipolar = min + max === 0; + const dashLength = isBipolar ? 251.5 : 184; + const valueOffset = isBipolar ? 0 : 132; + this.getDashOffset = val => dashLength - 184 / (maxKnobRotation * 2) * (val + valueOffset); + + this.trackValue = createSvgElement ("path"); + + this.trackValue.setAttribute ("d", isBipolar ? "M50.01,10 A 40 40 0 1 1 50 10" + : "M20,76 A 40 40 0 1 1 80 76"); + this.trackValue.setAttribute ("stroke-dasharray", dashLength); + this.trackValue.classList.add ("knob-path"); + this.trackValue.classList.add ("knob-track-value"); + + this.dial = document.createElement ("div"); + this.dial.className = "knob-dial"; + + const dialTick = document.createElement ("div"); + dialTick.className = "knob-dial-tick"; + this.dial.appendChild (dialTick); + + svg.appendChild (trackBackground); + svg.appendChild (this.trackValue); + + this.appendChild (svg); + this.appendChild (this.dial); + + const remap = (source, sourceFrom, sourceTo, targetFrom, targetTo) => + (targetFrom + (source - sourceFrom) * (targetTo - targetFrom) / (sourceTo - sourceFrom)); + + const toValue = (knobRotation) => + { + if (mid > min && mid < max) + { + const normalisedKnob = remap (knobRotation, -maxKnobRotation, maxKnobRotation, 0, 1); + const range = max - min; + const power = Math.log ((mid - min) / (range)) / Math.log (0.5); + + return min + range * Math.pow (normalisedKnob, power); + } + else + { + return remap (knobRotation, -maxKnobRotation, maxKnobRotation, min, max); + } + }; + + this.toRotation = (value) => + { + if (mid > min && mid < max) + { + const range = max - min; + const power = Math.log ((mid - min) / (range)) / Math.log (0.5); + + const normalisedKnob = Math.pow ((value - min) / range, 1 / power); + + return remap (normalisedKnob, 0, 1, -maxKnobRotation, maxKnobRotation); + } + else + { + return remap (value, min, max, -maxKnobRotation, maxKnobRotation); + } + }; + + this.rotation = this.toRotation (this.defaultValue); + this.setRotation (this.rotation, true); + + const onMouseMove = (event) => + { + event.preventDefault(); // avoid scrolling whilst dragging + + const nextRotation = (rotation, delta) => + { + const clamp = (v, min, max) => Math.min (Math.max (v, min), max); + return clamp (rotation - delta, -maxKnobRotation, maxKnobRotation); + }; + + const workaroundBrowserIncorrectlyCalculatingMovementY = event.movementY === event.screenY; + const movementY = workaroundBrowserIncorrectlyCalculatingMovementY ? event.screenY - this.previousScreenY + : event.movementY; + this.previousScreenY = event.screenY; + + const speedMultiplier = event.shiftKey ? 0.25 : 1.5; + this.accumulatedRotation = nextRotation (this.accumulatedRotation, movementY * speedMultiplier); + this.setValue (toValue (this.accumulatedRotation)); + }; + + const onMouseUp = (event) => + { + this.previousScreenY = undefined; + this.accumulatedRotation = undefined; + window.removeEventListener ("mousemove", onMouseMove); + window.removeEventListener ("mouseup", onMouseUp); + this.endGesture(); + }; + + const onMouseDown = (event) => + { + this.previousScreenY = event.screenY; + this.accumulatedRotation = this.rotation; + this.beginGesture(); + window.addEventListener ("mousemove", onMouseMove); + window.addEventListener ("mouseup", onMouseUp); + event.preventDefault(); + }; + + const onTouchStart = (event) => + { + this.previousClientY = event.changedTouches[0].clientY; + this.accumulatedRotation = this.rotation; + this.touchIdentifier = event.changedTouches[0].identifier; + this.beginGesture(); + window.addEventListener ("touchmove", onTouchMove); + window.addEventListener ("touchend", onTouchEnd); + event.preventDefault(); + }; + + const onTouchMove = (event) => + { + for (const touch of event.changedTouches) + { + if (touch.identifier == this.touchIdentifier) + { + const nextRotation = (rotation, delta) => + { + const clamp = (v, min, max) => Math.min (Math.max (v, min), max); + return clamp (rotation - delta, -maxKnobRotation, maxKnobRotation); + }; + + const movementY = touch.clientY - this.previousClientY; + this.previousClientY = touch.clientY; + + const speedMultiplier = event.shiftKey ? 0.25 : 1.5; + this.accumulatedRotation = nextRotation (this.accumulatedRotation, movementY * speedMultiplier); + this.setValue (toValue (this.accumulatedRotation)); + } + } + }; + + const onTouchEnd = (event) => + { + this.previousClientY = undefined; + this.accumulatedRotation = undefined; + window.removeEventListener ("touchmove", onTouchMove); + window.removeEventListener ("touchend", onTouchEnd); + this.endGesture(); + }; + + this.addEventListener ("mousedown", onMouseDown); + this.addEventListener ("dblclick", () => this.resetToDefault()); + this.addEventListener ('touchstart', onTouchStart); + } + + /** Returns true if this type of control is suitable for the given endpoint info */ + static canBeUsedFor (endpointInfo) + { + return endpointInfo.purpose === "parameter"; + } + + /** @override */ + valueChanged (newValue) { this.setRotation (this.toRotation (newValue), false); } + + /** Returns a string version of the given value */ + getDisplayValue (v) { return toFloatDisplayValueWithUnit (v, this.endpointInfo); } + + /** @private */ + setRotation (degrees, force) + { + if (force || this.rotation !== degrees) + { + this.rotation = degrees; + this.trackValue.setAttribute ("stroke-dashoffset", this.getDashOffset (this.rotation)); + this.dial.style.transform = `translate(-50%,-50%) rotate(${degrees}deg)`; + } + } + + /** @private */ + static getCSS() + { + return ` + .knob-container { + --knob-track-background-color: var(--background); + --knob-track-value-color: var(--foreground); + + --knob-dial-border-color: var(--foreground); + --knob-dial-background-color: var(--background); + --knob-dial-tick-color: var(--foreground); + + position: relative; + display: inline-block; + height: 5rem; + width: 5rem; + margin: 0; + padding: 0; + } + + .knob-path { + fill: none; + stroke-linecap: round; + stroke-width: 0.15rem; + } + + .knob-track-background { + stroke: var(--knob-track-background-color); + } + + .knob-track-value { + stroke: var(--knob-track-value-color); + } + + .knob-dial { + position: absolute; + text-align: center; + height: 60%; + width: 60%; + top: 50%; + left: 50%; + border: 0.15rem solid var(--knob-dial-border-color); + border-radius: 100%; + box-sizing: border-box; + transform: translate(-50%,-50%); + background-color: var(--knob-dial-background-color); + } + + .knob-dial-tick { + position: absolute; + display: inline-block; + + height: 1rem; + width: 0.15rem; + background-color: var(--knob-dial-tick-color); + }`; + } +} + +//============================================================================== +/** A boolean switch control */ +export class Switch extends ParameterControlBase +{ + constructor (patchConnection, endpointInfo) + { + super(); + this.setEndpoint (patchConnection, endpointInfo); + } + + setEndpoint (patchConnection, endpointInfo) + { + super.setEndpoint (patchConnection, endpointInfo); + + const outer = document.createElement ("div"); + outer.classList = "switch-outline"; + + const inner = document.createElement ("div"); + inner.classList = "switch-thumb"; + + this.innerHTML = ""; + this.currentValue = this.defaultValue > 0.5; + this.valueChanged (this.currentValue); + this.classList.add ("switch-container"); + + outer.appendChild (inner); + this.appendChild (outer); + this.addEventListener ("click", () => this.setValueAsGesture (this.currentValue ? 0 : 1.0)); + } + + /** Returns true if this type of control is suitable for the given endpoint info */ + static canBeUsedFor (endpointInfo) + { + return endpointInfo.purpose === "parameter" + && endpointInfo.annotation?.boolean; + } + + /** @override */ + valueChanged (newValue) + { + const b = newValue > 0.5; + this.currentValue = b; + this.classList.remove (! b ? "switch-on" : "switch-off"); + this.classList.add (b ? "switch-on" : "switch-off"); + } + + /** Returns a string version of the given value */ + getDisplayValue (v) { return `${v > 0.5 ? "On" : "Off"}`; } + + /** @private */ + static getCSS() + { + return ` + .switch-container { + --switch-outline-color: var(--foreground); + --switch-thumb-color: var(--foreground); + --switch-on-background-color: var(--background); + --switch-off-background-color: var(--background); + + position: relative; + display: flex; + align-items: center; + justify-content: center; + height: 100%; + width: 100%; + margin: 0; + padding: 0; + } + + .switch-outline { + position: relative; + display: inline-block; + height: 1.25rem; + width: 2.5rem; + border-radius: 10rem; + box-shadow: 0 0 0 0.15rem var(--switch-outline-color); + transition: background-color 0.1s cubic-bezier(0.5, 0, 0.2, 1); + } + + .switch-thumb { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%,-50%); + height: 1rem; + width: 1rem; + background-color: var(--switch-thumb-color); + border-radius: 100%; + transition: left 0.1s cubic-bezier(0.5, 0, 0.2, 1); + } + + .switch-off .switch-thumb { + left: 25%; + background: none; + border: var(--switch-thumb-color) solid 0.1rem; + height: 0.8rem; + width: 0.8rem; + } + .switch-on .switch-thumb { + left: 75%; + } + + .switch-off .switch-outline { + background-color: var(--switch-on-background-color); + } + .switch-on .switch-outline { + background-color: var(--switch-off-background-color); + }`; + } +} + +//============================================================================== +function toFloatDisplayValueWithUnit (v, endpointInfo) +{ + return `${v.toFixed (2)} ${endpointInfo.annotation?.unit ?? ""}`; +} + +//============================================================================== +/** A control that allows an item to be selected from a drop-down list of options */ +export class Options extends ParameterControlBase +{ + constructor (patchConnection, endpointInfo) + { + super(); + this.setEndpoint (patchConnection, endpointInfo); + } + + setEndpoint (patchConnection, endpointInfo) + { + super.setEndpoint (patchConnection, endpointInfo); + + const toValue = (min, step, index) => min + (step * index); + const toStepCount = count => count > 0 ? count - 1 : 1; + + const { min, max, options } = (() => + { + if (Options.hasTextOptions (endpointInfo)) + { + const optionList = endpointInfo.annotation.text.split ("|"); + const stepCount = toStepCount (optionList.length); + let min = 0, max = stepCount, step = 1; + + if (endpointInfo.annotation.min != null && endpointInfo.annotation.max != null) + { + min = endpointInfo.annotation.min; + max = endpointInfo.annotation.max; + step = (max - min) / stepCount; + } + + const options = optionList.map ((text, index) => ({ value: toValue (min, step, index), text })); + + return { min, max, options }; + } + + if (Options.isExplicitlyDiscrete (endpointInfo)) + { + const step = endpointInfo.annotation.step; + + const min = endpointInfo.annotation?.min || 0; + const max = endpointInfo.annotation?.max || 1; + + const numDiscreteOptions = (((max - min) / step) | 0) + 1; + + const options = new Array (numDiscreteOptions); + for (let i = 0; i < numDiscreteOptions; ++i) + { + const value = toValue (min, step, i); + options[i] = { value, text: toFloatDisplayValueWithUnit (value, endpointInfo) }; + } + + return { min, max, options }; + } + })(); + + this.options = options; + + const stepCount = toStepCount (this.options.length); + const normalise = value => (value - min) / (max - min); + this.toIndex = value => Math.min (stepCount, normalise (value) * this.options.length) | 0; + + this.innerHTML = ""; + + this.select = document.createElement ("select"); + + for (const option of this.options) + { + const optionElement = document.createElement ("option"); + optionElement.innerText = option.text; + this.select.appendChild (optionElement); + } + + this.selectedIndex = this.toIndex (this.defaultValue); + + this.select.addEventListener ("change", (e) => + { + const newIndex = e.target.selectedIndex; + + // prevent local state change. the caller will update us when the backend actually applies the update + e.target.selectedIndex = this.selectedIndex; + + this.setValueAsGesture (this.options[newIndex].value) + }); + + this.valueChanged (this.selectedIndex); + + this.className = "select-container"; + this.appendChild (this.select); + + const icon = document.createElement ("span"); + icon.className = "select-icon"; + this.appendChild (icon); + } + + /** Returns true if this type of control is suitable for the given endpoint info */ + static canBeUsedFor (endpointInfo) + { + return endpointInfo.purpose === "parameter" + && (this.hasTextOptions (endpointInfo) || this.isExplicitlyDiscrete (endpointInfo)); + } + + /** @override */ + valueChanged (newValue) + { + const index = this.toIndex (newValue); + this.selectedIndex = index; + this.select.selectedIndex = index; + } + + /** Returns a string version of the given value */ + getDisplayValue (v) { return this.options[this.toIndex(v)].text; } + + /** @private */ + static hasTextOptions (endpointInfo) + { + return endpointInfo.annotation?.text?.split?.("|").length > 1 + } + + /** @private */ + static isExplicitlyDiscrete (endpointInfo) + { + return endpointInfo.annotation?.discrete && endpointInfo.annotation?.step > 0; + } + + /** @private */ + static getCSS() + { + return ` + .select-container { + position: relative; + display: block; + font-size: 0.8rem; + width: 100%; + color: var(--foreground); + border: 0.15rem solid var(--foreground); + border-radius: 0.6rem; + margin: 0; + padding: 0; + } + + select { + background: none; + appearance: none; + -webkit-appearance: none; + font-family: inherit; + font-size: 0.8rem; + + overflow: hidden; + text-overflow: ellipsis; + + padding: 0 1.5rem 0 0.6rem; + + outline: none; + color: var(--foreground); + height: 2rem; + box-sizing: border-box; + margin: 0; + border: none; + + width: 100%; + } + + select option { + background: var(--background); + color: var(--foreground); + } + + .select-icon { + position: absolute; + right: 0.3rem; + top: 0.5rem; + pointer-events: none; + background-color: var(--foreground); + width: 1.4em; + height: 1.4em; + mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17,9.17a1,1,0,0,0-1.41,0L12,12.71,8.46,9.17a1,1,0,0,0-1.41,0,1,1,0,0,0,0,1.42l4.24,4.24a1,1,0,0,0,1.42,0L17,10.59A1,1,0,0,0,17,9.17Z'/%3E%3C/svg%3E"); + mask-repeat: no-repeat; + -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17,9.17a1,1,0,0,0-1.41,0L12,12.71,8.46,9.17a1,1,0,0,0-1.41,0,1,1,0,0,0,0,1.42l4.24,4.24a1,1,0,0,0,1.42,0L17,10.59A1,1,0,0,0,17,9.17Z'/%3E%3C/svg%3E"); + -webkit-mask-repeat: no-repeat; + }`; + } +} + +//============================================================================== +/** A control which wraps a child control, adding a label and value display box below it */ +export class LabelledControlHolder extends ParameterControlBase +{ + constructor (patchConnection, endpointInfo, childControl) + { + super(); + this.childControl = childControl; + this.setEndpoint (patchConnection, endpointInfo); + } + + setEndpoint (patchConnection, endpointInfo) + { + super.setEndpoint (patchConnection, endpointInfo); + + this.innerHTML = ""; + this.className = "labelled-control"; + + const centeredControl = document.createElement ("div"); + centeredControl.className = "labelled-control-centered-control"; + + centeredControl.appendChild (this.childControl); + + const titleValueHoverContainer = document.createElement ("div"); + titleValueHoverContainer.className = "labelled-control-label-container"; + + const nameText = document.createElement ("div"); + nameText.classList.add ("labelled-control-name"); + nameText.innerText = endpointInfo.annotation?.name || endpointInfo.name || endpointInfo.endpointID || ""; + + this.valueText = document.createElement ("div"); + this.valueText.classList.add ("labelled-control-value"); + + titleValueHoverContainer.appendChild (nameText); + titleValueHoverContainer.appendChild (this.valueText); + + this.appendChild (centeredControl); + this.appendChild (titleValueHoverContainer); + } + + /** @override */ + valueChanged (newValue) + { + this.valueText.innerText = this.childControl?.getDisplayValue (newValue); + } + + /** @private */ + static getCSS() + { + return ` + .labelled-control { + --labelled-control-font-color: var(--foreground); + --labelled-control-font-size: 0.8rem; + + position: relative; + display: inline-block; + margin: 0 0.4rem 0.4rem; + vertical-align: top; + text-align: left; + padding: 0; + } + + .labelled-control-centered-control { + position: relative; + display: flex; + align-items: center; + justify-content: center; + + width: 5.5rem; + height: 5rem; + } + + .labelled-control-label-container { + position: relative; + display: block; + max-width: 5.5rem; + margin: -0.4rem auto 0.4rem; + text-align: center; + font-size: var(--labelled-control-font-size); + color: var(--labelled-control-font-color); + cursor: default; + } + + .labelled-control-name { + overflow: hidden; + text-overflow: ellipsis; + } + + .labelled-control-value { + position: absolute; + top: 0; + left: 0; + right: 0; + overflow: hidden; + text-overflow: ellipsis; + opacity: 0; + } + + .labelled-control:hover .labelled-control-name, + .labelled-control:active .labelled-control-name { + opacity: 0; + } + .labelled-control:hover .labelled-control-value, + .labelled-control:active .labelled-control-value { + opacity: 1; + }`; + } +} + +window.customElements.define ("cmaj-knob-control", Knob); +window.customElements.define ("cmaj-switch-control", Switch); +window.customElements.define ("cmaj-options-control", Options); +window.customElements.define ("cmaj-labelled-control-holder", LabelledControlHolder); + +//============================================================================== +/** Fetches all the CSS for the controls defined in this module */ +export function getAllCSS() +{ + return ` + ${Options.getCSS()} + ${Knob.getCSS()} + ${Switch.getCSS()} + ${LabelledControlHolder.getCSS()}`; +} + +//============================================================================== +/** Creates a suitable control for the given endpoint. + * + * @param {PatchConnection} patchConnection - the connection to connect to + * @param {Object} endpointInfo - the endpoint details, as provided by a PatchConnection + * in its status callback. +*/ +export function createControl (patchConnection, endpointInfo) +{ + if (Switch.canBeUsedFor (endpointInfo)) + return new Switch (patchConnection, endpointInfo); + + if (Options.canBeUsedFor (endpointInfo)) + return new Options (patchConnection, endpointInfo); + + if (Knob.canBeUsedFor (endpointInfo)) + return new Knob (patchConnection, endpointInfo); + + return undefined; +} + +//============================================================================== +/** Creates a suitable labelled control for the given endpoint. + * + * @param {PatchConnection} patchConnection - the connection to connect to + * @param {Object} endpointInfo - the endpoint details, as provided by a PatchConnection + * in its status callback. +*/ +export function createLabelledControl (patchConnection, endpointInfo) +{ + const control = createControl (patchConnection, endpointInfo); + + if (control) + return new LabelledControlHolder (patchConnection, endpointInfo, control); + + return undefined; +} + +//============================================================================== +/** Takes a patch connection and its current status object, and tries to create + * a control for the given endpoint ID. + * + * @param {PatchConnection} patchConnection - the connection to connect to + * @param {Object} status - the connection's current status + * @param {string} endpointID - the endpoint you'd like to control + */ +export function createLabelledControlForEndpointID (patchConnection, status, endpointID) +{ + for (const endpointInfo of status?.details?.inputs) + if (endpointInfo.endpointID == endpointID) + return createLabelledControl (patchConnection, endpointInfo); + + return undefined; +} diff --git a/assets/example_patches/SubtractOne/cmaj_api/cmaj-patch-connection.js b/assets/example_patches/SubtractOne/cmaj_api/cmaj-patch-connection.js new file mode 100644 index 00000000..ca423ec8 --- /dev/null +++ b/assets/example_patches/SubtractOne/cmaj_api/cmaj-patch-connection.js @@ -0,0 +1,242 @@ +// +// ,ad888ba, 88 +// d8"' "8b +// d8 88,dba,,adba, ,aPP8A.A8 88 +// Y8, 88 88 88 88 88 88 +// Y8a. .a8P 88 88 88 88, ,88 88 (C)2024 Cmajor Software Ltd +// '"Y888Y"' 88 88 88 '"8bbP"Y8 88 https://cmajor.dev +// ,88 +// 888P" +// +// This file may be used under the terms of the ISC license: +// +// Permission to use, copy, modify, and/or distribute this software for any purpose with or +// without fee is hereby granted, provided that the above copyright notice and this permission +// notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import { EventListenerList } from "./cmaj-event-listener-list.js" +import * as midi from "./cmaj-midi-helpers.js" +import PianoKeyboard from "./cmaj-piano-keyboard.js" +import GenericPatchView from "./cmaj-generic-patch-view.js" +import * as ParameterControls from "./cmaj-parameter-controls.js" + +//============================================================================== +/** This class implements the API and much of the logic for communicating with + * an instance of a patch that is running. + */ +export class PatchConnection extends EventListenerList +{ + constructor() + { + super(); + } + + /** Returns the current Cmajor version */ + getCmajorVersion() + { + const version = import ("./cmaj-version.js"); + return version.getCmajorVersion(); + } + + //============================================================================== + // Status-handling methods: + + /** Calling this will trigger an asynchronous callback to any status listeners with the + * patch's current state. Use addStatusListener() to attach a listener to receive it. + */ + requestStatusUpdate() { this.sendMessageToServer ({ type: "req_status" }); } + + /** Attaches a listener function that will be called whenever the patch's status changes. + * The function will be called with a parameter object containing many properties describing the status, + * including whether the patch is loaded, any errors, endpoint descriptions, its manifest, etc. + */ + addStatusListener (listener) { this.addEventListener ("status", listener); } + + /** Removes a listener that was previously added with addStatusListener() + */ + removeStatusListener (listener) { this.removeEventListener ("status", listener); } + + /** Causes the patch to be reset to its "just loaded" state. */ + resetToInitialState() { this.sendMessageToServer ({ type: "req_reset" }); } + + //============================================================================== + // Methods for sending data to input endpoints: + + /** Sends a value to one of the patch's input endpoints. + * + * This can be used to send a value to either an 'event' or 'value' type input endpoint. + * If the endpoint is a 'value' type, then the rampFrames parameter can optionally be used to specify + * the number of frames over which the current value should ramp to the new target one. + * The value parameter will be coerced to the type that is expected by the endpoint. So for + * examples, numbers will be converted to float or integer types, javascript objects and arrays + * will be converted into more complex types in as good a fashion is possible. + */ + sendEventOrValue (endpointID, value, rampFrames, timeoutMillisecs) { this.sendMessageToServer ({ type: "send_value", id: endpointID, value, rampFrames, timeout: timeoutMillisecs }); } + + /** Sends a short MIDI message value to a MIDI endpoint. + * The value must be a number encoded with `(byte0 << 16) | (byte1 << 8) | byte2`. + */ + sendMIDIInputEvent (endpointID, shortMIDICode) { this.sendEventOrValue (endpointID, { message: shortMIDICode }); } + + /** Tells the patch that a series of changes that constitute a gesture is about to take place + * for the given endpoint. Remember to call sendParameterGestureEnd() after they're done! + */ + sendParameterGestureStart (endpointID) { this.sendMessageToServer ({ type: "send_gesture_start", id: endpointID }); } + + /** Tells the patch that a gesture started by sendParameterGestureStart() has finished. + */ + sendParameterGestureEnd (endpointID) { this.sendMessageToServer ({ type: "send_gesture_end", id: endpointID }); } + + //============================================================================== + // Stored state control methods: + + /** Requests a callback to any stored-state value listeners with the current value of a given key-value pair. + * To attach a listener to receive these events, use addStoredStateValueListener(). + * @param {string} key + */ + requestStoredStateValue (key) { this.sendMessageToServer ({ type: "req_state_value", key: key }); } + + /** Modifies a key-value pair in the patch's stored state. + * @param {string} key + * @param {Object} newValue + */ + sendStoredStateValue (key, newValue) { this.sendMessageToServer ({ type: "send_state_value", key: key, value: newValue }); } + + /** Attaches a listener function that will be called when any key-value pair in the stored state is changed. + * The listener function will receive a message parameter with properties 'key' and 'value'. + */ + addStoredStateValueListener (listener) { this.addEventListener ("state_key_value", listener); } + + /** Removes a listener that was previously added with addStoredStateValueListener(). + */ + removeStoredStateValueListener (listener) { this.removeEventListener ("state_key_value", listener); } + + /** Applies a complete stored state to the patch. + * To get the current complete state, use requestFullStoredState(). + */ + sendFullStoredState (fullState) { this.sendMessageToServer ({ type: "send_full_state", value: fullState }); } + + /** Asynchronously requests the full stored state of the patch. + * The listener function that is supplied will be called asynchronously with the state as its argument. + */ + requestFullStoredState (callback) + { + const replyType = "fullstate_response_" + (Math.floor (Math.random() * 100000000)).toString(); + this.addSingleUseListener (replyType, callback); + this.sendMessageToServer ({ type: "req_full_state", replyType: replyType }); + } + + //============================================================================== + // Listener methods: + + /** Attaches a listener function that will receive updates with the events or audio data + * that is being sent or received by an endpoint. + * + * If the endpoint is an event or value, the callback will be given an argument which is + * the new value. + * + * If the endpoint has the right shape to be treated as "audio" then the callback will receive + * a stream of updates of the min/max range of chunks of data that is flowing through it. + * There will be one callback per chunk of data, and the size of chunks is specified by + * the optional granularity parameter. + * + * @param {string} endpointID + * @param {number} granularity - if defined, this specifies the number of frames per callback + * @param {boolean} sendFullAudioData - if false, the listener will receive an argument object containing + * two properties 'min' and 'max', which are each an array of values, one element per audio + * channel. This allows you to find the highest and lowest samples in that chunk for each channel. + * If sendFullAudioData is true, the listener's argument will have a property 'data' which is an + * array containing one array per channel of raw audio samples data. + */ + addEndpointListener (endpointID, listener, granularity, sendFullAudioData) + { + listener.eventID = "event_" + endpointID + "_" + (Math.floor (Math.random() * 100000000)).toString(); + this.addEventListener (listener.eventID, listener); + this.sendMessageToServer ({ type: "add_endpoint_listener", endpoint: endpointID, replyType: + listener.eventID, granularity: granularity, fullAudioData: sendFullAudioData }); + } + + /** Removes a listener that was previously added with addEndpointListener() + * @param {string} endpointID + */ + removeEndpointListener (endpointID, listener) + { + this.removeEventListener (listener.eventID, listener); + this.sendMessageToServer ({ type: "remove_endpoint_listener", endpoint: endpointID, replyType: listener.eventID }); + } + + /** This will trigger an asynchronous callback to any parameter listeners that are + * attached, providing them with its up-to-date current value for the given endpoint. + * Use addAllParameterListener() to attach a listener to receive the result. + * @param {string} endpointID + */ + requestParameterValue (endpointID) { this.sendMessageToServer ({ type: "req_param_value", id: endpointID }); } + + /** Attaches a listener function which will be called whenever the value of a specific parameter changes. + * The listener function will be called with an argument which is the new value. + * @param {string} endpointID + */ + addParameterListener (endpointID, listener) { this.addEventListener ("param_value_" + endpointID.toString(), listener); } + + /** Removes a listener that was previously added with addParameterListener() + * @param {string} endpointID + */ + removeParameterListener (endpointID, listener) { this.removeEventListener ("param_value_" + endpointID.toString(), listener); } + + /** Attaches a listener function which will be called whenever the value of any parameter changes in the patch. + * The listener function will be called with an argument object with the fields 'endpointID' and 'value'. + */ + addAllParameterListener (listener) { this.addEventListener ("param_value", listener); } + + /** Removes a listener that was previously added with addAllParameterListener() + */ + removeAllParameterListener (listener) { this.removeEventListener ("param_value", listener); } + + /** This takes a relative path to an asset within the patch bundle, and converts it to a + * path relative to the root of the browser that is showing the view. + * + * You need you use this in your view code to translate your asset URLs to a form that + * can be safely used in your view's HTML DOM (e.g. in its CSS). This is needed because the + * host's HTTP server (which is delivering your view pages) may have a different '/' root + * than the root of your patch (e.g. if a single server is serving multiple patch GUIs). + * + * @param {string} path + */ + getResourceAddress (path) { return path; } + + //============================================================================== + /** + * This property contains various utility classes and functions from the Cmajor API, + * for use in your GUI or worker code. + */ + utilities = { + /** MIDI utility functions from cmaj-midi-helpers.js */ + midi, + /** On-screen keyboard class from cmaj-piano-keyboard.js */ + PianoKeyboard, + /** Basic parameter control GUI elements, from cmaj-parameter-controls.js */ + ParameterControls, + /** The default view GUI, from cmaj-generic-patch-view.js */ + GenericPatchView + }; + + //============================================================================== + // Private methods follow this point.. + + /** @private */ + deliverMessageFromServer (msg) + { + if (msg.type === "status") + this.manifest = msg.message?.manifest; + + if (msg.type == "param_value") + this.dispatchEvent ("param_value_" + msg.message.endpointID, msg.message.value); + + this.dispatchEvent (msg.type, msg.message); + } +} diff --git a/assets/example_patches/SubtractOne/cmaj_api/cmaj-patch-view.js b/assets/example_patches/SubtractOne/cmaj_api/cmaj-patch-view.js new file mode 100644 index 00000000..0619ba62 --- /dev/null +++ b/assets/example_patches/SubtractOne/cmaj_api/cmaj-patch-view.js @@ -0,0 +1,179 @@ +// +// ,ad888ba, 88 +// d8"' "8b +// d8 88,dba,,adba, ,aPP8A.A8 88 +// Y8, 88 88 88 88 88 88 +// Y8a. .a8P 88 88 88 88, ,88 88 (C)2024 Cmajor Software Ltd +// '"Y888Y"' 88 88 88 '"8bbP"Y8 88 https://cmajor.dev +// ,88 +// 888P" +// +// This file may be used under the terms of the ISC license: +// +// Permission to use, copy, modify, and/or distribute this software for any purpose with or +// without fee is hereby granted, provided that the above copyright notice and this permission +// notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import { PatchConnection } from "./cmaj-patch-connection.js" + +//============================================================================== +/** Returns a list of types of view that can be created for this patch. + */ +export function getAvailableViewTypes (patchConnection) +{ + if (! patchConnection) + return []; + + if (patchConnection.manifest?.view?.src) + return ["custom", "generic"]; + + return ["generic"]; +} + +//============================================================================== +/** Creates and returns a HTMLElement view which can be shown to control this patch. + * + * If no preferredType argument is supplied, this will return either a custom patch-specific + * view (if the manifest specifies one), or a generic view if not. The preferredType argument + * can be used to choose one of the types of view returned by getAvailableViewTypes(). + * + * @param {PatchConnection} patchConnection - the connection to use + * @param {string} preferredType - the name of the type of view to open, e.g. "generic" + * or the name of one of the views in the manifest + * @returns {HTMLElement} a HTMLElement that can be displayed as the patch GUI + */ +export async function createPatchView (patchConnection, preferredType) +{ + if (patchConnection?.manifest) + { + let view = patchConnection.manifest.view; + + if (view && preferredType === "generic") + if (view.src) + view = undefined; + + const viewModuleURL = view?.src ? patchConnection.getResourceAddress (view.src) : "./cmaj-generic-patch-view.js"; + const viewModule = await import (viewModuleURL); + const patchView = await viewModule?.default (patchConnection); + + if (patchView) + { + patchView.style.display = "block"; + + if (view?.width > 10) + patchView.style.width = view.width + "px"; + else + patchView.style.width = undefined; + + if (view?.height > 10) + patchView.style.height = view.height + "px"; + else + patchView.style.height = undefined; + + return patchView; + } + } + + return undefined; +} + +//============================================================================== +/** If a patch view declares itself to be scalable, this will attempt to scale it to fit + * into a given parent element. + * + * @param {HTMLElement} view - the patch view + * @param {HTMLElement} parentToScale - the patch view's direct parent element, to which + * the scale factor will be applied + * @param {HTMLElement} parentContainerToFitTo - an outer parent of the view, whose bounds + * the view will be made to fit + */ +export function scalePatchViewToFit (view, parentToScale, parentContainerToFitTo) +{ + function getClientSize (view) + { + const clientStyle = getComputedStyle (view); + + return { + width: view.clientHeight - parseFloat (clientStyle.paddingTop) - parseFloat (clientStyle.paddingBottom), + height: view.clientWidth - parseFloat (clientStyle.paddingLeft) - parseFloat (clientStyle.paddingRight) + }; + } + + const scaleLimits = view.getScaleFactorLimits?.(); + + if (scaleLimits && (scaleLimits.minScale || scaleLimits.maxScale) && parentContainerToFitTo) + { + const minScale = scaleLimits.minScale || 0.25; + const maxScale = scaleLimits.maxScale || 5.0; + + const targetSize = getClientSize (parentContainerToFitTo); + const clientSize = getClientSize (view); + + const scaleW = targetSize.width / clientSize.width; + const scaleH = targetSize.height / clientSize.height; + + const scale = Math.min (maxScale, Math.max (minScale, Math.min (scaleW, scaleH))); + + parentToScale.style.transform = `scale(${scale})`; + } + else + { + parentToScale.style.transform = "none"; + } +} + +//============================================================================== +class PatchViewHolder extends HTMLElement +{ + constructor (view) + { + super(); + this.view = view; + this.style = `display: block; position: relative; width: 100%; height: 100%; overflow: visible; transform-origin: 0% 0%;`; + } + + connectedCallback() + { + this.appendChild (this.view); + this.resizeObserver = new ResizeObserver (() => scalePatchViewToFit (this.view, this, this.parentElement)); + this.resizeObserver.observe (this.parentElement); + scalePatchViewToFit (this.view, this, this.parentElement); + } + + disconnectedCallback() + { + this.resizeObserver = undefined; + this.innerHTML = ""; + } +} + +window.customElements.define ("cmaj-patch-view-holder", PatchViewHolder); + +//============================================================================== +/** Creates and returns a HTMLElement view which can be shown to control this patch. + * + * Unlike createPatchView(), this will return a holder element that handles scaling + * and resizing, and which follows changes to the size of the parent that you + * append it to. + * + * If no preferredType argument is supplied, this will return either a custom patch-specific + * view (if the manifest specifies one), or a generic view if not. The preferredType argument + * can be used to choose one of the types of view returned by getAvailableViewTypes(). + * + * @param {PatchConnection} patchConnection - the connection to use + * @param {string} preferredType - the name of the type of view to open, e.g. "generic" + * or the name of one of the views in the manifest + * @returns {HTMLElement} a HTMLElement that can be displayed as the patch GUI + */ +export async function createPatchViewHolder (patchConnection, preferredType) +{ + const view = await createPatchView (patchConnection, preferredType); + + if (view) + return new PatchViewHolder (view); +} diff --git a/assets/example_patches/SubtractOne/cmaj_api/cmaj-piano-keyboard.js b/assets/example_patches/SubtractOne/cmaj_api/cmaj-piano-keyboard.js new file mode 100644 index 00000000..e4084071 --- /dev/null +++ b/assets/example_patches/SubtractOne/cmaj_api/cmaj-piano-keyboard.js @@ -0,0 +1,471 @@ +// +// ,ad888ba, 88 +// d8"' "8b +// d8 88,dba,,adba, ,aPP8A.A8 88 The Cmajor Toolkit +// Y8, 88 88 88 88 88 88 +// Y8a. .a8P 88 88 88 88, ,88 88 (C)2024 Cmajor Software Ltd +// '"Y888Y"' 88 88 88 '"8bbP"Y8 88 https://cmajor.dev +// ,88 +// 888P" +// +// The Cmajor project is subject to commercial or open-source licensing. +// You may use it under the terms of the GPLv3 (see www.gnu.org/licenses), or +// visit https://cmajor.dev to learn about our commercial licence options. +// +// CMAJOR IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER +// EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE +// DISCLAIMED. + +import * as midi from "./cmaj-midi-helpers.js" + +/** + * An general-purpose on-screen piano keyboard component that allows clicks or + * key-presses to be used to play things. + * + * To receive events, you can attach "note-down" and "note-up" event listeners via + * the standard HTMLElement/EventTarget event system, e.g. + * + * myKeyboardElement.addEventListener("note-down", (note) => { ...handle note on... }); + * myKeyboardElement.addEventListener("note-up", (note) => { ...handle note off... }); + * + * The `note` object will contain a `note` property with the MIDI note number. + * (And obviously you can remove them with removeEventListener) + * + * Or, if you're connecting the keyboard to a PatchConnection, you can use the helper + * method attachToPatchConnection() to create and attach some suitable listeners. + * + */ +export default class PianoKeyboard extends HTMLElement +{ + constructor ({ naturalNoteWidth, + accidentalWidth, + accidentalPercentageHeight, + naturalNoteBorder, + accidentalNoteBorder, + pressedNoteColour } = {}) + { + super(); + + this.naturalWidth = naturalNoteWidth || 20; + this.accidentalWidth = accidentalWidth || 12; + this.accidentalPercentageHeight = accidentalPercentageHeight || 66; + this.naturalBorder = naturalNoteBorder || "2px solid #333"; + this.accidentalBorder = accidentalNoteBorder || "2px solid #333"; + this.pressedColour = pressedNoteColour || "#8ad"; + + this.root = this.attachShadow({ mode: "open" }); + + this.root.addEventListener ("mousedown", (event) => this.handleMouse (event, true, false) ); + this.root.addEventListener ("mouseup", (event) => this.handleMouse (event, false, true) ); + this.root.addEventListener ("mousemove", (event) => this.handleMouse (event, false, false) ); + this.root.addEventListener ("mouseenter", (event) => this.handleMouse (event, false, false) ); + this.root.addEventListener ("mouseout", (event) => this.handleMouse (event, false, false) ); + + this.addEventListener ("keydown", (event) => this.handleKey (event, true)); + this.addEventListener ("keyup", (event) => this.handleKey (event, false)); + this.addEventListener ("focusout", (event) => this.allNotesOff()); + + this.currentDraggedNote = -1; + this.currentExternalNotesOn = new Set(); + this.currentKeyboardNotes = new Set(); + this.currentPlayedNotes = new Set(); + this.currentDisplayedNotes = new Set(); + this.notes = []; + this.modifierKeys = 0; + this.currentTouches = new Map(); + + this.refreshHTML(); + + for (let child of this.root.children) + { + child.addEventListener ("touchstart", (event) => this.touchStart (event) ); + child.addEventListener ("touchend", (event) => this.touchEnd (event) ); + } + } + + static get observedAttributes() + { + return ["root-note", "note-count", "key-map"]; + } + + get config() + { + return { + rootNote: parseInt(this.getAttribute("root-note") || "36"), + numNotes: parseInt(this.getAttribute("note-count") || "61"), + keymap: this.getAttribute("key-map") || "KeyA KeyW KeyS KeyE KeyD KeyF KeyT KeyG KeyY KeyH KeyU KeyJ KeyK KeyO KeyL KeyP Semicolon", + }; + } + + /** This attaches suitable listeners to make this keyboard control the given MIDI + * endpoint of a PatchConnection object. Use detachPatchConnection() to remove + * a connection later on. + * + * @param {PatchConnection} patchConnection + * @param {string} midiInputEndpointID + */ + attachToPatchConnection (patchConnection, midiInputEndpointID) + { + const velocity = 100; + + const callbacks = { + noteDown: e => patchConnection.sendMIDIInputEvent (midiInputEndpointID, 0x900000 | (e.detail.note << 8) | velocity), + noteUp: e => patchConnection.sendMIDIInputEvent (midiInputEndpointID, 0x800000 | (e.detail.note << 8) | velocity), + midiIn: e => this.handleExternalMIDI (e.message), + midiInputEndpointID + }; + + if (! this.callbacks) + this.callbacks = new Map(); + + this.callbacks.set (patchConnection, callbacks); + + this.addEventListener ("note-down", callbacks.noteDown); + this.addEventListener ("note-up", callbacks.noteUp); + patchConnection.addEndpointListener (midiInputEndpointID, callbacks.midiIn); + } + + /** This removes the connection to a PatchConnection object that was previously attached + * with attachToPatchConnection(). + * + * @param {PatchConnection} patchConnection + */ + detachPatchConnection (patchConnection) + { + const callbacks = this.callbacks.get (patchConnection); + + if (callbacks) + { + this.removeEventListener ("note-down", callbacks.noteDown); + this.removeEventListener ("note-up", callbacks.noteUp); + patchConnection.removeEndpointListener (callbacks.midiInputEndpointID, callbacks.midiIn); + } + + this.callbacks[patchConnection] = undefined; + } + + //============================================================================== + /** Can be overridden to return the color to use for a note index */ + getNoteColour (note) { return undefined; } + + /** Can be overridden to return the text label to draw on a note index */ + getNoteLabel (note) { return midi.getChromaticScaleIndex (note) == 0 ? midi.getNoteNameWithOctaveNumber (note) : ""; } + + /** Clients should call this to deliver a MIDI message, which the keyboard will use to + * highlight the notes that are currently playing. + */ + handleExternalMIDI (message) + { + if (midi.isNoteOn (message)) + { + const note = midi.getNoteNumber (message); + this.currentExternalNotesOn.add (note); + this.refreshActiveNoteElements(); + } + else if (midi.isNoteOff (message)) + { + const note = midi.getNoteNumber (message); + this.currentExternalNotesOn.delete (note); + this.refreshActiveNoteElements(); + } + } + + /** This method will be called when the user plays a note. The default behaviour is + * to dispath an event, but you could override this if you needed to. + */ + sendNoteOn (note) { this.dispatchEvent (new CustomEvent('note-down', { detail: { note: note }})); } + + /** This method will be called when the user releases a note. The default behaviour is + * to dispath an event, but you could override this if you needed to. + */ + sendNoteOff (note) { this.dispatchEvent (new CustomEvent('note-up', { detail: { note: note } })); } + + /** Clients can call this to force all the notes to turn off, e.g. in a "panic". */ + allNotesOff() + { + this.setDraggedNote (-1); + this.modifierKeys = 0; + + for (let note of this.currentKeyboardNotes.values()) + this.removeKeyboardNote (note); + + this.currentExternalNotesOn.clear(); + this.refreshActiveNoteElements(); + } + + setDraggedNote (newNote) + { + if (newNote != this.currentDraggedNote) + { + if (this.currentDraggedNote >= 0) + this.sendNoteOff (this.currentDraggedNote); + + this.currentDraggedNote = newNote; + + if (this.currentDraggedNote >= 0) + this.sendNoteOn (this.currentDraggedNote); + + this.refreshActiveNoteElements(); + } + } + + addKeyboardNote (note) + { + if (! this.currentKeyboardNotes.has (note)) + { + this.sendNoteOn (note); + this.currentKeyboardNotes.add (note); + this.refreshActiveNoteElements(); + } + } + + removeKeyboardNote (note) + { + if (this.currentKeyboardNotes.has (note)) + { + this.sendNoteOff (note); + this.currentKeyboardNotes.delete (note); + this.refreshActiveNoteElements(); + } + } + + isNoteActive (note) + { + return note == this.currentDraggedNote + || this.currentExternalNotesOn.has (note) + || this.currentKeyboardNotes.has (note); + } + + //============================================================================== + /** @private */ + touchEnd (event) + { + for (const touch of event.changedTouches) + { + const note = this.currentTouches.get (touch.identifier); + this.currentTouches.delete (touch.identifier); + this.removeKeyboardNote (note); + } + + event.preventDefault(); + } + + /** @private */ + touchStart (event) + { + for (const touch of event.changedTouches) + { + const note = touch.target.id.substring (4); + this.currentTouches.set (touch.identifier, note); + this.addKeyboardNote (note); + } + + event.preventDefault(); + } + + /** @private */ + handleMouse (event, isDown, isUp) + { + if (isDown) + this.isDragging = true; + + if (this.isDragging) + { + let newActiveNote = -1; + + if (event.buttons != 0 && event.type != "mouseout") + { + const note = event.target.id.substring (4); + + if (note !== undefined) + newActiveNote = parseInt (note); + } + + this.setDraggedNote (newActiveNote); + + if (! isDown) + event.preventDefault(); + } + + if (isUp) + this.isDragging = false; + } + + /** @private */ + handleKey (event, isDown) + { + if (event.key == "Meta" || event.key == "Alt" || event.key == "Control" || event.key == "Shift") + { + this.modifierKeys += isDown ? 1 : -1; + return; + } + + if (this.modifierKeys != 0) + return; + + const config = this.config; + const index = config.keymap.split (" ").indexOf (event.code); + + if (index >= 0) + { + const note = Math.floor ((config.rootNote + (config.numNotes / 4) + 11) / 12) * 12 + index; + + if (isDown) + this.addKeyboardNote (note); + else + this.removeKeyboardNote (note); + + event.preventDefault(); + } + } + + /** @private */ + refreshHTML() + { + this.root.innerHTML = `${this.getNoteElements()}`; + + for (let i = 0; i < 128; ++i) + { + const elem = this.shadowRoot.getElementById (`note${i.toString()}`); + this.notes.push ({ note: i, element: elem }); + } + + this.style.maxWidth = window.getComputedStyle (this).scrollWidth; + } + + /** @private */ + refreshActiveNoteElements() + { + for (let note of this.notes) + { + if (note.element) + { + if (this.isNoteActive (note.note)) + note.element.classList.add ("active"); + else + note.element.classList.remove ("active"); + } + } + } + + /** @private */ + getAccidentalOffset (note) + { + let index = midi.getChromaticScaleIndex (note); + + let negativeOffset = -this.accidentalWidth / 16; + let positiveOffset = 3 * this.accidentalWidth / 16; + + const accOffset = this.naturalWidth - (this.accidentalWidth / 2); + const offsets = [ 0, negativeOffset, 0, positiveOffset, 0, 0, negativeOffset, 0, 0, 0, positiveOffset, 0 ]; + + return accOffset + offsets[index]; + } + + /** @private */ + getNoteElements() + { + const config = this.config; + let naturals = "", accidentals = ""; + let x = 0; + + for (let i = 0; i < config.numNotes; ++i) + { + const note = config.rootNote + i; + const name = this.getNoteLabel (note); + + if (midi.isNatural (note)) + { + naturals += `

${name}

`; + } + else + { + let accidentalOffset = this.getAccidentalOffset (note); + accidentals += `
`; + } + + if (midi.isNatural (note + 1) || i == config.numNotes - 1) + x += this.naturalWidth; + } + + this.style.maxWidth = (x + 1) + "px"; + + return `
+ ${naturals} + ${accidentals} +
`; + } + + /** @private */ + getCSS() + { + let extraColours = ""; + const config = this.config; + + for (let i = 0; i < config.numNotes; ++i) + { + const note = config.rootNote + i; + const colourOverride = this.getNoteColour (note); + + if (colourOverride) + extraColours += `#note${note}:not(.active) { background: ${colourOverride}; }`; + } + + return ` + * { + box-sizing: border-box; + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + margin: 0; + padding: 0; + } + + :host { + display: block; + overflow: auto; + position: relative; + } + + .natural-note { + position: absolute; + border: ${this.naturalBorder}; + background: #fff; + width: ${this.naturalWidth}px; + height: 100%; + + display: flex; + align-items: end; + justify-content: center; + } + + p { + pointer-events: none; + text-align: center; + font-size: 0.7rem; + color: grey; + } + + .accidental-note { + position: absolute; + top: 0; + border: ${this.accidentalBorder}; + background: #333; + width: ${this.accidentalWidth}px; + height: ${this.accidentalPercentageHeight}%; + } + + .note-holder { + position: relative; + height: 100%; + } + + .active { + background: ${this.pressedColour}; + } + + ${extraColours} + ` + } +} diff --git a/assets/example_patches/SubtractOne/cmaj_api/cmaj-server-session.js b/assets/example_patches/SubtractOne/cmaj_api/cmaj-server-session.js new file mode 100644 index 00000000..813f5fcd --- /dev/null +++ b/assets/example_patches/SubtractOne/cmaj_api/cmaj-server-session.js @@ -0,0 +1,452 @@ +// +// ,ad888ba, 88 +// d8"' "8b +// d8 88,dba,,adba, ,aPP8A.A8 88 +// Y8, 88 88 88 88 88 88 +// Y8a. .a8P 88 88 88 88, ,88 88 (C)2024 Cmajor Software Ltd +// '"Y888Y"' 88 88 88 '"8bbP"Y8 88 https://cmajor.dev +// ,88 +// 888P" +// +// This file may be used under the terms of the ISC license: +// +// Permission to use, copy, modify, and/or distribute this software for any purpose with or +// without fee is hereby granted, provided that the above copyright notice and this permission +// notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import { PatchConnection } from "./cmaj-patch-connection.js" +import { EventListenerList } from "./cmaj-event-listener-list.js" + + +//============================================================================== +/* + * This class provides the API and manages the communication protocol between + * a javascript application and a Cmajor session running on some kind of server + * (which may be local or remote). + * + * This is an abstract base class: some kind of transport layer will create a + * subclass of ServerSession which a client application can then use to control + * and interact with the server. + */ +export class ServerSession extends EventListenerList +{ + /** A server session must be given a unique sessionID. + * @param {string} sessionID - this must be a unique string which is safe for + * use as an identifier or filename + */ + constructor (sessionID) + { + super(); + + this.sessionID = sessionID; + this.activePatchConnections = new Set(); + this.status = { connected: false, loaded: false }; + this.lastServerMessageTime = Date.now(); + this.checkForServerTimer = setInterval (() => this.checkServerStillExists(), 2000); + } + + /** Call `dispose()` when this session is no longer needed and should be released. */ + dispose() + { + if (this.checkForServerTimer) + { + clearInterval (this.checkForServerTimer); + this.checkForServerTimer = undefined; + } + + this.status = { connected: false, loaded: false }; + } + + //============================================================================== + // Session status methods: + + /** Attaches a listener function which will be called when the session status changes. + * The listener will be called with an argument object containing lots of properties + * describing the state, including any errors, loaded patch manifest, etc. + */ + addStatusListener (listener) { this.addEventListener ("session_status", listener); } + + /** Removes a listener that was previously added by `addStatusListener()` + */ + removeStatusListener (listener) { this.removeEventListener ("session_status", listener); } + + /** Asks the server to asynchronously send a status update message with the latest status. + */ + requestSessionStatus() { this.sendMessageToServer ({ type: "req_session_status" }); } + + /** Returns the session's last known status object. */ + getCurrentStatus() { return this.status; } + + //============================================================================== + // Patch loading: + + /** Asks the server to load the specified patch into our session. + */ + loadPatch (patchFileToLoad) + { + this.currentPatchLocation = patchFileToLoad; + this.sendMessageToServer ({ type: "load_patch", file: patchFileToLoad }); + } + + /** Tells the server to asynchronously generate a list of patches that it has access to. + * The function provided will be called back with an array of manifest objects describing + * each of the patches. + */ + requestAvailablePatchList (callbackFunction) + { + const replyType = this.createReplyID ("patchlist_"); + this.addSingleUseListener (replyType, callbackFunction); + this.sendMessageToServer ({ type: "req_patchlist", + replyType: replyType }); + } + + /** Creates and returns a new PatchConnection object which can be used to control the + * patch that this session has loaded. + */ + createPatchConnection() + { + class ServerPatchConnection extends PatchConnection + { + constructor (session) + { + super(); + this.session = session; + this.manifest = session.status?.manifest; + this.session.activePatchConnections.add (this); + } + + dispose() + { + this.session.activePatchConnections.delete (this); + this.session = undefined; + } + + sendMessageToServer (message) + { + this.session?.sendMessageToServer (message); + } + + getResourceAddress (path) + { + if (! this.session?.status?.httpRootURL) + return undefined; + + return this.session.status.httpRootURL + + (path.startsWith ("/") ? path.substr (1) : path); + } + } + + return new ServerPatchConnection (this); + } + + //============================================================================== + // Audio input source handling: + + /** + * Sets a custom audio input source for a particular endpoint. + * + * When a source is changed, a callback is sent to any audio input mode listeners (see + * `addAudioInputModeListener()`) + * + * @param {Object} endpointID + * @param {boolean} shouldMute - if true, the endpoint will be muted + * @param {Uint8Array | Array} fileDataToPlay - if this is some kind of array containing + * binary data that can be parsed as an audio file, then it will be sent across for the + * server to play as a looped input sample. + */ + setAudioInputSource (endpointID, shouldMute, fileDataToPlay) + { + const loopFile = "_audio_source_" + endpointID; + + if (fileDataToPlay) + { + this.registerFile (loopFile, + { + size: fileDataToPlay.byteLength, + read: (start, length) => { return new Blob ([fileDataToPlay.slice (start, start + length)]); } + }); + + this.sendMessageToServer ({ type: "set_custom_audio_input", + endpoint: endpointID, + file: loopFile }); + } + else + { + this.removeFile (loopFile); + + this.sendMessageToServer ({ type: "set_custom_audio_input", + endpoint: endpointID, + mute: !! shouldMute }); + } + } + + /** Attaches a listener function to be told when the input source for a particular + * endpoint is changed by a call to `setAudioInputSource()`. + */ + addAudioInputModeListener (endpointID, listener) { this.addEventListener ("audio_input_mode_" + endpointID, listener); } + + /** Removes a listener previously added with `addAudioInputModeListener()` */ + removeAudioInputModeListener (endpointID, listener) { this.removeEventListener ("audio_input_mode_" + endpointID, listener); } + + /** Asks the server to send an update with the latest status to any audio mode listeners that + * are attached to the given endpoint. + * @param {string} endpointID + */ + requestAudioInputMode (endpointID) { this.sendMessageToServer ({ type: "req_audio_input_mode", endpoint: endpointID }); } + + //============================================================================== + // Audio device methods: + + /** Enables or disables audio playback. + * When playback state changes, a status update is sent to any status listeners. + * @param {boolean} shouldBeActive + */ + setAudioPlaybackActive (shouldBeActive) { this.sendMessageToServer ({ type: "set_audio_playback_active", active: shouldBeActive }); } + + /** Asks the server to apply a new set of audio device properties. + * The properties object uses the same format as the object that is passed to the listeners + * (see `addAudioDevicePropertiesListener()`). + */ + setAudioDeviceProperties (newProperties) { this.sendMessageToServer ({ type: "set_audio_device_props", properties: newProperties }); } + + /** Attaches a listener function which will be called when the audio device properties are + * changed. + * + * You can remove the listener when it's no longer needed with `removeAudioDevicePropertiesListener()`. + * + * @param listener - this callback will receive an argument object containing all the + * details about the device. + */ + addAudioDevicePropertiesListener (listener) { this.addEventListener ("audio_device_properties", listener); } + + /** Removes a listener that was added with `addAudioDevicePropertiesListener()` */ + removeAudioDevicePropertiesListener (listener) { this.removeEventListener ("audio_device_properties", listener); } + + /** Causes an asynchronous callback to any audio device listeners that are registered. */ + requestAudioDeviceProperties() { this.sendMessageToServer ({ type: "req_audio_device_props" }); } + + //============================================================================== + /** Asks the server to asynchronously generate some code from the currently loaded patch. + * + * @param {string} codeType - this must be one of the strings that are listed in the + * status's `codeGenTargets` property. For example, "cpp" + * would request a C++ version of the patch. + * @param {Object} [extraOptions] - this optionally provides target-specific properties. + * @param callbackFunction - this function will be called with the result when it has + * been generated. Its argument will be an object containing the + * code, errors and other metadata about the patch. + */ + requestGeneratedCode (codeType, extraOptions, callbackFunction) + { + const replyType = this.createReplyID ("codegen_"); + this.addSingleUseListener (replyType, callbackFunction); + this.sendMessageToServer ({ type: "req_codegen", + codeType: codeType, + options: extraOptions, + replyType: replyType }); + } + + //============================================================================== + // File change monitoring: + + /** Attaches a listener to be told when a file change is detected in the currently-loaded + * patch. The function will be called with an object that gives rough details about the + * type of change, i.e. whether it's a manifest or asset file, or a cmajor file, but it + * won't provide any information about exactly which files are involved. + */ + addFileChangeListener (listener) { this.addEventListener ("patch_source_changed", listener); } + + /** Removes a listener that was previously added with `addFileChangeListener()`. + */ + removeFileChangeListener (listener) { this.removeEventListener ("patch_source_changed", listener); } + + //============================================================================== + // CPU level monitoring methods: + + /** Attaches a listener function which will be sent messages containing CPU info. + * To remove the listener, call `removeCPUListener()`. To change the rate of these + * messages, use `setCPULevelUpdateRate()`. + */ + addCPUListener (listener) { this.addEventListener ("cpu_info", listener); this.updateCPULevelUpdateRate(); } + + /** Removes a listener that was previously attached with `addCPUListener()`. */ + removeCPUListener (listener) { this.removeEventListener ("cpu_info", listener); this.updateCPULevelUpdateRate(); } + + /** Changes the frequency at which CPU level update messages are sent to listeners. */ + setCPULevelUpdateRate (framesPerUpdate) { this.cpuFramesPerUpdate = framesPerUpdate; this.updateCPULevelUpdateRate(); } + + /** Attaches a listener to be told when a file change is detected in the currently-loaded + * patch. The function will be called with an object that gives rough details about the + * type of change, i.e. whether it's a manifest or asset file, or a cmajor file, but it + * won't provide any information about exactly which files are involved. + */ + addInfiniteLoopListener (listener) { this.addEventListener ("infinite_loop_detected", listener); } + + /** Removes a listener that was previously added with `addFileChangeListener()`. */ + removeInfiniteLoopListener (listener) { this.removeEventListener ("infinite_loop_detected", listener); } + + //============================================================================== + /** Registers a virtual file with the server, under the given name. + * + * @param {string} filename - the full path name of the file + * @param {Object} contentProvider - this object must have a property called `size` which is a + * constant size in bytes for the file, and a method `read (offset, size)` which + * returns an array (or UInt8Array) of bytes for the data in a given chunk of the file. + * The server may repeatedly call this method at any time until `removeFile()` is + * called to deregister the file. + */ + registerFile (filename, contentProvider) + { + if (! this.files) + this.files = new Map(); + + this.files.set (filename, contentProvider); + + this.sendMessageToServer ({ type: "register_file", + filename: filename, + size: contentProvider.size }); + } + + /** Removes a file that was previously registered with `registerFile()`. */ + removeFile (filename) + { + this.sendMessageToServer ({ type: "remove_file", + filename: filename }); + this.files?.delete (filename); + } + + //============================================================================== + // Private methods from this point... + + /** An implementation subclass must call this when the session first connects + * @private + */ + handleSessionConnection() + { + if (! this.status.connected) + { + this.requestSessionStatus(); + this.requestAudioDeviceProperties(); + + if (this.currentPatchLocation) + { + this.loadPatch (this.currentPatchLocation); + this.currentPatchLocation = undefined; + } + } + } + + /** An implementation subclass must call this when a message arrives + * @private + */ + handleMessageFromServer (msg) + { + this.lastServerMessageTime = Date.now(); + const type = msg.type; + const message = msg.message; + + switch (type) + { + case "cpu_info": + case "audio_device_properties": + case "patch_source_changed": + case "infinite_loop_detected": + this.dispatchEvent (type, message); + break; + + case "session_status": + message.connected = true; + this.setNewStatus (message); + break; + + case "req_file_read": + this.handleFileReadRequest (message); + break; + + case "ping": + this.sendMessageToServer ({ type: "ping" }); + break; + + default: + if (type.startsWith ("audio_input_mode_") || type.startsWith ("reply_")) + { + this.dispatchEvent (type, message); + break; + } + + for (const c of this.activePatchConnections) + c.deliverMessageFromServer (msg); + + break; + } + } + + /** @private */ + checkServerStillExists() + { + if (Date.now() > this.lastServerMessageTime + 10000) + this.setNewStatus ({ + connected: false, + loaded: false, + status: "Cannot connect to the Cmajor server" + }); + } + + /** @private */ + setNewStatus (newStatus) + { + this.status = newStatus; + this.dispatchEvent ("session_status", this.status); + this.updateCPULevelUpdateRate(); + } + + /** @private */ + updateCPULevelUpdateRate() + { + const rate = this.getNumListenersForType ("cpu_info") > 0 ? (this.cpuFramesPerUpdate || 15000) : 0; + this.sendMessageToServer ({ type: "set_cpu_info_rate", + framesPerCallback: rate }); + } + + /** @private */ + handleFileReadRequest (request) + { + const contentProvider = this.files?.get (request?.file); + + if (contentProvider && request.offset !== null && request.size != 0) + { + const data = contentProvider.read (request.offset, request.size); + const reader = new FileReader(); + + reader.onloadend = (e) => + { + const base64 = e.target?.result?.split?.(",", 2)[1]; + + if (base64) + this.sendMessageToServer ({ type: "file_content", + file: request.file, + data: base64, + start: request.offset }); + }; + + reader.readAsDataURL (data); + } + } + + /** @private */ + createReplyID (stem) + { + return "reply_" + stem + this.createRandomID(); + } + + /** @private */ + createRandomID() + { + return (Math.floor (Math.random() * 100000000)).toString(); + } +} diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/images/facebook.svg b/assets/example_patches/SubtractOne/gui/stripped-build/images/facebook.svg new file mode 100644 index 00000000..a0222a7b --- /dev/null +++ b/assets/example_patches/SubtractOne/gui/stripped-build/images/facebook.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/images/favicon-16x16.png b/assets/example_patches/SubtractOne/gui/stripped-build/images/favicon-16x16.png new file mode 100644 index 00000000..8570d488 Binary files /dev/null and b/assets/example_patches/SubtractOne/gui/stripped-build/images/favicon-16x16.png differ diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/images/favicon-32x32.png b/assets/example_patches/SubtractOne/gui/stripped-build/images/favicon-32x32.png new file mode 100644 index 00000000..84bfdcb3 Binary files /dev/null and b/assets/example_patches/SubtractOne/gui/stripped-build/images/favicon-32x32.png differ diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/images/favicon.ico b/assets/example_patches/SubtractOne/gui/stripped-build/images/favicon.ico new file mode 100644 index 00000000..6c12f43c Binary files /dev/null and b/assets/example_patches/SubtractOne/gui/stripped-build/images/favicon.ico differ diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/images/keyboard.png b/assets/example_patches/SubtractOne/gui/stripped-build/images/keyboard.png new file mode 100644 index 00000000..7756a0df Binary files /dev/null and b/assets/example_patches/SubtractOne/gui/stripped-build/images/keyboard.png differ diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/images/knobs.png b/assets/example_patches/SubtractOne/gui/stripped-build/images/knobs.png new file mode 100644 index 00000000..fbf06719 Binary files /dev/null and b/assets/example_patches/SubtractOne/gui/stripped-build/images/knobs.png differ diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/images/logo.svg b/assets/example_patches/SubtractOne/gui/stripped-build/images/logo.svg new file mode 100644 index 00000000..6c9010de --- /dev/null +++ b/assets/example_patches/SubtractOne/gui/stripped-build/images/logo.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/images/midi-keyboard.png b/assets/example_patches/SubtractOne/gui/stripped-build/images/midi-keyboard.png new file mode 100644 index 00000000..6cd2efa2 Binary files /dev/null and b/assets/example_patches/SubtractOne/gui/stripped-build/images/midi-keyboard.png differ diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/images/presets.png b/assets/example_patches/SubtractOne/gui/stripped-build/images/presets.png new file mode 100644 index 00000000..0c302ac2 Binary files /dev/null and b/assets/example_patches/SubtractOne/gui/stripped-build/images/presets.png differ diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/images/twitter-preview.png b/assets/example_patches/SubtractOne/gui/stripped-build/images/twitter-preview.png new file mode 100644 index 00000000..d025eae4 Binary files /dev/null and b/assets/example_patches/SubtractOne/gui/stripped-build/images/twitter-preview.png differ diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/images/twitter.svg b/assets/example_patches/SubtractOne/gui/stripped-build/images/twitter.svg new file mode 100644 index 00000000..6b17c70c --- /dev/null +++ b/assets/example_patches/SubtractOne/gui/stripped-build/images/twitter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/images/wood-1.jpg b/assets/example_patches/SubtractOne/gui/stripped-build/images/wood-1.jpg new file mode 100644 index 00000000..4998e48c Binary files /dev/null and b/assets/example_patches/SubtractOne/gui/stripped-build/images/wood-1.jpg differ diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/images/wood-2.jpg b/assets/example_patches/SubtractOne/gui/stripped-build/images/wood-2.jpg new file mode 100644 index 00000000..f31877c3 Binary files /dev/null and b/assets/example_patches/SubtractOne/gui/stripped-build/images/wood-2.jpg differ diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/images/x.svg b/assets/example_patches/SubtractOne/gui/stripped-build/images/x.svg new file mode 100644 index 00000000..5dbd9198 --- /dev/null +++ b/assets/example_patches/SubtractOne/gui/stripped-build/images/x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/index.html b/assets/example_patches/SubtractOne/gui/stripped-build/index.html new file mode 100644 index 00000000..cc0fca64 --- /dev/null +++ b/assets/example_patches/SubtractOne/gui/stripped-build/index.html @@ -0,0 +1 @@ +SUBTRACT ONE | Web Audio Synthesizer
\ No newline at end of file diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/index.js b/assets/example_patches/SubtractOne/gui/stripped-build/index.js new file mode 100644 index 00000000..859b6b18 --- /dev/null +++ b/assets/example_patches/SubtractOne/gui/stripped-build/index.js @@ -0,0 +1,14 @@ +export default function createView (patchConnection) { + const iframe = document.createElement ("iframe"); + iframe.style.display = "block"; + iframe.style.border = "0"; + iframe.style.width = "100%"; + iframe.style.height = "100%"; + + const base = new URL (".", import.meta.url); + iframe.src = new URL ("./index.html", base); + + iframe.CmajorSingletonPatchConnection = patchConnection; + + return iframe; +} \ No newline at end of file diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/static/css/main.a3473d71.css b/assets/example_patches/SubtractOne/gui/stripped-build/static/css/main.a3473d71.css new file mode 100644 index 00000000..8ed77f46 --- /dev/null +++ b/assets/example_patches/SubtractOne/gui/stripped-build/static/css/main.a3473d71.css @@ -0,0 +1 @@ +@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:400;src:url(../../static/media/P5sMzZCDf9_T_10UxCFuj5-v6dg.53583fe6e9e2e5b8c66e.woff2) format("woff2");unicode-range:u+0460-052f,u+1c80-1c88,u+20b4,u+2de0-2dff,u+a640-a69f,u+fe2e-fe2f}@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:400;src:url(../../static/media/P5sMzZCDf9_T_10dxCFuj5-v6dg.21be06171f7185794c4b.woff2) format("woff2");unicode-range:u+0301,u+0400-045f,u+0490-0491,u+04b0-04b1,u+2116}@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:400;src:url(../../static/media/P5sMzZCDf9_T_10VxCFuj5-v6dg.4473ecd0a0b773933553.woff2) format("woff2");unicode-range:u+1f??}@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:400;src:url(../../static/media/P5sMzZCDf9_T_10axCFuj5-v6dg.3da9eb7138433db3b882.woff2) format("woff2");unicode-range:u+0370-03ff}@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:400;src:url(../../static/media/P5sMzZCDf9_T_10bxCFuj5-v6dg.346f2a5db1314ce33bea.woff2) format("woff2");unicode-range:u+0590-05ff,u+200c-2010,u+20aa,u+25cc,u+fb1d-fb4f}@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:400;src:url(../../static/media/P5sMzZCDf9_T_10WxCFuj5-v6dg.0f9c796637424dcc93de.woff2) format("woff2");unicode-range:u+0102-0103,u+0110-0111,u+0128-0129,u+0168-0169,u+01a0-01a1,u+01af-01b0,u+1ea0-1ef9,u+20ab}@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:400;src:url(../../static/media/P5sMzZCDf9_T_10XxCFuj5-v6dg.9412ea211130ade2e55c.woff2) format("woff2");unicode-range:u+0100-024f,u+0259,u+1e??,u+2020,u+20a0-20ab,u+20ad-20cf,u+2113,u+2c60-2c7f,u+a720-a7ff}@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:400;src:url(../../static/media/P5sMzZCDf9_T_10ZxCFuj5-v.af99bbe483be9cef4824.woff2) format("woff2");unicode-range:u+00??,u+0131,u+0152-0153,u+02bb-02bc,u+02c6,u+02da,u+02dc,u+2000-206f,u+2074,u+20ac,u+2122,u+2191,u+2193,u+2212,u+2215,u+feff,u+fffd}@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:700;src:url(../../static/media/P5sMzZCDf9_T_10UxCFuj5-v6dg.53583fe6e9e2e5b8c66e.woff2) format("woff2");unicode-range:u+0460-052f,u+1c80-1c88,u+20b4,u+2de0-2dff,u+a640-a69f,u+fe2e-fe2f}@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:700;src:url(../../static/media/P5sMzZCDf9_T_10dxCFuj5-v6dg.21be06171f7185794c4b.woff2) format("woff2");unicode-range:u+0301,u+0400-045f,u+0490-0491,u+04b0-04b1,u+2116}@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:700;src:url(../../static/media/P5sMzZCDf9_T_10VxCFuj5-v6dg.4473ecd0a0b773933553.woff2) format("woff2");unicode-range:u+1f??}@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:700;src:url(../../static/media/P5sMzZCDf9_T_10axCFuj5-v6dg.3da9eb7138433db3b882.woff2) format("woff2");unicode-range:u+0370-03ff}@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:700;src:url(../../static/media/P5sMzZCDf9_T_10bxCFuj5-v6dg.346f2a5db1314ce33bea.woff2) format("woff2");unicode-range:u+0590-05ff,u+200c-2010,u+20aa,u+25cc,u+fb1d-fb4f}@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:700;src:url(../../static/media/P5sMzZCDf9_T_10WxCFuj5-v6dg.0f9c796637424dcc93de.woff2) format("woff2");unicode-range:u+0102-0103,u+0110-0111,u+0128-0129,u+0168-0169,u+01a0-01a1,u+01af-01b0,u+1ea0-1ef9,u+20ab}@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:700;src:url(../../static/media/P5sMzZCDf9_T_10XxCFuj5-v6dg.9412ea211130ade2e55c.woff2) format("woff2");unicode-range:u+0100-024f,u+0259,u+1e??,u+2020,u+20a0-20ab,u+20ad-20cf,u+2113,u+2c60-2c7f,u+a720-a7ff}@font-face{font-display:swap;font-family:Arimo;font-style:normal;font-weight:700;src:url(../../static/media/P5sMzZCDf9_T_10ZxCFuj5-v.af99bbe483be9cef4824.woff2) format("woff2");unicode-range:u+00??,u+0131,u+0152-0153,u+02bb-02bc,u+02c6,u+02da,u+02dc,u+2000-206f,u+2074,u+20ac,u+2122,u+2191,u+2193,u+2212,u+2215,u+feff,u+fffd}@font-face{font-family:Syne Bold;font-style:normal;font-weight:400;src:url(../../static/media/Syne-Bold.8bdf52aa76a4f6d135cc.woff) format("woff")}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-touch-callout:none;background-color:#353535;color:#fff;cursor:default;font-family:Arimo,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;height:100%;margin:0;padding:0;position:relative;-webkit-user-select:none;user-select:none}*{box-sizing:border-box}h1{font-family:Syne Bold;font-size:62px;margin:0}@media (max-height:900px){h1{margin-bottom:18px!important}}body,html{margin:0;padding:0} \ No newline at end of file diff --git a/assets/example_patches/SubtractOne/gui/stripped-build/static/js/main.62462333.js b/assets/example_patches/SubtractOne/gui/stripped-build/static/js/main.62462333.js new file mode 100644 index 00000000..0572712e --- /dev/null +++ b/assets/example_patches/SubtractOne/gui/stripped-build/static/js/main.62462333.js @@ -0,0 +1,321 @@ +/*! For license information please see main.62462333.js.LICENSE.txt */ +(()=>{var e={835:(e,t,n)=>{"use strict";n.d(t,{o:()=>Os});var r={};function o(e){return"object"===typeof e&&"string"===typeof e.name}function i(e){return"object"===typeof e&&"number"===typeof e.step&&"number"===typeof e.alt}n.r(r),n.d(r,{anticipate:()=>pr,backIn:()=>cr,backInOut:()=>dr,backOut:()=>fr,bounceIn:()=>wr,bounceInOut:()=>xr,bounceOut:()=>br,circIn:()=>ur,circInOut:()=>sr,circOut:()=>lr,createAnticipateEasing:()=>nr,createBackIn:()=>tr,createExpoIn:()=>er,createMirroredEasing:()=>Jn,createReversedEasing:()=>Zn,cubicBezier:()=>Dr,easeIn:()=>or,easeInOut:()=>ar,easeOut:()=>ir,linear:()=>rr,mirrored:()=>Qn,reversed:()=>Kn});const a=[0,2,4,-1,1,3,5],u=a.map((e=>Math.floor(7*e/12)));function l(e){const{step:t,alt:n,oct:r,dir:o=1}=e,i=a[t]+7*n;if(void 0===r)return[o*i];return[o*i,o*(r-u[t]-4*n)]}const s={empty:!0,name:"",pc:"",acc:""},c={},f=(e,t)=>Array(t+1).join(e),d=e=>"CDEFGAB".charAt(e),p=e=>e<0?f("b",-e):f("#",e),h=e=>"b"===e[0]?-e.length:e.length;function m(e){return"string"===typeof e?c[e]||(c[e]=function(e){const t=function(e){const t=v.exec(e);return[t[1].toUpperCase(),t[2].replace(/x/g,"##"),t[3],t[4]]}(e);if(""===t[0]||""!==t[3])return s;const n=t[0],r=t[1],o=t[2],i=(n.charCodeAt(0)+3)%7,a=h(r),u=o.length?+o:void 0,c=l({step:i,alt:a,oct:u}),f=n+r+o,d=n+r,p=(g[i]+a+120)%12,m=void 0===u?-100:u,y=g[i]+a+12*(m+1),b=y>=0&&y<=127?y:null,w=void 0===u?null:440*Math.pow(2,(y-69)/12);return{empty:!1,acc:r,alt:a,chroma:p,coord:c,freq:w,height:y,letter:n,midi:b,name:f,oct:u,pc:d,step:i}}(e)):i(e)?m(function(e){const{step:t,alt:n,oct:r}=e,o=d(t);if(!o)return"";const i=o+p(n);return r||0===r?i+r:i}(e)):o(e)?m(e.name):s}const v=/^([a-gA-G]?)(#{1,}|b{1,}|x{1,}|)(-?\d*)\s*(.*)$/;const g=[0,2,4,5,7,9,11];new RegExp("^([-+]?\\d+)(d{1,4}|m|M|P|A{1,4})|(AA|A|P|M|m|d|dd)([-+]?\\d+)$");Math.log(2),Math.log(440);const y="C C# D D# E F F# G G# A A# B".split(" "),b="C Db D Eb E F Gb G Ab A Bb B".split(" ");function w(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};e=Math.round(e);const n=(!0===t.sharps?y:b)[e%12];if(t.pitchClass)return n;return n+(Math.floor(e/12)-1)}const x=(e,t,n,r)=>({type:"SET_PARAM",value:r,module:e,moduleIndex:t,param:n}),E=(e,t,n)=>({type:"BEGIN_SET_PARAM",module:e,moduleIndex:t,param:n}),k=(e,t,n)=>({type:"END_SET_PARAM",module:e,moduleIndex:t,param:n}),S=e=>({type:"SET_POWER",active:e}),C=e=>({type:"LOAD_PRESET",preset:e}),T=e=>({type:"SET_PRESET",preset:e}),P=e=>({type:"PRESS_NOTE",note:m(w(e))}),O=e=>({type:"UPDATE_SAMPLE_RATE",sampleRate:e}),_=(e,t)=>({type:"UPDATE_OSCILLOSCOPE",dataArray:e,currentTime:t});function A(e){let{vcoShapes:t,enableSoundEffectsOnControlInteractions:n,connection:r}=e;const{toEndpoint:o,toParameter:i}=function(e){let{vcoShapes:t}=e;const n=e=>{let{toEndpointID:t}=e;return{toEndpointID:t,toEndpointValue:e=>e,fromEndpointValue:e=>e}},r=e=>{const t=t=>`${e}Eg${t}`;return{attack:n({toEndpointID:()=>t("Attack")}),decay:n({toEndpointID:()=>t("Decay")}),sustain:n({toEndpointID:()=>t("Sustain")}),release:n({toEndpointID:()=>t("Release")})}},o=()=>{const e=(e,t)=>`vco${e+1}${t}`;return{semitones:n({toEndpointID:t=>e(t,"Semitones")}),detune:n({toEndpointID:t=>e(t,"Detune")}),gain:n({toEndpointID:t=>e(t,"Level")}),type:{toEndpointID:t=>e(t,"Shape"),toEndpointValue:e=>t.indexOf(e),fromEndpointValue:e=>t[0|e]}}},i={amp:{parameters:{gain:n({toEndpointID:()=>"masterGain"})}},general:{parameters:{octave:n({toEndpointID:()=>"masterOctave"}),glide:n({toEndpointID:()=>"masterGlide"})}},vco:{count:3,parameters:{...o()}},envelope:{parameters:{...r("amp")}},filter:{parameters:{frequency:n({toEndpointID:()=>"filterCutoff"}),resonance:n({toEndpointID:()=>"filterResonance"})}},filterEnvelope:{parameters:{intensity:n({toEndpointID:()=>"filterEgInt"}),...r("filter")}}},a={};for(const[u,{parameters:l,count:s}]of Object.entries(i))for(const[e,t]of Object.entries(l))for(let n=0;n<(s||1);++n){const r=!!s&&n;a[t.toEndpointID(r)]={parameter:{param:e,module:u,moduleIndex:r},fromEndpointValue:t.fromEndpointValue}}return{toEndpoint:e=>{let{param:t,module:n,moduleIndex:r}=e;const o=i[n];if(!o)return;const a=o.parameters[t];return a?{endpointID:a.toEndpointID(r),toEndpointValue:a.toEndpointValue}:void 0},toParameter:e=>a[e]}}({vcoShapes:t});return n||(window.Audio=class{play(){}}),{stateOverrides:{vcoShapes:t},middleware:[e=>{let{dispatch:t}=e;r.addStatusListener((e=>{(e.details.inputs||[]).filter((e=>"parameter"===e.purpose)).forEach((e=>{let{endpointID:t}=e;return r.requestParameterValue(t)})),t(O(e.sampleRate))})),r.addAllParameterListener((e=>{if("power"===e.endpointID)return void t({type:"SET_POWER",fromPatchConnection:!0,active:!!e.value});const{parameter:n,fromEndpointValue:r}=i(e.endpointID);t({type:"SET_PARAM",fromPatchConnection:!0,value:r(e.value),...n})})),r.addEndpointListener("midiIn",(e=>{if(!(e=>{let{message:t}=e;return((e,t)=>(e>>16&240)===t)(t,144)&&(e=>255&e)(t)>0})(e))return;const n=e.message>>8&255;t(P(n))})),r.addEndpointListener("snapshot",(e=>t(_(e)))),r.addStoredStateValueListener((e=>{"preset"===e.key&&t({...T(JSON.parse(e.value)),fromPatchConnection:!0})}));const a=e=>setTimeout(e,0);return a((()=>r.requestStatusUpdate())),a((()=>r.requestStoredStateValue("preset"))),e=>t=>{if(!t.fromPatchConnection){switch(t.type){case"BEGIN_SET_PARAM":return void r.sendParameterGestureStart(o(t).endpointID);case"SET_PARAM":const{endpointID:i,toEndpointValue:a}=o(t);return void r.sendEventOrValue(i,a(t.value));case"END_SET_PARAM":return void r.sendParameterGestureEnd(o(t).endpointID);case"SET_POWER":return r.sendEventOrValue("power",t.active),n?e(t):void 0;case"LOAD_PRESET":const u=e=>{let[t,n]=e;const i=(e,t,n)=>{Object.entries(n).forEach((n=>{let[i,a]=n;const u=o({param:i,module:e,moduleIndex:t});if(!u)return;const{endpointID:l,toEndpointValue:s}=u;r.sendEventOrValue(l,s(a))}))};n instanceof Array?n.forEach(((e,n)=>{i(t,n,e)})):i(t,!1,n)};return void Object.entries(t.preset).forEach(u);case"SET_PRESET":return void r.sendStoredStateValue("preset",JSON.stringify(t.preset))}return e(t)}e(t)}}]}}var R=n(522);const N=()=>{try{const e=localStorage.getItem("presets");return null===e?[]:JSON.parse(e)}catch(e){return[]}};let M={meta:{presetName:"",preset:-1,patchLink:""},onboarding:{finished:(()=>{try{const e=localStorage.getItem("onboardingState");return null!==e&&e}catch(e){return!1}})(),currentStep:0,animating:!1,shareModal:!1},power:{active:!1},general:{octave:0,glide:0},oscilloscope:{dataArray:[],fftSize:2048,sampleRate:44100},vco:[{pitch:0,type:"sawtooth",gain:1,octave:0,semitones:0,detune:0},{pitch:0,type:"sawtooth",gain:0,octave:0,semitones:0,detune:0},{pitch:0,type:"sawtooth",gain:0,octave:0,semitones:0,detune:0}],envelope:{attack:.2,decay:.2,sustain:100,release:.5},filterEnvelope:{attack:.2,decay:.2,sustain:100,release:.5,intensity:50},filter:{frequency:1500,resonance:1},sequencer:{tempo:90,gate:50,currentStep:0,steps:16},amp:{gain:1},keyboard:{note:m("C3")}};const D=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:M,t=arguments.length>1?arguments[1]:void 0;switch(t.type){case"SET_PARAM":return!1===t.moduleIndex?{...e,[t.module]:{...e[t.module],[t.param]:t.value}}:{...e,[t.module]:e[t.module].map(((e,n)=>n===t.moduleIndex?{...e,[t.param]:t.value}:e))};case"SET_POWER":return{...e,power:{...e.power,active:t.active}};case"LOAD_PRESET":return{...M,...e,...t.preset,envelope:{...e.envelope,...t.preset.envelope},power:{active:e.power.active}};case"SET_PRESET":return{...e,meta:{...e.meta,preset:t.preset}};case"PRESS_NOTE":return{...e,keyboard:{...e.keyboard,note:{...t.note}}};case"TICK":return{...e,sequencer:{...e.sequencer,currentStep:e.sequencer.currentStep===e.sequencer.steps-1?0:e.sequencer.currentStep+1}};case"UPDATE_SAMPLE_RATE":return{...e,oscilloscope:{...e.oscilloscope,sampleRate:t.sampleRate}};case"UPDATE_OSCILLOSCOPE":return{...e,oscilloscope:{...e.oscilloscope,dataArray:t.dataArray.map((e=>e))},general:{...e.general,currentTime:t.currentTime}};case"UPDATE_CURRENT_TIME":return{...e,general:{...e.general,currentTime:t.currentTime}};case"ONBOARDING_ANIMATION_COMPLETE":return{...e,onboarding:{...e.onboarding,animating:!1}};case"ONBOARDING_FINISH":return{...e,onboarding:{...e.onboarding,finished:!0},power:{...e.power,active:!0}};case"ONBOARDING_NEXT_STEP":return{...e,onboarding:{...e.onboarding,animating:!0,currentStep:e.onboarding.currentStep+1}};case"ONBOARDING_RESET":return{...e,onboarding:{...e.onboarding,animating:!1,currentStep:0,finished:!1}};case"SHARE_PATCH":return{...e,meta:{...e.meta,patchLink:t.patchLink},onboarding:{...e.onboarding,shareModal:!0}};case"CLOSE_SHARE_MODAL":return{...e,onboarding:{...e.onboarding,shareModal:!1}};default:return e}},I=e=>{let{stateOverrides:t,middleware:n}=e;return(0,R.y$)((0,R.HY)({state:D}),{state:{...M,...t}},(0,R.Tw)(...n))};var j=n(950),L=n.n(j),z=n(669),F=n.n(z),U=n(764),V=n.n(U);const $={animationIterationCount:1,borderImageOutset:1,borderImageSlice:1,borderImageWidth:1,boxFlex:1,boxFlexGroup:1,boxOrdinalGroup:1,columnCount:1,columns:1,flex:1,flexGrow:1,flexPositive:1,flexShrink:1,flexNegative:1,flexOrder:1,gridRow:1,gridRowEnd:1,gridRowSpan:1,gridRowStart:1,gridColumn:1,gridColumnEnd:1,gridColumnSpan:1,gridColumnStart:1,msGridRow:1,msGridRowSpan:1,msGridColumn:1,msGridColumnSpan:1,fontWeight:1,lineHeight:1,opacity:1,order:1,orphans:1,tabSize:1,widows:1,zIndex:1,zoom:1,WebkitLineClamp:1,fillOpacity:1,floodOpacity:1,stopOpacity:1,strokeDasharray:1,strokeDashoffset:1,strokeMiterlimit:1,strokeOpacity:1,strokeWidth:1};var B=n(429);function H(e,t){if(e.length!==t.length)return!1;for(var n=0;n1?r-1:0),i=1;i0?" Additional arguments: "+o.join(", "):"")));return ae(a)}return ie(t,e),t}(Error),be=/^[^\S\n]*?\/\* sc-component-id:\s*(\S+)\s+\*\//gm,we=function(e){var t=""+(e||""),n=[];return t.replace(be,(function(e,t,r){return n.push({componentId:t,matchIndex:r}),e})),n.map((function(e,r){var o=e.componentId,i=e.matchIndex,a=n[r+1];return{componentId:o,cssFromDOM:a?t.slice(i,a.matchIndex):t.slice(i)}}))},xe=/^\s*\/\/.*$/gm,Ee=new(F())({global:!1,cascade:!0,keyframe:!1,prefix:!1,compress:!1,semicolon:!0}),ke=new(F())({global:!1,cascade:!0,keyframe:!1,prefix:!0,compress:!1,semicolon:!1}),Se=[],Ce=function(e){if(-2===e){var t=Se;return Se=[],t}},Te=V()((function(e){Se.push(e)})),Pe=void 0,Oe=void 0,_e=void 0,Ae=function(e,t,n){return t>0&&-1!==n.slice(0,t).indexOf(Oe)&&n.slice(t-Oe.length,t)!==Oe?"."+Pe:e};ke.use([function(e,t,n){2===e&&n.length&&n[0].lastIndexOf(Oe)>0&&(n[0]=n[0].replace(_e,Ae))},Te,Ce]),Ee.use([Te,Ce]);var Re=function(e){return Ee("",e)};function Ne(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"&",o=e.join("").replace(xe,""),i=t&&n?n+" "+t+" { "+o+" }":o;return Pe=r,Oe=t,_e=new RegExp("\\"+Oe+"\\b","g"),ke(n||!t?"":t,i)}var Me=function(){return n.nc},De=function(e,t,n){n&&((e[t]||(e[t]=Object.create(null)))[n]=!0)},Ie=function(e,t){e[t]=Object.create(null)},je=function(e){return function(t,n){return void 0!==e[t]&&e[t][n]}},Le=function(e){var t="";for(var n in e)t+=Object.keys(e[n]).join(" ")+" ";return t.trim()},ze=function(e){if(e.sheet)return e.sheet;for(var t=e.ownerDocument.styleSheets.length,n=0;n"+e()+""}},Be=function(e,t){return function(){var n,r=((n={})[pe]=Le(t),n[he]="4.4.0",n),o=Me();return o&&(r.nonce=o),L().createElement("style",oe({},r,{dangerouslySetInnerHTML:{__html:e()}}))}},He=function(e){return function(){return Object.keys(e)}},We=function(e,t){return e.createTextNode(Ue(t))},qe=function e(t,n){var r=void 0===t?Object.create(null):t,o=void 0===n?Object.create(null):n,i=function(e){var t=o[e];return void 0!==t?t:o[e]=[""]},a=function(){var e="";for(var t in o){var n=o[t][0];n&&(e+=Ue(t)+n)}return e},u={clone:function(){var t=function(e){var t=Object.create(null);for(var n in e)t[n]=oe({},e[n]);return t}(r),n=Object.create(null);for(var i in o)n[i]=[o[i][0]];return e(t,n)},css:a,getIds:He(o),hasNameForId:je(r),insertMarker:i,insertRules:function(e,t,n){i(e)[0]+=t.join(" "),De(r,e,n)},removeRules:function(e){var t=o[e];void 0!==t&&(t[0]="",Ie(r,e))},sealed:!1,styleTag:null,toElement:Be(a,r),toHTML:$e(a,r)};return u},Ye=function(e,t,n,r,o){if(ve&&!n){var i=function(e,t,n){var r=document;e?r=e.ownerDocument:t&&(r=t.ownerDocument);var o=r.createElement("style");o.setAttribute(pe,""),o.setAttribute(he,"4.4.0");var i=Me();if(i&&o.setAttribute("nonce",i),o.appendChild(r.createTextNode("")),e&&!t)e.appendChild(o);else{if(!t||!e||!t.parentNode)throw new ye(6);t.parentNode.insertBefore(o,n?t:t.nextSibling)}return o}(e,t,r);return ge?function(e,t){var n=Object.create(null),r=Object.create(null),o=void 0!==t,i=!1,a=function(t){var o=r[t];return void 0!==o?o:(r[t]=We(e.ownerDocument,t),e.appendChild(r[t]),n[t]=Object.create(null),r[t])},u=function(){var e="";for(var t in r)e+=r[t].data;return e};return{clone:function(){throw new ye(5)},css:u,getIds:He(r),hasNameForId:je(n),insertMarker:a,insertRules:function(e,r,u){for(var l=a(e),s=[],c=r.length,f=0;f0&&(i=!0,t().insertRules(e+"-import",s))},removeRules:function(a){var u=r[a];if(void 0!==u){var l=We(e.ownerDocument,a);e.replaceChild(l,u),r[a]=l,Ie(n,a),o&&i&&t().removeRules(a+"-import")}},sealed:!1,styleTag:e,toElement:Be(u,n),toHTML:$e(u,n)}}(i,o):function(e,t){var n=Object.create(null),r=Object.create(null),o=[],i=void 0!==t,a=!1,u=function(e){var t=r[e];return void 0!==t?t:(r[e]=o.length,o.push(0),Ie(n,e),r[e])},l=function(){var t=ze(e).cssRules,n="";for(var i in r){n+=Ue(i);for(var a=r[i],u=Ve(o,a),l=u-o[a];l0&&(a=!0,t().insertRules(r+"-import",h)),o[c]+=p,De(n,r,s)},removeRules:function(u){var l=r[u];if(void 0!==l&&!1!==e.isConnected){var s=o[l];!function(e,t,n){for(var r=t-n,o=t;o>r;o-=1)e.deleteRule(o)}(ze(e),Ve(o,l)-1,s),o[l]=0,Ie(n,u),i&&a&&t().removeRules(u+"-import")}},sealed:!1,styleTag:e,toElement:Be(l,n),toHTML:$e(l,n)}}(i,o)}return qe()},Ge=/\s+/,Xe=void 0;Xe=ve?ge?40:1e3:-1;var Ke=0,Qe=void 0,Ze=function(){function e(){var t=this,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:ve?document.head:null,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1];ne(this,e),this.getImportRuleTag=function(){var e=t.importRuleTag;if(void 0!==e)return e;var n=t.tags[0];return t.importRuleTag=Ye(t.target,n?n.styleTag:null,t.forceServer,!0)},Ke+=1,this.id=Ke,this.forceServer=r,this.target=r?null:n,this.tagMap={},this.deferred={},this.rehydratedNames={},this.ignoreRehydratedNames={},this.tags=[],this.capacity=1,this.clones=[]}return e.prototype.rehydrate=function(){if(!ve||this.forceServer)return this;var e=[],t=[],n=!1,r=document.querySelectorAll("style["+pe+"]["+he+'="4.4.0"]'),o=r.length;if(!o)return this;for(var i=0;i0&&void 0!==arguments[0]&&arguments[0]).rehydrate()},e.prototype.clone=function(){var t=new e(this.target,this.forceServer);return this.clones.push(t),t.tags=this.tags.map((function(e){for(var n=e.getIds(),r=e.clone(),o=0;o1?t-1:0),r=1;r2&&void 0!==arguments[2]?arguments[2]:se;if(!(0,B.isValidElementType)(t))throw new ye(1,String(t));var r=function(){return e(t,n,at.apply(void 0,arguments))};return r.withConfig=function(r){return ut(e,t,oe({},n,r))},r.attrs=function(r){return ut(e,t,oe({},n,{attrs:Array.prototype.concat(n.attrs,r).filter(Boolean)}))},r}function lt(e){for(var t,n=0|e.length,r=0|n,o=0;n>=4;)t=1540483477*(65535&(t=255&e.charCodeAt(o)|(255&e.charCodeAt(++o))<<8|(255&e.charCodeAt(++o))<<16|(255&e.charCodeAt(++o))<<24))+((1540483477*(t>>>16)&65535)<<16),r=1540483477*(65535&r)+((1540483477*(r>>>16)&65535)<<16)^(t=1540483477*(65535&(t^=t>>>24))+((1540483477*(t>>>16)&65535)<<16)),n-=4,++o;switch(n){case 3:r^=(255&e.charCodeAt(o+2))<<16;case 2:r^=(255&e.charCodeAt(o+1))<<8;case 1:r=1540483477*(65535&(r^=255&e.charCodeAt(o)))+((1540483477*(r>>>16)&65535)<<16)}return((r=1540483477*(65535&(r^=r>>>13))+((1540483477*(r>>>16)&65535)<<16))^r>>>15)>>>0}var st=52,ct=function(e){return String.fromCharCode(e+(e>25?39:97))};function ft(e){var t="",n=void 0;for(n=e;n>st;n=Math.floor(n/st))t=ct(n%st)+t;return ct(n%st)+t}function dt(e,t){for(var n=0;n2&&void 0!==arguments[2]?arguments[2]:se,r=!!n&&e.theme===n.theme;return e.theme&&!r?e.theme:t||n.theme},gt=/[[\].#*$><+~=|^:(),"'`-]+/g,yt=/(^-|-$)/g;function bt(e){return e.replace(gt,"-").replace(yt,"")}function wt(e){return"string"===typeof e&&!0}var xt={childContextTypes:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDerivedStateFromProps:!0,propTypes:!0,type:!0},Et={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},kt=((pt={})[B.ForwardRef]={$$typeof:!0,render:!0},pt),St=Object.defineProperty,Ct=Object.getOwnPropertyNames,Tt=Object.getOwnPropertySymbols,Pt=void 0===Tt?function(){return[]}:Tt,Ot=Object.getOwnPropertyDescriptor,_t=Object.getPrototypeOf,At=Object.prototype,Rt=Array.prototype;function Nt(e,t,n){if("string"!==typeof t){var r=_t(t);r&&r!==At&&Nt(e,r,n);for(var o=Rt.concat(Ct(t),Pt(t)),i=kt[e.$$typeof]||xt,a=kt[t.$$typeof]||xt,u=o.length,l=void 0,s=void 0;u--;)if(s=o[u],!Et[s]&&(!n||!n[s])&&(!a||!a[s])&&(!i||!i[s])&&(l=Ot(t,s)))try{St(e,s,l)}catch(c){}return e}return e}var Mt=(0,j.createContext)(),Dt=Mt.Consumer,It=(function(e){function t(n){ne(this,t);var r=ae(this,e.call(this,n));return r.getContext=W(r.getContext.bind(r)),r.renderInner=r.renderInner.bind(r),r}ie(t,e),t.prototype.render=function(){return this.props.children?L().createElement(Mt.Consumer,null,this.renderInner):null},t.prototype.renderInner=function(e){var t=this.getContext(this.props.theme,e);return L().createElement(Mt.Provider,{value:t},this.props.children)},t.prototype.getTheme=function(e,t){if(ce(e))return e(t);if(null===e||Array.isArray(e)||"object"!==("undefined"===typeof e?"undefined":te(e)))throw new ye(8);return oe({},t,e)},t.prototype.getContext=function(e,t){return this.getTheme(e,t)}}(j.Component),function(){function e(){ne(this,e),this.masterSheet=Ze.master,this.instance=this.masterSheet.clone(),this.sealed=!1}e.prototype.seal=function(){if(!this.sealed){var e=this.masterSheet.clones.indexOf(this.instance);this.masterSheet.clones.splice(e,1),this.sealed=!0}},e.prototype.collectStyles=function(e){if(this.sealed)throw new ye(2);return L().createElement(Lt,{sheet:this.instance},e)},e.prototype.getStyleTags=function(){return this.seal(),this.instance.toHTML()},e.prototype.getStyleElement=function(){return this.seal(),this.instance.toReactElements()},e.prototype.interleaveWithNodeStream=function(e){throw new ye(3)}}(),(0,j.createContext)()),jt=It.Consumer,Lt=function(e){function t(n){ne(this,t);var r=ae(this,e.call(this,n));return r.getContext=W(r.getContext),r}return ie(t,e),t.prototype.getContext=function(e,t){if(e)return e;if(t)return new Ze(t);throw new ye(4)},t.prototype.render=function(){var e=this.props,t=e.children,n=e.sheet,r=e.target;return L().createElement(It.Provider,{value:this.getContext(n,r)},t)},t}(j.Component),zt={};var Ft=function(e){function t(){ne(this,t);var n=ae(this,e.call(this));return n.attrs={},n.renderOuter=n.renderOuter.bind(n),n.renderInner=n.renderInner.bind(n),n}return ie(t,e),t.prototype.render=function(){return L().createElement(jt,null,this.renderOuter)},t.prototype.renderOuter=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Ze.master;return this.styleSheet=e,this.props.forwardedComponent.componentStyle.isStatic?this.renderInner():L().createElement(Dt,null,this.renderInner)},t.prototype.renderInner=function(e){var t=this.props.forwardedComponent,n=t.componentStyle,r=t.defaultProps,o=(t.displayName,t.foldedComponentIds),i=t.styledComponentId,a=t.target,u=(t.usesTheme,void 0),l=void 0;n.isStatic?u=this.generateAndInjectStyles(se,this.props):(l=vt(this.props,e,r),u=this.generateAndInjectStyles(l||se,this.props));var s=this.props.as||this.attrs.as||a,c=wt(s),f={},d=oe({},this.props,this.attrs),p=void 0;for(p in d)"forwardedComponent"!==p&&"as"!==p&&("forwardedRef"===p?f.ref=d[p]:"forwardedAs"===p?f.as=d[p]:c&&!(0,q.A)(p)||(f[p]=d[p]));return this.props.style&&this.attrs.style&&(f.style=oe({},this.attrs.style,this.props.style)),f.className=Array.prototype.concat(o,i,u!==i?u:null,this.props.className,this.attrs.className).filter(Boolean).join(" "),(0,j.createElement)(s,f)},t.prototype.buildExecutionContext=function(e,t,n){var r=this,o=oe({},t,{theme:e});return n.length?(this.attrs={},n.forEach((function(e){var t,n=e,i=!1,a=void 0,u=void 0;for(u in ce(n)&&(n=n(o),i=!0),n)a=n[u],i||!ce(a)||(t=a)&&t.prototype&&t.prototype.isReactComponent||de(a)||(a=a(o)),r.attrs[u]=a,o[u]=a})),o):o},t.prototype.generateAndInjectStyles=function(e,t){var n=t.forwardedComponent,r=n.attrs,o=n.componentStyle;n.warnTooManyClasses;return o.isStatic&&!r.length?o.generateAndInjectStyles(se,this.styleSheet):o.generateAndInjectStyles(this.buildExecutionContext(e,t,r),this.styleSheet)},t}(j.Component);function Ut(e,t,n){var r=de(e),o=!wt(e),i=t.displayName,a=void 0===i?function(e){return wt(e)?"styled."+e:"Styled("+fe(e)+")"}(e):i,u=t.componentId,l=void 0===u?function(e,t,n){var r="string"!==typeof t?"sc":bt(t),o=(zt[r]||0)+1;zt[r]=o;var i=r+"-"+e.generateName(r+o);return n?n+"-"+i:i}(mt,t.displayName,t.parentComponentId):u,s=t.ParentComponent,c=void 0===s?Ft:s,f=t.attrs,d=void 0===f?le:f,p=t.displayName&&t.componentId?bt(t.displayName)+"-"+t.componentId:t.componentId||l,h=r&&e.attrs?Array.prototype.concat(e.attrs,d).filter(Boolean):d,m=new mt(r?e.componentStyle.rules.concat(n):n,h,p),v=void 0,g=function(e,t){return L().createElement(c,oe({},e,{forwardedComponent:v,forwardedRef:t}))};return g.displayName=a,(v=L().forwardRef(g)).displayName=a,v.attrs=h,v.componentStyle=m,v.foldedComponentIds=r?Array.prototype.concat(e.foldedComponentIds,e.styledComponentId):le,v.styledComponentId=p,v.target=r?e.target:e,v.withComponent=function(e){var r=t.componentId,o=function(e,t){var n={};for(var r in e)t.indexOf(r)>=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}(t,["componentId"]),i=r&&r+"-"+(wt(e)?e:bt(fe(e)));return Ut(e,oe({},o,{attrs:h,componentId:i,ParentComponent:c}),n)},Object.defineProperty(v,"defaultProps",{get:function(){return this._foldedDefaultProps},set:function(t){this._foldedDefaultProps=r?J(e.defaultProps,t):t}}),v.toString=function(){return"."+v.styledComponentId},o&&Nt(v,e,{attrs:!0,componentStyle:!0,displayName:!0,foldedComponentIds:!0,styledComponentId:!0,target:!0,withComponent:!0}),v}var Vt=function(e){return ut(Ut,e)};["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","big","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","keygen","label","legend","li","link","main","map","mark","marquee","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr","circle","clipPath","defs","ellipse","foreignObject","g","image","line","linearGradient","marker","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","svg","text","tspan"].forEach((function(e){Vt[e]=Vt(e)}));!function(){function e(t,n){ne(this,e),this.rules=t,this.componentId=n,this.isStatic=dt(t,le),Ze.master.hasId(n)||Ze.master.deferredInject(n,[])}e.prototype.createStyles=function(e,t){var n=Ne(it(this.rules,e,t),"");t.inject(this.componentId,n)},e.prototype.removeStyles=function(e){var t=this.componentId;e.hasId(t)&&e.remove(t)},e.prototype.renderStyles=function(e,t){this.removeStyles(t),this.createStyles(e,t)}}();ve&&(window.scCGSHMRCache={});const $t=Vt;var Bt=n(478);const Ht=$t.div` + height: 8px; + width: 8px; + border-radius: 100%; + + background: ${e=>e.active?"#40EC00":"#434343"}; + background-image: linear-gradient( + 180deg, + rgba(255, 255, 255, 0.5) 0%, + rgba(255, 255, 255, 0.02) 100% + ); + box-shadow: ${e=>e.active?"0 -1px 0 0 rgba(0,0,0,0.08), 0 1px 0 0 rgba(255,255,255,0.08), 0 0 10px 0 #40EC00, inset 0 -2px 4px 0 rgba(21,76,9,0.50), inset 0 2px 4px 0 rgba(212,255,170,0.50)":" 0 -1px 0 0 rgba(0,0,0,0.08), 0 1px 0 0 rgba(255,255,255,0.08), 0 0 10px 0 rgba(64,236,0,0.00), inset 0 -2px 4px 0 rgba(0,0,0,0.42), inset 0 2px 4px 0 rgba(51,51,51,0.50)"}; + + transition: all 0.1s; +`,Wt=$t.div` + display: flex; + flex-direction: column; + align-items: center; + flex: 1; + justify-content: space-around; +`,qt=$t.div` + box-shadow: inset 0 1px 0 0 rgba(0, 0, 0, 0.5), + inset 0 -1px 0 0 rgba(255, 255, 255, 0.16); + border-radius: 15px; + height: 24px; + width: 48px; + overflow: auto; + cursor: pointer; + transition: all 0.2s; +`,Yt=$t.div` + height: 20px; + width: 20px; + border-radius: 100%; + margin: 2px; + transition: all 0.3s; + + background-image: linear-gradient( + 180deg, + #4d4d4d 0%, + #393939 42%, + #1c1c1c 99% + ); + box-shadow: 0 5px 3px 0 rgba(0, 0, 0, 0.19), 0 8px 7px 0 rgba(0, 0, 0, 0.5), + inset 0 -1px 0 0 rgba(0, 0, 0, 0.5), + inset 0 1px 0 0 rgba(255, 255, 255, 0.16); +`;class Gt extends L().Component{constructor(e){super(e),this.state={}}toggle(){const{value:e}=this.props;this.props.setPower(!e)}componentDidUpdate(e){const{value:t}=this.props;if(e.value!==t){new Audio("./sounds/switch.mp3").play()}}render(){const{value:e}=this.props;return L().createElement(Wt,null,L().createElement(Ht,{active:e}),L().createElement(qt,{style:{background:e?"#aaa":"#111"},onClick:this.toggle.bind(this),active:e},L().createElement(Yt,{style:{marginLeft:e?26:2}})))}}Gt.defaultProps={value:!0};const Xt=(0,Bt.Ng)(null,(e=>(0,R.zH)({setPower:S},e)))(Gt);var Kt=function(){return Kt=Object.assign||function(e){for(var t,n=1,r=arguments.length;n4?(t=e.substr(1,2),n=e.substr(3,2),r=e.substr(5,2)):(t=e.substr(1,1),n=e.substr(2,1),r=e.substr(3,1),t+=t,n+=n,r+=r),{red:parseInt(t,16),green:parseInt(n,16),blue:parseInt(r,16),alpha:1}}}),Wn={test:function(e){return"string"===typeof e&&Cn.test(e)||Ln(e)||zn(e)},parse:function(e){return $n.test(e)?$n.parse(e):Bn.test(e)?Bn.parse(e):Hn.test(e)?Hn.parse(e):e},transform:function(e){return Ln(e)?$n.transform(e):zn(e)?Bn.transform(e):e}},qn="${c}",Yn="${n}",Gn=function(e){return"number"===typeof e?0:e},Xn={test:function(e){if("string"!==typeof e||!isNaN(e))return!1;var t=0,n=e.match(kn),r=e.match(Sn);return n&&(t+=n.length),r&&(t+=r.length),t>0},parse:function(e){var t=e,n=[],r=t.match(Sn);r&&(t=t.replace(Sn,qn),n.push.apply(n,r.map(Wn.parse)));var o=t.match(kn);return o&&n.push.apply(n,o.map(Tn.parse)),n},createTransformer:function(e){var t=e,n=0,r=e.match(Sn),o=r?r.length:0;if(r)for(var i=0;i=kr?function(t,r){for(var o=0,i=0;o0?o=a:r=a}while(Math.abs(i)>Sr&&++u=o.numNumbers,"Complex values '"+e+"' and '"+t+"' too different to mix. Ensure all colors are of the same type."),Zr(eo(r.parsed,o.parsed),n)},oo=function(e,t){return function(n){return Hr(e,t,n)}};function io(e,t,n){for(var r,o=[],i=n||("number"===typeof(r=e[0])?oo:"string"===typeof r?Wn.test(r)?Kr:ro:Array.isArray(r)?eo:"object"===typeof r?to:void 0),a=e.length-1,u=0;ue[l-1]&&(e=[].concat(e),t=[].concat(t),e.reverse(),t.reverse());var s=io(t,a,u),c=2===l?function(e,t){var n=e[0],r=e[1],o=t[0];return function(e){return o(Br(n,r,e))}}(e,s):function(e,t){var n=e.length,r=n-1;return function(o){var i=0,a=!1;if(o<=e[0]?a=!0:o>=e[r]&&(i=r-1,a=!0),!a){for(var u=1;uo||u===r);u++);i=u-1}var l=Br(e[i],e[i+1],o);return t[i](l)}}(e,s);return i?Zr(zr(e[0],e[l-1]),c):c}var uo=function(e){return e},lo=function(e){return void 0===e&&(e=uo),Lr((function(t,n,r){var o=n-r,i=-(0-t+1)*(0-e(Math.abs(o)));return o<=0?n+i:n-i}))},so=(lo(),lo(Math.sqrt),function(e,t){return t?e*(1e3/t):0}),co=(Lr((function(e,t,n){var r=t-e;return((n-e)%r+r)%r+e})),zr(0,1),function(){return co=Object.assign||function(e){for(var t,n=1,r=arguments.length;np||o<-p;r(i?y+o:y),i||(hn.update(b),n())}),!0);return{stop:function(){return hn.update(b)}}}))},gi=hi(vi,{from:Tn.test,modifyTarget:function(e){return"function"===typeof e},velocity:Tn.test}),yi=function(e){return void 0===e&&(e={}),ai((function(t){var n=t.update,r=t.complete,o=e.velocity,i=void 0===o?0:o,a=e.from,u=void 0===a?0:a,l=e.to,s=void 0===l?0:l,c=e.stiffness,f=void 0===c?100:c,d=e.damping,p=void 0===d?10:d,h=e.mass,m=void 0===h?1:h,v=e.restSpeed,g=void 0===v?.01:v,y=e.restDelta,b=void 0===y?.01:y,w=i?-i/1e3:0,x=0,E=s-u,k=u,S=k,C=bn.update((function(e){var t=e.delta;x+=t;var o=p/(2*Math.sqrt(f*m)),a=Math.sqrt(f/m)/1e3;if(S=k,o<1){var u=Math.exp(-o*a*x),l=a*Math.sqrt(1-o*o);k=s-u*((w+o*a*E)/l*Math.sin(l*x)+E*Math.cos(l*x))}else{u=Math.exp(-a*x);k=s-u*(E+(w+a*E)*x)}i=so(k-S,t);var c=Math.abs(i)<=g,d=Math.abs(s-k)<=b;c&&d?(n(k=s),hn.update(C),r()):n(k)}),!0);return{stop:function(){return hn.update(C)}}}))},bi=hi(yi,{from:Tn.test,to:Tn.test,stiffness:Tn.test,damping:Tn.test,mass:Tn.test,velocity:Tn.test}),wi=function(e){var t=e.from,n=void 0===t?0:t,r=e.velocity,o=void 0===r?0:r,i=e.min,a=e.max,u=e.power,l=void 0===u?.8:u,s=e.timeConstant,c=void 0===s?700:s,f=e.bounceStiffness,d=void 0===f?500:f,p=e.bounceDamping,h=void 0===p?10:p,m=e.restDelta,v=void 0===m?1:m,g=e.modifyTarget;return ai((function(e){var t,r=e.update,u=e.complete,s=n,f=n,p=!1,m=function(e){return void 0!==i&&e<=i},y=function(e){return void 0!==a&&e>=a},b=function(e){return m(e)||y(e)},w=function(e){r(e),s=f,o=so((f=e)-s,yn().delta),t&&!p&&function(e,t){return m(e)&&t<0||y(e)&&t>0}(e,o)&&E({from:e,velocity:o})},x=function(e,n){t&&t.stop(),t=e.start({update:w,complete:function(){n?n():u()}})},E=function(e){p=!0,x(bi(Kt({},e,{to:m(e.from)?i:a,stiffness:d,damping:h,restDelta:v})))};if(b(n))E({from:n,velocity:o});else if(0!==o){var k=gi({from:n,velocity:o,timeConstant:c,power:l,restDelta:b(n)?20:v,modifyTarget:g});x(k,(function(){b(f)?E({from:f,velocity:o}):u()}))}else u();return{stop:function(){return t&&t.stop()}}}))},xi=hi(wi,{from:Tn.test,velocity:Tn.test,min:Tn.test,max:Tn.test,damping:Tn.test,stiffness:Tn.test,modifyTarget:function(e){return"function"===typeof e}}),Ei=function(e){var t=e.from,n=void 0===t?0:t,r=e.to,o=void 0===r?1:r,i=e.ease,a=void 0===i?rr:i,u=e.reverseEase;return void 0!==u&&u&&(a=Zn(a)),ai((function(e){var t=e.update;return{seek:function(e){return t(e)}}})).pipe(a,(function(e){return Hr(n,o,e)}))},ki=hi(Ei,{ease:function(e){return"function"===typeof e},from:Tn.test,to:Tn.test}),Si=zr(0,1),Ci=function(e){return void 0===e&&(e={}),ai((function(t){var n,r=t.update,o=t.complete,i=e.duration,a=void 0===i?300:i,u=e.ease,l=void 0===u?ir:u,s=e.flip,c=void 0===s?0:s,f=e.loop,d=void 0===f?0:f,p=e.yoyo,h=void 0===p?0:p,m=e.repeatDelay,v=void 0===m?0:m,g=e.from,y=void 0===g?0:g,b=e.to,w=void 0===b?1:b,x=e.elapsed,E=void 0===x?0:x,k=e.flipCount,S=void 0===k?0:k,C=e.yoyoCount,T=void 0===C?0:C,P=e.loopCount,O=void 0===P?0:P,_=ki({from:y,to:w,ease:l}).start(r),A=0,R=!1,N=function(e){var t;void 0===e&&(e=!1),_=ki({from:y=(t=[w,y])[0],to:w=t[1],ease:l,reverseEase:e}).start(r)},M=function(){A=Si(Br(0,a,E)),_.seek(A)},D=function(){R=!0,n=bn.update((function(e){var t=e.delta;E+=t,M(),function(){var e=R&&E>a+v;return!!e&&(!(!e||d||c||h)||(E=E-a-v,d&&O=e[o]&&a[i].seek(1);for(var n=1;nt||n===o);n++);var u=Br(e[n-1],e[n],t);a[n-1].seek(Ti(u))}}(o,u,e)}))},Oi=function(e,t,n){return ai((function(r){var o=r.update,i=t.split(" ").map((function(t){return e.addEventListener(t,o,n),t}));return{stop:function(){return i.forEach((function(t){return e.removeEventListener(t,o,n)}))}}}))},_i=function(){return{clientX:0,clientY:0,pageX:0,pageY:0,x:0,y:0}},Ai=function(e,t){return void 0===t&&(t={clientX:0,clientY:0,pageX:0,pageY:0,x:0,y:0}),t.clientX=t.x=e.clientX,t.clientY=t.y=e.clientY,t.pageX=e.pageX,t.pageY=e.pageY,t},Ri=[_i()];if("undefined"!==typeof document){Oi(document,"touchstart touchmove",{passive:!0,capture:!0}).start((function(e){var t=e.touches;!0;var n=t.length;Ri.length=0;for(var r=0;r=0&&(o=n[r],!(i.timestamp-o.timestamp>ma(t)));)r--;if(!o)return{x:0,y:0};var a=(i.timestamp-o.timestamp)/1e3;if(0===a)return{x:0,y:0};var u={x:(i.x-o.x)/a,y:(i.y-o.y)/a};return u.x===1/0&&(u.x=0),u.y===1/0&&(u.y=0),u}function eu(e,t){var n=e.onPan,r=e.onPanStart,o=e.onPanEnd,i=e.onPanSessionStart,a=n||r||o||i,u=(0,j.useRef)(null),l=(0,j.useRef)(null),s=(0,j.useRef)(null),c=(0,j.useContext)(Ra).transformPagePoint,f=(0,j.useRef)(null),d=(0,j.useRef)({}).current;function p(){f.current&&f.current(),f.current=null}function h(e){var t=e.point,n=u.current;return{point:t,delta:Oa.subtract(t,Za(n)),offset:Oa.subtract(t,Qa(n)),velocity:Ja(n,.1)}}function m(e){return{point:c(e.point)}}function v(){p(),hn.update(g),Ma()}function g(){if(!u.current||!l.current||!s.current)return Zt(!1,"onPointerMove fired without pointer session"),void v();var e=h(s.current),t=void 0!==u.current.startEvent,n=$r(e.offset,{x:0,y:0})>=3;if(t||n){var r=e.point,o=yn().timestamp;u.current.pointHistory.push(Kt({},r,{timestamp:o})),t||(d.onPanStart&&d.onPanStart(l.current,e),u.current.startEvent=l.current),d.onPan&&d.onPan(l.current,e)}}function y(e,t){l.current=e,s.current=m(t),Da(e)&&0===e.buttons?b(e,t):bn.update(g,!0)}function b(e,t){v(),u.current?(d.onPanEnd&&d.onPanEnd(e,h(m(t))),u.current=null):Zt(!1,"onPointerUp fired without pointer session")}d.onPanSessionStart=i,d.onPanStart=r,d.onPan=n,d.onPanEnd=o,Ka(t,"pointerdown",a&&function(e,t){if(!(Ia(e)&&e.touches.length>1)){var n=m(t),r=n.point,o=yn().timestamp;u.current={target:e.target,pointHistory:[Kt({},r,{timestamp:o})]},d.onPanSessionStart&&d.onPanSessionStart(e,h(n)),p();var i=Xa(window,"pointermove",y),a=Xa(window,"pointerup",b);f.current=function(){i&&i(),a&&a()}}}),ja(v)}var tu=function(e,t){return!!t&&(e===t||tu(e,t.parentElement))},nu=["whileHover","whileTap","whileDrag"],ru=function(e){return nu.indexOf(e)+1};function ou(e){var t=null;return function(){return null===t&&(t=e,function(){t=null})}}var iu=ou("dragHorizontal"),au=ou("dragVertical");function uu(e){var t=!1;if("y"===e)t=au();else if("x"===e)t=iu();else{var n=iu(),r=au();n&&r?t=function(){n(),r()}:(n&&n(),r&&r())}return t}var lu=ru("whileTap");var su=ru("whileHover"),cu=function(e){return function(t,n){Da(t)&&e(t,n)}};function fu(e,t){eu(e,t),function(e,t){var n=e.onTap,r=e.onTapStart,o=e.onTapCancel,i=e.whileTap,a=e.controls,u=n||r||o||i,l=(0,j.useRef)(!1),s=(0,j.useRef)(null);function c(){s.current&&s.current(),s.current=null}i&&a&&a.setOverride(i,lu);var f=(0,j.useRef)(null);f.current=function(e,r){var u=t.current;if(c(),l.current&&u){l.current=!1,a&&i&&a.clearOverride(lu);var s=uu(!0);s&&(s(),tu(u,e.target)?n&&n(e,r):o&&o(e,r))}},Ka(t,"pointerdown",u?function(e,n){c(),s.current=Xa(window,"pointerup",(function(e,t){return f.current(e,t)})),t.current&&!l.current&&(l.current=!0,r&&r(e,n),a&&i&&a.startOverride(lu))}:void 0),ja(c)}(e,t),function(e,t){var n=e.whileHover,r=e.onHoverStart,o=e.onHoverEnd,i=e.controls;n&&i&&i.setOverride(n,su),Ka(t,"pointerenter",cu((function(e,t){r&&r(e,t),n&&i&&i.startOverride(su)}))),Ka(t,"pointerleave",cu((function(e,t){o&&o(e,t),n&&i&&i.clearOverride(su)})))}(e,t)}var du=function(e){return function(t){return e(t),null}},pu=["drag","onPan","onPanStart","onPanEnd","onPanSessionStart","onTap","onTapStart","onTapCancel","whileTap","whileHover","onHoverStart","onHoverEnd"],hu={key:"gestures",shouldRender:function(e){return pu.some((function(t){return e.hasOwnProperty(t)}))},Component:du((function(e){var t=e.innerRef;fu(Qt(e,["innerRef"]),t)}))},mu=function(e){return"object"===typeof e&&e.hasOwnProperty("current")};function vu(e){return ji((function(){return Ii(e)}))}var gu=new Set(["INPUT","TEXTAREA","SELECT"]),yu=function(e,t){var n=e.current.getBoundingClientRect(),r=t({x:n.left,y:n.top}),o=r.x,i=r.y,a=t({x:n.width,y:n.height});return{left:o,top:i,width:a.x,height:a.y}},bu=function(e){return e?e.get():0},wu=function(e,t,n,r){Jt(null!==e.current&&null!==t.current,"If `dragConstraints` is set as a React ref, that ref must be passed to another component's `ref` prop.");var o=yu(e,r),i=yu(t,r),a=o.left-i.left+bu(n.x),u=o.top-i.top+bu(n.y);return{top:u,left:a,right:o.width-i.width+a,bottom:o.height-i.height+u}};function xu(e,t,n){return(!0===t||t===e)&&(null===n||n===e)}var Eu=function(e,t){var n=t.top,r=t.right,o=t.bottom,i=t.left;return"x"===e?{min:i,max:r}:{min:n,max:o}};function ku(e,t,n,r){var o=t instanceof Di?t.get():t;if(!n)return o;var i=Eu(e,n),a=i.min,u=i.max;return void 0!==a&&ou&&(o=r?Su(u,o,r):Math.min(u,o)),t instanceof Di&&t.set(o),o}function Su(e,t,n){return Hr(e,t,"number"===typeof n?n:.35)}function Cu(e){return[e("x"),e("y")]}function Tu(e,t,n,r){var o=e.drag,i=void 0!==o&&o,a=e.dragDirectionLock,u=void 0!==a&&a,l=e.dragPropagation,s=void 0!==l&&l,c=e.dragConstraints,f=void 0!==c&&c,d=e.dragElastic,p=void 0===d||d,h=e.dragMomentum,m=void 0===h||h,v=e._dragValueX,g=e._dragValueY,y=e._dragTransitionControls,b=e.dragOriginX,w=e.dragOriginY,x=e.dragTransition,E=e.onDirectionLock,k=e.onDragStart,S=e.onDrag,C=e.onDragEnd,T=e.onDragTransitionEnd,P=mu(f),O=(0,j.useRef)({isDragging:!1,currentDirection:null,constraints:!1,handlers:{}}).current,_=O.handlers;_.onDragStart=k,_.onDrag=S,_.onDragEnd=C,_.onDirectionLock=E,_.onDragTransitionEnd=T;var A,R,N=(0,j.useRef)({}).current,M=vu(0),D=vu(0),I={x:b||M,y:w||D},L=(0,j.useRef)(null),z=(0,j.useContext)(Ra).transformPagePoint,F=(0,j.useRef)({width:0,height:0,x:0,y:0}).current,U=function(){if(mu(f)){var e=yu(f,z),n=yu(t,z),r=function(t,r){var o=N[t];if(o){if(o.isAnimating())return o.stop(),void V();var i=F[r]?(e[r]-n[r])/F[r]:1;o.set(F[t]*i)}};r("x","width"),r("y","height")}};A=f,R=U,(0,j.useEffect)((function(){if(A&&mu(A))return window.addEventListener("resize",R),function(){return window.removeEventListener("resize",R)}}),[A,R]);var V=function(e){if(e){var t=e.right,n=e.left,r=e.bottom,o=e.top;F.width=(t||0)-(n||0),F.height=(r||0)-(o||0)}N.x&&(F.x=N.x.get()),N.y&&(F.y=N.y.get())},$=function(e){return Cu((function(t){var n=N[t];n&&!n.isAnimating()&&ku(t,n,e,0)}))};function B(e){return Kt({},e,{point:{x:N.x?N.x.get():0,y:N.y?N.y.get():0}})}function H(e,t){var n=N[e];if(xu(e,i,O.currentDirection)&&n){var r=ku(e,I[e].get()+t[e],O.constraints,p);n.set(r)}}function W(){Ma(),O.isDragging=!1,!s&&L.current&&(L.current(),L.current=null)}(0,j.useEffect)((function(){if(P){var e=wu(f,t,N,z);$(e),V(e)}}),[]),O.constraints=P?O.constraints||!1:f,Cu((function(e){if(xu(e,i,O.currentDirection)){var t="x"===e?v:g;N[e]=t||n.get(e,0)}})),O.isDragging||!O.constraints||P||$(O.constraints),eu(i?{onPan:function(e,t){if(s||L.current){var n=t.offset;if(u&&null===O.currentDirection){if(O.currentDirection=function(e,t){void 0===t&&(t=10);var n=null;Math.abs(e.y)>t?n="y":Math.abs(e.x)>t&&(n="x");return n}(n),null!==O.currentDirection){var r=_.onDirectionLock;r&&r(O.currentDirection)}}else{H("x",n),H("y",n);var o=_.onDrag;o&&o(e,B(t))}}},onPanStart:function(e,n){if(O.isDragging=!0,P&&(O.constraints=wu(f,t,N,z),$(O.constraints)),Cu((function(e){var t=N[e];t&&(I[e].set(t.get()),t.stop())})),s||(L.current&&L.current(),L.current=uu(i),L.current)){O.currentDirection=null;var r=_.onDragStart;r&&r(e,B(n))}},onPanEnd:function(e,t){var n=O.isDragging;if(W(),n){if(m||p)!function(e){var t=Cu((function(t){var n;if(xu(t,i,O.currentDirection)){var o=O.constraints?Eu(t,O.constraints):{},a=p?200:1e6,u=p?40:1e7;return(y||r).start(((n={})[t]=0,n.transition=Kt({type:"inertia",velocity:m?e[t]:0,bounceStiffness:a,bounceDamping:u,timeConstant:750,restDelta:1},x,o),n))}}));Promise.all(t).then((function(){V(O.constraints),U();var e=_.onDragTransitionEnd;e&&e()}))}(t.velocity);else V(O.constraints);var o=_.onDragEnd;o&&o(e,B(t))}},onPanSessionStart:function(e){e.target&&!gu.has(e.target.tagName)&&(e.preventDefault(),document.activeElement instanceof HTMLElement&&document.activeElement.blur()),Na=!0,Cu((function(e){var t=N[e];t&&t.stop()}))}}:{},t),ja((function(){return O.isDragging&&W()}))}var Pu={key:"drag",shouldRender:function(e){return!!e.drag},Component:du((function(e){var t=e.innerRef,n=e.values,r=e.controls;return Tu(Qt(e,["innerRef","values","controls"]),t,n,r)}))};function Ou(e){return"string"===typeof e&&e.startsWith("var(--")}var _u=/var\((--[a-zA-Z0-9-_]+),? ?([a-zA-Z0-9 ()%#.,-]+)?\)/;var Au=4;function Ru(e,t,n){void 0===n&&(n=1),Jt(n<=Au,'Max CSS variable fallback depth detected in property "'+e+'". This may indicate a circular fallback dependency.');var r=function(e){var t=_u.exec(e);return t?[t[1],t[2]]:[,]}(e),o=r[0],i=r[1];if(o){var a=window.getComputedStyle(t).getPropertyValue(o);return a||(Ou(i)?Ru(i,t,n+1):i)}}var Nu,Mu=new Set(["width","height","top","left","right","bottom","x","y"]),Du=function(e){return Mu.has(e)},Iu=function(e,t){e.set(t,!1),e.set(t)},ju=function(e){return e===Tn||e===Nn};!function(e){e.width="width",e.height="height",e.left="left",e.right="right",e.top="top",e.bottom="bottom"}(Nu||(Nu={}));var Lu=function(e,t){return parseFloat(e.split(", ")[t])},zu=function(e,t){return function(n,r){var o=r.transform;if("none"===o||!o)return 0;var i=o.match(/^matrix3d\((.+)\)$/);if(i)return Lu(i[1],t);var a=o.match(/^matrix\((.+)\)$/);return Lu(a[1],e)}},Fu=new Set(["x","y","z"]),Uu=Co.filter((function(e){return!Fu.has(e)}));var Vu={width:function(e){return e.width},height:function(e){return e.height},top:function(e,t){var n=t.top;return parseFloat(n)},left:function(e,t){var n=t.left;return parseFloat(n)},bottom:function(e,t){var n=e.height,r=t.top;return parseFloat(r)+n},right:function(e,t){var n=e.width,r=t.left;return parseFloat(r)+n},x:zu(4,13),y:zu(5,14)},$u=function(e,t,n,r){void 0===r&&(r={}),n=Kt({},n),r=Kt({},r);var o=t.current,i=ni(o),a=Object.keys(n).filter(Du),u=[],l=!1,s=a.reduce((function(t,o){var a=e.get(o);if(!a)return t;var s,c=a.get(),f=n[o],d=oa(c);if(Ji(f))for(var p=f.length,h=null===f[0]?1:0;h{},onEndEdit:t=()=>{}}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const n=r=>{t(r),window.removeEventListener("mousemove",e),window.removeEventListener("touchmove",e),window.removeEventListener("mouseup",n),window.removeEventListener("touchend",n)};window.addEventListener("mousemove",e),window.addEventListener("touchmove",e),window.addEventListener("mouseup",n),window.addEventListener("touchend",n)}({onEdit:t=>e.onMouseMove(t),onEndEdit:o=>{e.onMouseUp(o),e.props.onEndGesture(t,n,r)}})}const Nl=$t.div` + position: relative; + margin: 10px 0; +`,Ml=$t.div` + padding: 0 15px; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 8px; +`,Dl=$t.div` + height: 100%; + width: 100%; + display: flex; + justify-content: center; + align-items: flex-end; +`,Il=$t.div` + touch-action: none; + cursor: pointer; + height: ${e=>e.size}px; + width: ${e=>e.size}px; + border-radius: 100%; + background-image: linear-gradient(180deg, #4d4d4d 0%, #1c1c1c 99%); + box-shadow: 0 5px 6px 0 rgba(0, 0, 0, 0.18), 0 22px 22px 0 rgba(0, 0, 0, 0.39), + inset 0 -1px 0 0 rgba(0, 0, 0, 0.5), + inset 0 1px 0 0 rgba(255, 255, 255, 0.16); +`,jl=$t.div` + background-image: linear-gradient(180deg, #1c1c1c 0%, #4d4d4d 99%); + height: 10px; + width: 10px; + border-radius: 100%; + margin: 10px; +`,Ll=$t(Pl.div)` + background: #191919; + box-shadow: 0 12px 33px 0 rgba(0, 0, 0, 0.37); + border-radius: 20px; + height: 40px; + padding: 0 15px; + font-size: 16px; + color: #b0b0b0; + letter-spacing: 1px; + text-align: center; + line-height: 40px; + position: absolute; + margin-left: 50%; + width: auto; + white-space: nowrap; + z-index: 999; + pointer-events: none; +`,zl={hidden:{opacity:0,transform:"translate(-50%, 20px)"},visible:{opacity:1,transform:"translate(-50%, 0px)"}};class Fl extends L().Component{constructor(e){super(e),this.state={rotate:this.getRotation(e.value),dragging:!1}}onKeyDown(e){"Shift"===e.key&&this.setState({freezeValue:this.props.value,freezeRotation:this.getRotation(this.props.value)})}onKeyUp(e){"Shift"===e.key&&this.setState({freezeValue:this.props.value,freezeRotation:this.getRotation(this.props.value)})}componentDidMount(){window.addEventListener("keydown",this.onKeyDown.bind(this)),window.addEventListener("keyup",this.onKeyUp.bind(this))}componentWillUnmount(){}getRotation(e){return this.props.log?this.getRotationLog(e):this.getRotationLin(e)}getRotationLin(e){const{min:t,max:n,minDeg:r,maxDeg:o}=this.props;return r+(e-t)*((o-r)/(n-t))}getRotationLog(e){const{min:t,max:n,minDeg:r,maxDeg:o}=this.props;if(0===e)return r;const i=Math.log(t),a=(Math.log(n)-i)/(o-r);return r+(Math.log(e)-i)/a}onMouseDown(e){Rl(this);const t=e.clientY||e.touches[0].clientY;this.setState({dragStartY:t,dragging:!0,freezeValue:this.props.value,freezeRotation:this.getRotation(this.props.value)})}onMouseUp(e){this.setState({dragging:!1})}getValue(e){return this.props.log?this.getValueLog(e):this.getValueLin(e)}getValueLin(e){const{min:t,max:n,minDeg:r,maxDeg:o}=this.props;return(e-r)*((n-t)/(o-r))+t}getValueLog(e){const{min:t,max:n,minDeg:r,maxDeg:o}=this.props,i=Math.log(t),a=(Math.log(n)-i)/(o-r);return Math.exp((e-r)*a+i)}onMouseMove(e){if(!this.state.dragging)return;const{min:t,max:n,param:r,module:o,moduleIndex:i,degreePerPixel:a}=this.props,u=e.clientY||e.touches[0].clientY;let l=(this.state.dragStartY-u)*a;e.shiftKey&&(l*=.2);let s=this.getValue(this.state.freezeRotation+l);!1!==this.props.snap&&(s=Math.round(s)),s!==this.props.value&&(s>n?s=n:sthis.onDoubleClick(e),onTouchStart:e=>this.onMouseDown(e),onMouseDown:e=>this.onMouseDown(e)},L().createElement(Dl,{style:{transform:`rotate(${this.getRotation(this.props.value)}deg)`}},L().createElement(jl,{style:{transform:`rotate(-${this.getRotation(this.props.value)}deg)`}})))),L().createElement(Al,null,this.props.label),L().createElement(Ll,{initial:"hidden",animate:this.state.dragging?"visible":"hidden",variants:zl,transition:{type:"spring",damping:20,stiffness:300,delay:this.state.dragging?0:1}},this.props.value.toFixed(this.props.decimals)," ",this.props.unit))}}Fl.defaultProps={min:0,max:100,minDeg:40,maxDeg:320,value:50,label:"Pitch",param:"pitch",unit:"",moduleIndex:!1,size:60,decimals:0,snap:!1,log:!1,degreePerPixel:1.5,onBeginGesture:()=>{},onEndGesture:()=>{}};const Ul=(0,Bt.Ng)(null,(e=>({onBeginGesture:function(){return e(E(...arguments))},onEndGesture:function(){return e(k(...arguments))},...(0,R.zH)({setParam:x},e)})))(Fl),Vl=$t.div` + display: flex; + flex-direction: column; + align-items: center; + margin: 20px 0 30px; +`,$l=$t.div` + background: #181818; + box-shadow: inset 0 1px 0 0 rgba(0, 0, 0, 0.5), + inset 0 -1px 0 0 rgba(255, 255, 255, 0.16); + border-radius: 7px; + width: 4px; + height: 100%; + margin: 0 5px; +`,Bl=$t.div` + display: flex; + align-items: ${e=>`flex-${e.align}`}; + flex-direction: column; + height: 100%; + justify-content: space-between; +`,Hl=$t.div` + position: absolute; + top: ${24}px; + bottom: -${24}px; + display: flex; + width: 100%; + align-items: center; + justify-content: center; +`,Wl=$t.div` + background-color: white; + height: 1px; + width: ${e=>"big"===e.size?18:12}px; + opacity: 0.3; +`,ql=$t.div` + position: relative; + height: 100%; + display: flex; + justify-content: center; +`,Yl=$t.div` + width: ${34}px; + width: 100%; + + position: relative; + height: ${e=>e.size}px; + margin-bottom: ${48}px; +`,Gl=$t.div` + background-image: linear-gradient(180deg, #1c1c1c 0%, #4d4d4d 99%); + width: 100%; + height: 2px; + opacity: 0.5; +`,Xl=$t.div` + position: relative; + padding: 5px 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-around; + height: ${48}px; + width: ${34}px; + background-image: linear-gradient(180deg, #1c1c1c 0%, #4d4d4d 99%); + box-shadow: 0 5px 3px 0 rgba(0, 0, 0, 0.19), 0 8px 7px 0 rgba(0, 0, 0, 0.5), + inset 0 -1px 0 0 rgba(0, 0, 0, 0.5), + inset 0 1px 0 0 rgba(255, 255, 255, 0.16); + border-radius: 5px; + z-index: 5; + cursor: pointer; + touch-action: none; +`,Kl=$t.div` + width: 100%; + height: 4px; + background: #bcbcbc; + margin: 5px 0; +`;class Ql extends L().Component{constructor(e){super(e),this.state={dragging:!1},this.defaultValue=e.value}getTransform(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.props.value;const{min:t,max:n,size:r}=this.props;return r-_l(e,[t,n],[0,r])}onMouseDown(e){Rl(this);const t=e.clientY||e.touches[0].clientY;this.setState({dragStartY:t,dragging:!0,freezeValue:this.props.value})}onMouseUp(e){this.setState({dragging:!1})}onMouseMove(e){if(!this.state.dragging)return;const{min:t,max:n,param:r,module:o,moduleIndex:i,size:a}=this.props,u=e.clientY||e.touches[0].clientY,l=this.state.dragStartY-u,s=_l(Math.abs(l),[0,a],[t,n]);let c=this.state.freezeValue+(l<0?-1*s:s);c>n?c=n:c{},onEndGesture:()=>{}};const Zl=(0,Bt.Ng)(null,(e=>({onBeginGesture:function(){return e(E(...arguments))},onEndGesture:function(){return e(k(...arguments))},...(0,R.zH)({setParam:x},e)})))(Ql),Jl="20px",es=$t.div` + display: flex; + height: ${e=>`${e.trackHeight}px`}; + justify-content: center; +`,ts=$t.div` + display: flex; + flex-direction: column; + justify-content: space-between; + margin-left: 10px; +`,ns=$t.div` + cursor: pointer; + height: 100%; + width: ${Jl}; + background: #111111; + box-shadow: inset 0 1px 0 0 rgba(0, 0, 0, 0.5), + inset 0 -1px 0 0 rgba(255, 255, 255, 0.16); + border-radius: 10px; +`,rs=$t.div` + cursor: pointer; + width: ${Jl}; + height: ${Jl}; + border-radius: 100%; + background-image: linear-gradient(180deg, #4d4d4d 0%, #1c1c1c 99%); + box-shadow: 0 5px 3px 0 rgba(0, 0, 0, 0.19), 0 8px 7px 0 rgba(0, 0, 0, 0.5), + inset 0 -1px 0 0 rgba(0, 0, 0, 0.5), + inset 0 1px 0 0 rgba(255, 255, 255, 0.16); + position: relative; + transition: all 0.2s; + touch-action: none; +`,os=$t.div` + cursor: pointer; +`,is={sine:()=>L().createElement("svg",{width:Jl,height:"11px",viewBox:"0 0 20 11",version:"1.1",xmlns:"http://www.w3.org/2000/svg"},L().createElement("g",{id:"Artboard",stroke:"none",strokeWidth:"1",fill:"none",fillRule:"evenodd",strokeLinecap:"round"},L().createElement("path",{d:"M19,5.5 C19,7.985 16.985,10 14.5,10 C12.015,10 10,7.985 10,5.5 C10,3.015 7.985,1 5.5,1 C3.015,1 1,3.015 1,5.5",id:"Stroke-1",stroke:"#C6C6C6"}))),triangle:()=>L().createElement("svg",{width:Jl,height:"11px",viewBox:"0 0 20 11",version:"1.1",xmlns:"http://www.w3.org/2000/svg"},L().createElement("g",{id:"Artboard-Copy-36",stroke:"none",strokeWidth:"1",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"},L().createElement("polyline",{id:"Path-4",stroke:"#C6C6C6",points:"1 10 10 1 19 10"}))),sawtooth:function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return L().createElement("svg",Object.assign({width:Jl,height:"11px",viewBox:"0 0 20 11",version:"1.1",xmlns:"http://www.w3.org/2000/svg"},e),L().createElement("g",{id:"Artboard-Copy-38",stroke:"none",strokeWidth:"1",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"},L().createElement("polyline",{id:"Path-7",stroke:"#C6C6C6",points:"1 10 19 1 19 10"})))},square:()=>L().createElement("svg",{width:Jl,height:"11px",viewBox:"0 0 20 11",version:"1.1",xmlns:"http://www.w3.org/2000/svg"},L().createElement("g",{id:"Artboard-Copy-37",stroke:"none",strokeWidth:"1",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"},L().createElement("polyline",{id:"Path-5-Copy",stroke:"#C6C6C6",points:"1 10 1 1 10 1 10 10 19 10"})))};class as extends L().Component{constructor(e){super(e),this.state={},this.getTrackHeight=()=>20*this.props.shapes.length,this.audio=new Audio("./sounds/switch.mp3")}select(e){const{module:t,moduleIndex:n}=this.props;new Audio("./sounds/switch.mp3").play(),this.props.setParam(t,n,"type",e)}getShapes(){return this.props.shapes.map(((e,t)=>L().createElement(os,{key:`${this.props.moduleIndex}shape_${t}`,onClick:t=>{this.select(e)}},(e=>{const t=is[e];return t?t():"rampdown"===e?is.sawtooth({style:{transform:"scale(-1,1)"}}):void 0})(e))))}getIndex(e){return this.props.shapes.indexOf(e)}onMouseDown(e){Rl(this);const t=e.clientY||e.touches[0].clientY;this.setState({dragStartY:t,dragging:!0,freezeValue:this.props.value})}onMouseMove(e){if(!this.state.dragging)return;const t=e.clientY||e.touches[0].clientY,n=this.state.dragStartY-t,r=this.getTrackHeight()/this.props.shapes.length,o=-1*Math.round(n/r);let i=this.getIndex(this.state.freezeValue)+o;i>-1&&i(e.stopPropagation(),!1),onTouchStart:this.onMouseDown.bind(this),onMouseDown:this.onMouseDown.bind(this),style:{top:this.getIndex(e)*(100/this.props.shapes.length)+"%"}})),L().createElement(ts,null,this.getShapes()))}}as.defaultProps={shapes:["sine","triangle","sawtooth","square"],value:"sine",onBeginGesture:()=>{},onEndGesture:()=>{}};const us=(0,Bt.Ng)((e=>({shapes:e.state.vcoShapes})),(e=>({onBeginGesture:function(){return e(E(...arguments))},onEndGesture:function(){return e(k(...arguments))},...(0,R.zH)({setParam:x},e)})))(as),ls=["#FFFFFF","#E89A0A","#EB420A","#D0227E","#7829D6","#235ED6","#23AC9E","#63BF17"],ss=$t.div` + cursor: pointer; + background: ${e=>e.color}; + box-shadow: ${e=>e.active?" 0 0 0 1px rgba(0,0,0,0.50), 0 1px 2px 0 rgba(0,0,0,0.19), 0 2px 5px 0 rgba(0,0,0,0.50), inset 0 -2px 3px 0 rgba(0,0,0,0.50), inset 0 3px 4px 0 rgba(255,255,255,0.09)":" 0 0 0 1px rgba(0,0,0,0.50), 0 5px 5px 0 rgba(0,0,0,0.19), 0 12px 13px 0 rgba(0,0,0,0.50), inset 0 -2px 3px 0 rgba(0,0,0,0.50), inset 0 3px 4px 0 rgba(255,255,255,0.09)"}; + border-radius: 3px; + transition: all 0.1s ease-out; + height: 44px; + flex: 1; + margin-right: 10px; + position: relative; + z-index: ${e=>e.active?1:5}; + &:last-child { + margin-right: 0; + } + &::before { + transition: all 0.1s ease-out; + content: ""; + position: absolute; + left: 0; + top: 0; + bottom: 0; + right: 0; + background-image: linear-gradient( + 180deg, + rgba(0, 0, 0, 0.16) 0%, + rgba(0, 0, 0, 0.37) 98% + ); + opacity: ${e=>e.active?1:0}; + } + + &::after { + transition: all 0.1s ease-out; + display: block; + + content: ""; + position: absolute; + left: 0; + top: 0; + bottom: 0; + right: 0; + background-image: linear-gradient( + 180deg, + rgba(255, 255, 255, 0.18) 0%, + rgba(255, 255, 255, 0) 100% + ); + opacity: ${e=>e.active?0:1}; + } +`;class cs extends L().Component{constructor(e){super(e),this.state={}}handleClick(){if(this.props.active)return;new Audio("./sounds/button.mp3").play(),this.props.onClick()}render(){const{active:e}=this.props;return L().createElement(ss,{color:ls[this.props.preset],onClick:this.handleClick.bind(this),active:e})}}cs.defaultProps={value:!0};const fs=(0,Bt.Ng)(null,(e=>(0,R.zH)({setPreset:T},e)))(cs),ds=[{general:{octave:0,glide:0},vco:[{pitch:0,gain:1,octave:0,semitones:0,detune:0,type:"sawtooth"},{pitch:0,type:"sawtooth",gain:0,octave:0,semitones:0,detune:0},{pitch:0,type:"sawtooth",gain:0,octave:0,semitones:0,detune:0}],envelope:{attack:0,decay:0,release:0,sustain:100},filter:{frequency:1512.7153011703033,resonance:0},filterEnvelope:{sustain:100,intensity:0,attack:0,decay:0,release:0}},{vco:[{pitch:0,type:"sawtooth",gain:1,octave:0,semitones:0,detune:0},{pitch:0,type:"sawtooth",octave:0,detune:10,semitones:7,gain:1},{pitch:0,octave:0,semitones:0,type:"square",detune:2.142857142857146,gain:.31363636363636366}],general:{octave:-1,glide:.08035714285714286},filter:{resonance:1,frequency:899.9248073623645},filterEnvelope:{attack:.2,release:.5,sustain:48.035714285714285,decay:.95,intensity:36.60714285714286},envelope:{decay:.2,sustain:100,release:.8321428571428571,attack:.01499999999999996}},{meta:{presetName:"Bell"},power:{active:!0},envelope:{sustain:0,attack:.006428571428571418,decay:.7821428571428571,release:.7392857142857142},general:{octave:2,glide:0},filterEnvelope:{attack:.010714285714285714,intensity:100,decay:.46785714285714286,release:.3964285714285714,sustain:40.714285714285715},vco:[{pitch:0,octave:0,semitones:0,detune:0,gain:.8136363636363636,type:"square"},{pitch:0,octave:0,type:"triangle",detune:11.25,semitones:7,gain:.6363636363636365},{pitch:0,octave:0,gain:1,semitones:12,detune:18.214285714285722,type:"square"}],filter:{resonance:0,frequency:765.4388234673022}},{meta:{presetName:"Troy"},power:{active:!0},general:{glide:0,octave:-1},filter:{resonance:0,frequency:514.4382313196404},filterEnvelope:{sustain:0,intensity:54.10714285714286,release:.45,attack:.48214285714285693,decay:.6749999999999999},envelope:{decay:0,release:0,sustain:100,attack:.36428571428571427},vco:[{pitch:0,octave:0,semitones:0,detune:0,type:"sawtooth",gain:1},{pitch:0,octave:0,detune:0,type:"sine",semitones:-12,gain:.6727272727272726},{pitch:0,octave:0,semitones:0,detune:0,type:"sine",gain:0}]},{power:{active:!0},envelope:{attack:2,decay:2,sustain:54.46428571428571,release:2},filter:{resonance:2.142857142857143,frequency:100},filterEnvelope:{sustain:100,decay:0,attack:2,release:1.7571428571428571,intensity:50.35714285714286},vco:[{pitch:0,octave:0,semitones:0,detune:0,type:"sine",gain:.75},{pitch:0,octave:0,gain:.7954545454545454,type:"triangle",detune:12.32142857142857,semitones:3},{pitch:0,octave:0,type:"square",gain:.4681818181818182,detune:-7.5,semitones:7}],general:{glide:.41785714285714287,octave:1}},{meta:{presetName:"WahWah"},general:{octave:-2,glide:.13,currentTime:0},vco:[{pitch:0,gain:1,octave:0,semitones:0,detune:0,type:"sawtooth"},{pitch:0,type:"triangle",gain:.7227272727272727,octave:0,semitones:12,detune:0},{pitch:0,type:"square",gain:0,octave:0,semitones:0,detune:0}],envelope:{attack:.16926666150378772,decay:6.520572293428623,sustain:100,release:.25118864315095835},filterEnvelope:{sustain:28,intensity:36.428571428571416,attack:.5531681197617235,decay:7.56,release:.12589254117941692},filter:{frequency:213.40171133990876,resonance:95.71428571428572}},{power:{active:!0},general:{octave:0,glide:0},vco:[{pitch:0,type:"square",gain:1,octave:0,semitones:0,detune:10.714285714285694},{pitch:0,type:"square",gain:.6590909090909092,octave:0,semitones:-7,detune:.5357142857142847},{pitch:0,type:"square",gain:.7181818181818183,octave:0,semitones:7,detune:10.17857142857143}],envelope:{attack:.005094984382828271,decay:2.357537269587174,sustain:26.071428571428573,release:.5179474679231217},filterEnvelope:{attack:.001,decay:.9699386857056398,sustain:4.821428571428571,release:.0048496934285282,intensity:70.71428571428572},filter:{frequency:571.4458476045286,resonance:65.89285714285714}},{general:{octave:-1,glide:.24107142857142827},vco:[{pitch:0,type:"triangle",gain:.6500000000000001,octave:0,semitones:5,detune:0},{pitch:0,type:"square",gain:.8818181818181818,octave:0,semitones:-7,detune:-15},{pitch:0,type:"sawtooth",gain:.9318181818181818,octave:0,semitones:0,detune:24.10714285714286}],envelope:{attack:.003789408531634213,decay:4.941822455971212,sustain:0,release:2.308105833452399},filterEnvelope:{attack:.3377313908791014,decay:.5179474679231217,sustain:24.107142857142858,release:9.676410537094561,intensity:-55},filter:{frequency:874.7405861451177,resonance:90}}],ps=$t.div` + display: flex; + padding: 10px; +`;class hs extends L().Component{constructor(e){super(e),this.state={presetName:e.meta.presetName,presets:[]}}componentDidMount(){this.fetch(),window.addEventListener("hashchange",this.loadFromUrl.bind(this),!1),this.loadFromUrl()}loadFromUrl(e){if(window.location.hash){var t=decodeURIComponent(window.location.hash.substring(1)),n=JSON.parse(t);n&&(console.log(n),this.props.setPreset(-1),this.props.loadPreset(n))}window.dispatchEvent(new Event("popstate"))}onNameChange(e){this.setState({presetName:e.target.value})}onSave(){this.props.setParam("meta",!1,"presetName",this.state.presetName);(e=>{try{let t=N();const n=((e,t)=>e.findIndex((e=>e.meta.presetName===t.meta.presetName)))(t,e);-1===n?t.push(e):t[n]=e,console.log(n);const r=JSON.stringify(t);localStorage.setItem("presets",r)}catch{}})(this.context.store.getState().state,this.state.presetName),this.fetch()}onClear(){window.confirm("DELETE ALL? SURE?")&&(localStorage.setItem("presets","[]"),this.setState({presetName:""}),this.fetch())}onExport(){var e=document.createElement("a");e.setAttribute("href","data:text/plain;charset=utf-8,"+encodeURIComponent(JSON.stringify(this.state.presets))),e.setAttribute("download","synth-presets"),e.style.display="none",document.body.appendChild(e),e.click(),document.body.removeChild(e)}fetch(){console.log(N()),this.setState({presets:N()})}loadPreset(e){this.props.loadPreset(ds[e]),this.props.setPreset(e)}renderButtons(){let e=[];for(let t=0;t<8;t++)e.push(L().createElement(fs,{key:`button_${t}`,onClick:()=>{this.loadPreset(t)},preset:t,active:this.props.meta.preset===t}));return e}render(){return L().createElement(ps,null,this.renderButtons())}}hs.contextType=Bt.ty;const ms=(0,Bt.Ng)((e=>({...e.state})),(e=>(0,R.zH)({setParam:x,setPreset:T,loadPreset:C},e)))(hs),vs=$t.div` + padding: 4px; + background: linear-gradient( + 180deg, + rgba(36, 36, 36, 0.9) 0%, + rgba(23, 23, 23, 0.9) 100% + ); + border: 1px solid rgba(33, 33, 33, 0.4); + border-radius: 6px; + margin: 8px; + width: auto; + height: 110px; + position: relative; +`,gs=$t.div` + background: linear-gradient(180deg, #1e1e1e 0.01%, #101010 100%); + border-radius: 2px; + position: relative; + height: 100%; + & > * { + opacity: ${e=>!0===e.power?1:0}; + transition: all 0.5s; + transition-delay: 0.2s; + } +`,ys=$t.canvas` +width:auto; +position:absolute; +top:0; +left:0 +width:100%; +height:100%; +`;const bs=(0,Bt.Ng)((e=>({dataArray:e.state.oscilloscope.dataArray,fftSize:e.state.oscilloscope.fftSize,sampleRate:e.state.oscilloscope.sampleRate,currentTime:e.state.general.currentTime,note:e.state.keyboard.note,power:e.state.power.active})),null)((function(e){const{dataArray:t,note:n,power:r,sampleRate:o}=e,i=(0,j.useRef)();return(0,j.useEffect)((()=>{let e,a=i.current,u=a.getContext("2d");if(u.clearRect(0,0,a.width,a.height),!r)return;const l=()=>{u.clearRect(0,0,a.width,a.height);var r=0;u.lineWidth=2,u.strokeStyle="#11CD43",u.shadowOffsetX=0,u.shadowOffsetY=0,u.shadowBlur=12,u.shadowColor="rgba(17, 205, 67, 0.88)",u.beginPath();let i,s=o/n.freq*3,c=0;for(var f=0;f0&&t[f]<=0){c=f;break}i=t[f]}let d=Math.max(...t);d=d<1?1:d;for(var p=1*a.width/s,h=0;h{cancelAnimationFrame(e)}})),L().createElement(vs,null,L().createElement(gs,{power:r},L().createElement(ys,{ref:i})))})),ws=$t.div` + display: flex; + text-align: center; + justify-content: space-between; + align-items: flex-end; +`,xs=$t.div` + display: flex; + align-items: space-between; + justify-content: stretch; +`,Es=$t.div` + display: flex; + flex-direction: column; + text-align: center; + align-items: stretch; +`,ks=$t.h2` + background: white; + margin: 4px; + color: #313131; + font-size: 16px; + letter-spacing: 2.5px; + text-transform: uppercase; + padding: 5px; + font-weight: bold; + border-radius: 3px; +`,Ss=$t.div` + padding: 20px; + flex: 1; + display: flex; + flex-direction: column; +`,Cs=$t.div` + text-align: center; + border: 0.5px solid; + margin: 8px; + border-radius: 6px; + flex: ${e=>"undefined"!==typeof e.flex?e.flex:1}; + display: flex; + flex-direction: column; +`;class Ts extends L().Component{render(){const{props:e}=this;return L().createElement(xs,{className:"Controls"},L().createElement(Es,null,L().createElement(Cs,{flex:"0 0 auto"},L().createElement(ks,null,"Master"),L().createElement(Ss,null,L().createElement(Ul,{decimals:2,label:"Gain",unit:"",module:"amp",param:"gain",min:0,max:1,default:1,value:e.amp.gain}),L().createElement(Ul,{snap:1,label:"Octave",unit:"",module:"general",param:"octave",min:-3,max:3,default:0,value:e.general.octave}),L().createElement(Ul,{label:"Glide",decimals:2,unit:"s",module:"general",param:"glide",min:0,max:3,default:0,value:e.general.glide}))),L().createElement(bs,null),L().createElement(Cs,null,L().createElement(ks,null,"POWER"),L().createElement(Ss,null,L().createElement(Xt,{module:"power",value:e.power.active})))),e.vco.map(((t,n)=>L().createElement(Es,{key:`vco_${n}`},L().createElement(Cs,null,L().createElement(ks,{key:`vco_title_${n}`},"VCO ",n+1),L().createElement(Ss,null,L().createElement(Ul,{key:`vco_semitones_${n}`,snap:1,label:"semitones",module:"vco",moduleIndex:n,param:"semitones",min:-24,max:24,default:0,value:e.vco[n].semitones}),L().createElement(Ul,{key:`vco_detune_${n}`,label:"detune",unit:"ct",module:"vco",moduleIndex:n,param:"detune",min:-50,max:50,default:0,value:e.vco[n].detune}),L().createElement(Zl,{key:`vco_gain2_${n}`,label:"Gain",module:"vco",moduleIndex:n,param:"gain",min:0,max:1,default:1,value:e.vco[n].gain}),L().createElement(us,{key:`vco_shape_${n}`,label:"Type",module:"vco",moduleIndex:n,param:"type",value:e.vco[n].type})))))),L().createElement(Es,null,L().createElement(Cs,{flex:1.2},L().createElement(ks,null,"FILTER"),L().createElement(Ss,null,L().createElement(ws,null,L().createElement(Ul,{label:"Cutoff",log:!0,unit:"Hz",module:"filter",size:90,param:"frequency",min:100,max:2e4,default:300,value:e.filter.frequency}),L().createElement(Ul,{label:"Resonance",module:"filter",param:"resonance",min:0,max:100,default:0,value:e.filter.resonance}),L().createElement(Ul,{label:"EG INT",unit:"%",module:"filterEnvelope",param:"intensity",min:-100,max:100,default:0,value:e.filterEnvelope.intensity})))),L().createElement(Cs,{flex:1},L().createElement(ks,null,"FILTER EG"),L().createElement(Ss,null,L().createElement(ws,null,L().createElement(Ul,{label:"Attack",decimals:2,unit:"s",module:"filterEnvelope",param:"attack",log:!0,min:.001,max:10,value:e.filterEnvelope.attack}),L().createElement(Ul,{label:"Decay",decimals:2,unit:"s",module:"filterEnvelope",param:"decay",log:!0,min:.001,max:10,value:e.filterEnvelope.decay}),L().createElement(Ul,{label:"Sustain",unit:"%",module:"filterEnvelope",param:"sustain",min:0,max:100,value:e.filterEnvelope.sustain}),L().createElement(Ul,{label:"Release",decimals:2,unit:"s",module:"filterEnvelope",param:"release",log:!0,min:.001,max:10,value:e.filterEnvelope.release})))),L().createElement(Cs,{flex:1},L().createElement(ks,null,"AMP EG"),L().createElement(Ss,null,L().createElement(ws,null,L().createElement("div",null,L().createElement(Ul,{label:"Attack",decimals:2,unit:"s",module:"envelope",param:"attack",log:!0,min:.001,max:10,value:e.envelope.attack})),L().createElement("div",null,L().createElement(Ul,{label:"Decay",decimals:2,unit:"s",module:"envelope",param:"decay",log:!0,min:.001,max:10,value:e.envelope.decay})),L().createElement("div",null,L().createElement(Ul,{label:"Sustain",unit:"%",module:"envelope",param:"sustain",min:0,max:100,value:e.envelope.sustain})),L().createElement("div",null,L().createElement(Ul,{label:"Release",decimals:2,unit:"s",module:"envelope",param:"release",log:!0,min:.001,max:10,value:e.envelope.release}))))),L().createElement(Cs,{style:{flex:"none"}},L().createElement(ms,null))))}}const Ps=(0,Bt.Ng)((e=>({...e.state})),null)(Ts);async function Os(){let e;window.frameElement&&window.frameElement.CmajorSingletonPatchConnection&&(e=window.frameElement.CmajorSingletonPatchConnection);const t=A({vcoShapes:["sine","triangle","square","sawtooth","rampdown"],enableSoundEffectsOnControlInteractions:!1,connection:e});return{Root:Ps,store:I(t)}}},779:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=/^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|download|draggable|encType|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|itemProp|itemScope|itemType|itemID|itemRef|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/;const o=function(e){var t={};return function(n){return void 0===t[n]&&(t[n]=e(n)),t[n]}}((function(e){return r.test(e)||111===e.charCodeAt(0)&&110===e.charCodeAt(1)&&e.charCodeAt(2)<91}))},876:(e,t,n)=>{"use strict";var r=n(429),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},i={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},a={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},u={};function l(e){return r.isMemo(e)?a:u[e.$$typeof]||o}u[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0};var s=Object.defineProperty,c=Object.getOwnPropertyNames,f=Object.getOwnPropertySymbols,d=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,h=Object.prototype;e.exports=function e(t,n,r){if("string"!==typeof n){if(h){var o=p(n);o&&o!==h&&e(t,o,r)}var a=c(n);f&&(a=a.concat(f(n)));for(var u=l(t),m=l(n),v=0;v{"use strict";e.exports=function(e,t,n,r,o,i,a,u){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var s=[n,r,o,i,a,u],c=0;(l=new Error(t.replace(/%s/g,(function(){return s[c++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},470:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(o){return!1}}()?Object.assign:function(e,o){for(var i,a,u=function(e){if(null===e||void 0===e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),l=1;l{"use strict";var r=n(959);function o(){}function i(){}i.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,i,a){if(a!==r){var u=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw u.name="Invariant Violation",u}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:i,resetWarningCache:o};return n.PropTypes=n,n}},942:(e,t,n)=>{e.exports=n(488)()},959:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},345:(e,t,n)=>{"use strict";var r=n(950),o=n(470),i=n(340);function a(e){for(var t=e.message,n="https://reactjs.org/docs/error-decoder.html?invariant="+t,r=1;rthis.eventPool.length&&this.eventPool.push(e)}function de(e){e.eventPool=[],e.getPooled=ce,e.release=fe}o(se.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!==typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=ue)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!==typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=ue)},persist:function(){this.isPersistent=ue},isPersistent:le,destructor:function(){var e,t=this.constructor.Interface;for(e in t)this[e]=null;this.nativeEvent=this._targetInst=this.dispatchConfig=null,this.isPropagationStopped=this.isDefaultPrevented=le,this._dispatchInstances=this._dispatchListeners=null}}),se.Interface={type:null,target:null,currentTarget:function(){return null},eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null},se.extend=function(e){function t(){}function n(){return r.apply(this,arguments)}var r=this;t.prototype=r.prototype;var i=new t;return o(i,n.prototype),n.prototype=i,n.prototype.constructor=n,n.Interface=o({},r.Interface,e),n.extend=r.extend,de(n),n},de(se);var pe=se.extend({data:null}),he=se.extend({data:null}),me=[9,13,27,32],ve=q&&"CompositionEvent"in window,ge=null;q&&"documentMode"in document&&(ge=document.documentMode);var ye=q&&"TextEvent"in window&&!ge,be=q&&(!ve||ge&&8=ge),we=String.fromCharCode(32),xe={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["compositionend","keypress","textInput","paste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:"blur compositionend keydown keypress keyup mousedown".split(" ")},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},dependencies:"blur compositionstart keydown keypress keyup mousedown".split(" ")},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:"blur compositionupdate keydown keypress keyup mousedown".split(" ")}},Ee=!1;function ke(e,t){switch(e){case"keyup":return-1!==me.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"blur":return!0;default:return!1}}function Se(e){return"object"===typeof(e=e.detail)&&"data"in e?e.data:null}var Ce=!1;var Te={eventTypes:xe,extractEvents:function(e,t,n,r){var o=void 0,i=void 0;if(ve)e:{switch(e){case"compositionstart":o=xe.compositionStart;break e;case"compositionend":o=xe.compositionEnd;break e;case"compositionupdate":o=xe.compositionUpdate;break e}o=void 0}else Ce?ke(e,n)&&(o=xe.compositionEnd):"keydown"===e&&229===n.keyCode&&(o=xe.compositionStart);return o?(be&&"ko"!==n.locale&&(Ce||o!==xe.compositionStart?o===xe.compositionEnd&&Ce&&(i=ae()):(oe="value"in(re=r)?re.value:re.textContent,Ce=!0)),o=pe.getPooled(o,t,n,r),i?o.data=i:null!==(i=Se(n))&&(o.data=i),W(o),i=o):i=null,(e=ye?function(e,t){switch(e){case"compositionend":return Se(t);case"keypress":return 32!==t.which?null:(Ee=!0,we);case"textInput":return(e=t.data)===we&&Ee?null:e;default:return null}}(e,n):function(e,t){if(Ce)return"compositionend"===e||!ve&&ke(e,t)?(e=ae(),ie=oe=re=null,Ce=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1