diff --git a/Makefile b/Makefile index e7c16b7..8e5b987 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,7 @@ libs: $(MAKE) -C dpf/dgl plugins: libs + $(MAKE) all -C plugins/openav-ducka $(MAKE) all -C plugins/openav-roomy $(MAKE) all -C plugins/Parameters $(MAKE) all -C plugins/States @@ -27,6 +28,7 @@ dpf/utils/lv2_ttl_generator: clean: $(MAKE) clean -C dpf/dgl $(MAKE) clean -C dpf/utils/lv2-ttl-generator + $(MAKE) clean -C plugins/openav-ducka $(MAKE) clean -C plugins/openav-roomy $(MAKE) clean -C plugins/Parameters $(MAKE) clean -C plugins/States diff --git a/plugins/openav-ducka/ArtyFxPluginDucka.cpp b/plugins/openav-ducka/ArtyFxPluginDucka.cpp new file mode 100644 index 0000000..35663ad --- /dev/null +++ b/plugins/openav-ducka/ArtyFxPluginDucka.cpp @@ -0,0 +1,298 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2014 Filipe Coelho + * + * 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. + */ + +#include "DistrhoPlugin.hpp" + +START_NAMESPACE_DISTRHO + +// ----------------------------------------------------------------------------------------------------------- + +class ArtyFxPluginDucka : public Plugin +{ +public: + ArtyFxPluginDucka() + : Plugin(4, 0, 0), // 4 parameters, 0 programs, 0 states + // parameters init + controlThreshold(0.25f), + controlReduction(1.0f), + controlReleaseTime(0.5f), + controlSidechainAmp(0.0f), + // filter state init + w(10.0f / (d_getSampleRate() * 0.02)), + a(0.07f), + b(1.0f / (1.0f - a)), + g1(0.0f), + g2(0.0f), + samplerate( d_getSampleRate() ), + peakFrameCounter(0), + peakCountDuration( samplerate / 4 ), + currentTarget(0) + { + } + +protected: + /* -------------------------------------------------------------------------------------------------------- + * Information */ + + /** + Get the plugin label. + A plugin label follows the same rules as Parameter::symbol, with the exception that it can start with numbers. + */ + const char* d_getLabel() const override + { + return "roomy"; + } + + /** + Get the plugin author/maker. + */ + const char* d_getMaker() const override + { + return "OpenAV Productions"; + } + + /** + Get the plugin license name (a single line of text). + */ + const char* d_getLicense() const override + { + return "ISC"; + } + + /** + Get the plugin version, in hexadecimal. + TODO format to be defined + */ + uint32_t d_getVersion() const override + { + return 0x1000; + } + + /** + Get the plugin unique Id. + This value is used by LADSPA, DSSI and VST plugin formats. + */ + int64_t d_getUniqueId() const override + { + return d_cconst('O', 'V', 'd', 'k'); + } + + /* -------------------------------------------------------------------------------------------------------- + * Init */ + + /** + Initialize the parameter @a index. + This function will be called once, shortly after the plugin is created. + */ + void d_initParameter(uint32_t index, Parameter& parameter) override + { + parameter.hints = kParameterIsAutomable; + parameter.ranges.min = 0.0f; + parameter.ranges.max = 1.0f; + + switch (index) + { + case 0: + parameter.name = "Threshold"; + parameter.symbol = "threshold"; + parameter.ranges.def = 0.25f; + break; + case 1: + parameter.name = "Reduction"; + parameter.symbol = "reduction"; + parameter.ranges.def = 1.0f; + break; + case 2: + parameter.name = "Release Time"; + parameter.symbol = "release_time"; + parameter.ranges.def = 0.5f; + break; + case 3: + parameter.hints |= kParameterIsOutput; + parameter.name = "Sidechain Amplitude"; + parameter.symbol = "sidechain_amp"; + parameter.ranges.def = 0.0f; + break; + } + } + + /* -------------------------------------------------------------------------------------------------------- + * Internal data */ + + /** + Get the current value of a parameter. + */ + float d_getParameterValue(uint32_t index) const override + { + switch (index) + { + case 0: return controlThreshold; + case 1: return controlReduction; + case 2: return controlReleaseTime; + case 3: return controlSidechainAmp; + } + + return 0.0f; + } + + /** + Change a parameter value. + */ + void d_setParameterValue(uint32_t index, float value) override + { + switch (index) + { + case 0: + controlThreshold = value; + break; + case 1: + controlReduction = value; + break; + case 2: + controlReleaseTime = value; + break; + } + + // outputs can't be changed by the host + } + + /* -------------------------------------------------------------------------------------------------------- + * Process */ + + /** + Run/process function for plugins without MIDI input. + */ + void d_run(const float** inputs, float** outputs, uint32_t frames) override + { + const float* inL = inputs[0]; + const float* inR = inputs[1]; + const float* side = inputs[2]; + float* outL = outputs[0]; + float* outR = outputs[1]; + + const TimePosition& timePos(d_getTimePosition()); + + if (timePos.bbt.valid) + peakCountDuration = samplerate / ( timePos.bbt.beatsPerMinute / 60.0); + else + peakCountDuration = samplerate / 2.0f; + + /// analyse sidechain input for peak + float sum = 0.f; + for( uint32_t i = 0; i < frames; i++ ) + { + if ( *side > 0.000001 ) + sum += *side++; + else + sum += -*side++; + } + + currentTarget = 0.f; + + /// check for peak level (offset to avoid "always on" peak) + if ( sum / frames > controlThreshold + 0.05 ) + { + peakFrameCounter = peakCountDuration * controlReleaseTime; + currentTarget = 1.f - controlReduction; + } + else if ( peakFrameCounter < 0 ) + { + currentTarget = 1.f; + } + else + { + currentTarget = 1.f - controlReduction; + } + + if ( currentTarget < 0.f ) + currentTarget = 0.f; + + peakFrameCounter -= frames; + + for( uint32_t i = 0; i < frames; i++ ) + { + /// smoothing algo is a lowpass, to de-zip the fades + /// x^^4 approximates linear volume increase for human ears + g1 += w * ( std::pow ( currentTarget, 4.f ) - g1 - a * g2 - 1e-20f); + g2 += w * (b * g1 - g2 + 1e-20f); + float gain = g2; + + *outL++ = *inL++ * gain; + *outR++ = *inR++ * gain; + } + + /// update output value + controlSidechainAmp = 1-currentTarget; + } + + /* -------------------------------------------------------------------------------------------------------- + * Callbacks */ + + /** + Optional callback to inform the plugin about a sample rate change. + This function will only be called when the plugin is deactivated. + */ + void d_sampleRateChanged(double newSampleRate) override + { + // reinit filter + w = 10.0f / (newSampleRate * 0.02); + a = 0.07f; + b = 1.0f / (1.0f - a); + g1 = 0.0f; + g2 = 0.0f; + samplerate = newSampleRate; + peakFrameCounter = 0; + peakCountDuration = samplerate / 4; + currentTarget = 0; + } + + // ------------------------------------------------------------------------------------------------------- + +private: + /// control signals + float controlThreshold; + float controlReduction; + float controlReleaseTime; + float controlSidechainAmp; + + /// filter state + float w, a, b, g1, g2; + + /// last peak history + long samplerate; + bool nowIsAPeak; + long peakFrameCounter; + + /// nframes available for countdown + long peakCountDuration; + + /// control output + float currentTarget; + + DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ArtyFxPluginDucka) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * Plugin entry point, called by DPF to create a new plugin instance. */ + +Plugin* createPlugin() +{ + return new ArtyFxPluginDucka(); +} + +// ----------------------------------------------------------------------------------------------------------- + +END_NAMESPACE_DISTRHO diff --git a/plugins/openav-ducka/ArtyFxUiDucka.cpp b/plugins/openav-ducka/ArtyFxUiDucka.cpp new file mode 100644 index 0000000..3a7d776 --- /dev/null +++ b/plugins/openav-ducka/ArtyFxUiDucka.cpp @@ -0,0 +1,103 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2014 Filipe Coelho + * + * 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. + */ + +#include "DistrhoUI.hpp" + +// include full file here for convenience +#include "gui/ducka_widget.cxx" + +START_NAMESPACE_DISTRHO + +// ----------------------------------------------------------------------------------------------------------- + +class ArtyFxUiDucka : public UI +{ +public: + ArtyFxUiDucka() + : UI(), + fUI(this), + sidechainAmp(0.0f) + { + // ntk method to add sub-window + add(fUI.window); + fUI.window->show(); + + // start widgets on their default values + fUI.graph->threshold(0.25f); + fUI.graph->reduce(1.0f); + fUI.graph->release(0.5f); + fUI.threshold->value(0.25f); + fUI.drop->value(1.0f); + fUI.time->value(0.5f); + + setSize(fUI.getWidth(), fUI.getHeight()); + } + +protected: + /* -------------------------------------------------------------------------------------------------------- + * DSP/Plugin Callbacks */ + + /** + A parameter has changed on the plugin side. + This is called by the host to inform the UI about parameter changes. + */ + void d_parameterChanged(uint32_t index, float value) override + { + switch (index) + { + case 0: + fUI.graph->threshold( value ); + fUI.threshold->value( value ); + break; + case 1: + fUI.graph->reduce( value ); + fUI.drop->value( value ); + break; + case 2: + fUI.graph->release( value ); + fUI.time->value( value ); + break; + case 3: + /// only update when value changes? + //if ( sidechainAmp > value + 0.1 || sidechainAmp < value - 0.1) + { + fUI.graph->sidechain( value ); + sidechainAmp = value; + } + break; + } + } + + // ------------------------------------------------------------------------------------------------------- + +private: + DuckaUI fUI; + float sidechainAmp; + + DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ArtyFxUiDucka) +}; + +/* ------------------------------------------------------------------------------------------------------------ + * UI entry point, called by DPF to create a new UI instance. */ + +UI* createUI() +{ + return new ArtyFxUiDucka(); +} + +// ----------------------------------------------------------------------------------------------------------- + +END_NAMESPACE_DISTRHO diff --git a/plugins/openav-ducka/DistrhoPluginInfo.h b/plugins/openav-ducka/DistrhoPluginInfo.h new file mode 100644 index 0000000..d949347 --- /dev/null +++ b/plugins/openav-ducka/DistrhoPluginInfo.h @@ -0,0 +1,39 @@ +/* + * DISTRHO Plugin Framework (DPF) + * Copyright (C) 2012-2014 Filipe Coelho + * + * 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. + */ + +#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED +#define DISTRHO_PLUGIN_INFO_H_INCLUDED + +#define DISTRHO_PLUGIN_NAME "Roomy" + +#define DISTRHO_PLUGIN_HAS_UI 1 +#define DISTRHO_PLUGIN_IS_RT_SAFE 1 +#define DISTRHO_PLUGIN_IS_SYNTH 0 + +#define DISTRHO_PLUGIN_NUM_INPUTS 3 +#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 + +#define DISTRHO_PLUGIN_WANT_LATENCY 0 +#define DISTRHO_PLUGIN_WANT_PROGRAMS 0 +#define DISTRHO_PLUGIN_WANT_STATE 0 +#define DISTRHO_PLUGIN_WANT_TIMEPOS 1 + +#define DISTRHO_PLUGIN_URI "http://www.openavproductions.com/artyfx#ducka" +#define DISTRHO_UI_URI "http://www.openavproductions.com/artyfx#ducka/gui" + +#define DISTRHO_UI_USE_NTK 1 + +#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED diff --git a/plugins/openav-ducka/Makefile b/plugins/openav-ducka/Makefile new file mode 100644 index 0000000..edd251d --- /dev/null +++ b/plugins/openav-ducka/Makefile @@ -0,0 +1,35 @@ +#!/usr/bin/make -f +# Makefile for DISTRHO Plugins # +# ---------------------------- # +# Created by falkTX +# + +# -------------------------------------------------------------- +# Project name, used for binaries + +NAME = ducka + +# -------------------------------------------------------------- +# Files to build + +OBJS_DSP = \ + ArtyFxPluginDucka.cpp.o + +OBJS_UI = \ + ArtyFxUiDucka.cpp.o + +# -------------------------------------------------------------- +# Do some magic + +include ../Makefile.ntk.mk + +# -------------------------------------------------------------- +# Enable all possible plugin types + +ifeq ($(LINUX),true) +all: jack ladspa dssi lv2_sep vst +else +all: ladspa dssi lv2_sep vst +endif + +# -------------------------------------------------------------- diff --git a/plugins/openav-ducka/README.md b/plugins/openav-ducka/README.md new file mode 100644 index 0000000..17bdb73 --- /dev/null +++ b/plugins/openav-ducka/README.md @@ -0,0 +1,4 @@ +# OpenAV / NTK example + +This example will show an OpenAV based plugin working with DPF.
+The UI uses NTK instead of OpenGL.
diff --git a/plugins/openav-ducka/gui/avtk.h b/plugins/openav-ducka/gui/avtk.h new file mode 100644 index 0000000..f4ee7c4 --- /dev/null +++ b/plugins/openav-ducka/gui/avtk.h @@ -0,0 +1,28 @@ +/* + * Author: Harry van Haaren 2013 + * harryhaaren@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef DUCKA_AVTK +#define DUCKA_AVTK + +#include "../../avtk/dial.h" +#include "../../avtk/image.h" +#include "../../avtk/sidechain_gain.h" + +#endif diff --git a/plugins/openav-ducka/gui/ducka_widget.cxx b/plugins/openav-ducka/gui/ducka_widget.cxx new file mode 100644 index 0000000..56ac136 --- /dev/null +++ b/plugins/openav-ducka/gui/ducka_widget.cxx @@ -0,0 +1,153 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0300 + +#include "ducka_widget.h" + +START_NAMESPACE_DISTRHO + +void DuckaUI::cb_headerImage_i(Avtk::Image*, void*) { + //system("xdg-open http://www.openavproductions.com/artyfx#ducka"); +} +void DuckaUI::cb_headerImage(Avtk::Image* o, void* v) { + ((DuckaUI*)(o->parent()->user_data()))->cb_headerImage_i(o,v); +} + +void DuckaUI::cb_graph_i(Avtk::SidechainGain* o, void*) { + //cutoff = o->value(); +//float g = o->getGain(); +//gainDial->value( g ); +//freq->value( cutoff ); // update dial +//writePort(CUTOFF_FREQ, cutoff); +//writePort(CUTOFF_GAIN, g); +} +void DuckaUI::cb_graph(Avtk::SidechainGain* o, void* v) { + ((DuckaUI*)(o->parent()->user_data()))->cb_graph_i(o,v); +} + +void DuckaUI::cb_threshold_i(Avtk::Dial* o, void*) { + float tmp = o->value(); + graph->threshold( tmp ); + setHostParameter( 0, tmp ); +} +void DuckaUI::cb_threshold(Avtk::Dial* o, void* v) { + ((DuckaUI*)(o->parent()->user_data()))->cb_threshold_i(o,v); +} + +void DuckaUI::cb_drop_i(Avtk::Dial* o, void*) { + float tmp = o->value(); + graph->reduce( tmp ); + setHostParameter( 1, tmp ); +} +void DuckaUI::cb_drop(Avtk::Dial* o, void* v) { + ((DuckaUI*)(o->parent()->user_data()))->cb_drop_i(o,v); +} + +void DuckaUI::cb_time_i(Avtk::Dial* o, void*) { + float tmp = o->value(); + graph->release( tmp ); + setHostParameter( 2, tmp ); +} +void DuckaUI::cb_time(Avtk::Dial* o, void* v) { + ((DuckaUI*)(o->parent()->user_data()))->cb_time_i(o,v); +} + +/** + if the type of filter changes, this function will highlight the right button +*/ +void DuckaUI::update_button(int button) { +} + +DuckaUI::DuckaUI(UI* const uic) : ui(uic) { + { Fl_Double_Window* o = window = new Fl_Double_Window(160, 220); + window->user_data((void*)(this)); + { headerImage = new Avtk::Image(0, 0, 160, 29, "header.png"); + headerImage->box(FL_NO_BOX); + headerImage->color(FL_BACKGROUND_COLOR); + headerImage->selection_color(FL_BACKGROUND_COLOR); + headerImage->labeltype(FL_NORMAL_LABEL); + headerImage->labelfont(0); + headerImage->labelsize(14); + headerImage->labelcolor((Fl_Color)20); + headerImage->callback((Fl_Callback*)cb_headerImage); + headerImage->align(Fl_Align(FL_ALIGN_CENTER)); + headerImage->when(FL_WHEN_RELEASE_ALWAYS); + headerImage->setPixbuf(header.pixel_data,4); + } // Avtk::Image* headerImage + { graph = new Avtk::SidechainGain(5, 36, 150, 126, "graph"); + graph->box(FL_UP_BOX); + graph->color((Fl_Color)179); + graph->selection_color(FL_INACTIVE_COLOR); + graph->labeltype(FL_NO_LABEL); + graph->labelfont(0); + graph->labelsize(14); + graph->labelcolor(FL_FOREGROUND_COLOR); + graph->callback((Fl_Callback*)cb_graph); + graph->align(Fl_Align(FL_ALIGN_BOTTOM)); + graph->when(FL_WHEN_CHANGED); + } // Avtk::SidechainGain* graph + { threshold = new Avtk::Dial(10, 169, 37, 37, "Thres"); + threshold->box(FL_NO_BOX); + threshold->color((Fl_Color)90); + threshold->selection_color(FL_INACTIVE_COLOR); + threshold->labeltype(FL_NORMAL_LABEL); + threshold->labelfont(0); + threshold->labelsize(10); + threshold->labelcolor(FL_FOREGROUND_COLOR); + threshold->callback((Fl_Callback*)cb_threshold); + threshold->align(Fl_Align(FL_ALIGN_BOTTOM)); + threshold->when(FL_WHEN_CHANGED); + } // Avtk::Dial* threshold + { drop = new Avtk::Dial(62, 169, 37, 37, "Drop"); + drop->box(FL_NO_BOX); + drop->color((Fl_Color)90); + drop->selection_color(FL_INACTIVE_COLOR); + drop->labeltype(FL_NORMAL_LABEL); + drop->labelfont(0); + drop->labelsize(10); + drop->labelcolor(FL_FOREGROUND_COLOR); + drop->callback((Fl_Callback*)cb_drop); + drop->align(Fl_Align(FL_ALIGN_BOTTOM)); + drop->when(FL_WHEN_CHANGED); + } // Avtk::Dial* drop + { time = new Avtk::Dial(113, 168, 37, 37, "Time"); + time->box(FL_NO_BOX); + time->color((Fl_Color)90); + time->selection_color(FL_INACTIVE_COLOR); + time->labeltype(FL_NORMAL_LABEL); + time->labelfont(0); + time->labelsize(10); + time->labelcolor(FL_FOREGROUND_COLOR); + time->callback((Fl_Callback*)cb_time); + time->align(Fl_Align(FL_ALIGN_BOTTOM)); + time->when(FL_WHEN_CHANGED); + } // Avtk::Dial* time + window->color( fl_rgb_color( 17,17,17) ); + close_cb( o, 0 ); + window->end(); + } // Fl_Double_Window* window +} + +int DuckaUI::getWidth() { + return window->w(); +} + +int DuckaUI::getHeight() { + return window->h(); +} + +void DuckaUI::setHostParameter(uint32_t index, float value) { + //cout << "port " << port << " value " << value << endl; + ui->d_setParameterValue(index, value); +} + +void DuckaUI::close_cb(Fl_Widget* o, void*) { + if ((Fl::event() == FL_KEYDOWN || Fl::event() == FL_SHORTCUT) && Fl::event_key() == FL_Escape) + { + return; // ignore ESC + } + else + { + o->hide(); + } +} + +END_NAMESPACE_DISTRHO diff --git a/plugins/openav-ducka/gui/ducka_widget.fl b/plugins/openav-ducka/gui/ducka_widget.fl new file mode 100644 index 0000000..bb27aea --- /dev/null +++ b/plugins/openav-ducka/gui/ducka_widget.fl @@ -0,0 +1,108 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0300 +header_name {.h} +code_name {.cxx} +class DuckaUI {open +} { + Function {update_button(int button)} { + comment {if the type of filter changes, this function will highlight the right button} open return_type void + } { + code {} {} + } + Function {DuckaUI()} {open + } { + Fl_Window window {open selected + xywh {1734 413 160 220} type Double + code0 {\#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"} + code1 {\#include "avtk.h"} + code2 {window->color( fl_rgb_color( 17,17,17) );} + code3 {close_cb( o, 0 );} visible + } { + Fl_Box headerImage { + label {header.png} + callback {//system("xdg-open http://www.openavproductions.com/artyfx\#ducka");} + xywh {0 0 160 29} labelcolor 20 when 6 + code0 {using namespace std;} + code1 {\#include } + code2 {\#include "header.c"} + code3 {headerImage->setPixbuf(header.pixel_data,4);} + class {Avtk::Image} + } + Fl_Dial graph { + label graph + callback {//cutoff = o->value(); +//float g = o->getGain(); +//gainDial->value( g ); +//freq->value( cutoff ); // update dial +//writePort(CUTOFF_FREQ, cutoff); +//writePort(CUTOFF_GAIN, g);} + xywh {5 36 150 126} box UP_BOX color 179 labeltype NO_LABEL + code1 {\#include "../dsp/ducka.hxx"} + class {Avtk::SidechainGain} + } + Fl_Dial threshold { + label Thres + callback {float tmp = o->value(); +graph->threshold( tmp ); +writePort( int(DUCKA_THRESHOLD), tmp );} + xywh {10 169 37 37} color 90 labelsize 10 + class {Avtk::Dial} + } + Fl_Dial drop { + label Drop + callback {float tmp = o->value(); +graph->reduce( tmp ); +writePort( int(DUCKA_REDUCTION), tmp );} + xywh {62 169 37 37} color 90 labelsize 10 + class {Avtk::Dial} + } + Fl_Dial time { + label Time + callback {float tmp = o->value(); +graph->release( tmp ); +writePort( int(DUCKA_RELEASE_TIME),tmp );} + xywh {113 168 37 37} color 90 labelsize 10 + class {Avtk::Dial} + } + } + } + decl {LV2UI_Write_Function write_function;} {public local + } + decl {LV2UI_Controller controller;} {public local + } + Function {idle()} {open return_type void + } { + code {Fl::check(); +Fl::flush();} {} + } + Function {getWidth()} {open return_type int + } { + code {return window->w();} {} + } + Function {getHeight()} {open return_type int + } { + code {return window->h();} {} + } + decl {float gain;} {private local + } + decl {float cutoff;} {private local + } + decl {float Q;} {private local + } + Function {writePort(int port, float& value)} {open + } { + code {//cout << "port " << port << " value " << value << endl; +write_function(controller, port, sizeof(float), 0, &value);} {} + } + Function {close_cb(Fl_Widget* o, void*)} {open + } { + code {if ((Fl::event() == FL_KEYDOWN || Fl::event() == FL_SHORTCUT) && Fl::event_key() == FL_Escape) + { + return; // ignore ESC + } + else + { + o->hide(); + }} {} + } +} diff --git a/plugins/openav-ducka/gui/ducka_widget.h b/plugins/openav-ducka/gui/ducka_widget.h new file mode 100644 index 0000000..244059e --- /dev/null +++ b/plugins/openav-ducka/gui/ducka_widget.h @@ -0,0 +1,64 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0300 + +#ifndef ducka_widget_h +#define ducka_widget_h + +#include +#include +//#include "lv2/lv2plug.in/ns/extensions/ui/ui.h" +#include "DistrhoUI.hpp" + +#include "avtk.h" +#include +#include "header.c" + +using namespace std; + +// keep things inside the namespace to prevent issues with public symbols +START_NAMESPACE_DISTRHO + +class DuckaUI { +public: + void update_button(int button); + DuckaUI(UI* const ui); + Fl_Double_Window *window; + Avtk::Image *headerImage; +private: + void cb_headerImage_i(Avtk::Image*, void*); + static void cb_headerImage(Avtk::Image*, void*); +public: + Avtk::SidechainGain *graph; +private: + void cb_graph_i(Avtk::SidechainGain*, void*); + static void cb_graph(Avtk::SidechainGain*, void*); +public: + Avtk::Dial *threshold; +private: + void cb_threshold_i(Avtk::Dial*, void*); + static void cb_threshold(Avtk::Dial*, void*); +public: + Avtk::Dial *drop; +private: + void cb_drop_i(Avtk::Dial*, void*); + static void cb_drop(Avtk::Dial*, void*); +public: + Avtk::Dial *time; +private: + void cb_time_i(Avtk::Dial*, void*); + static void cb_time(Avtk::Dial*, void*); +public: + int getWidth(); + int getHeight(); +private: + UI* const ui; + float gain; + float cutoff; + float Q; +public: + void setHostParameter(uint32_t index, float value); + void close_cb(Fl_Widget* o, void*); +}; + +END_NAMESPACE_DISTRHO + +#endif diff --git a/plugins/openav-ducka/gui/header.c b/plugins/openav-ducka/gui/header.c new file mode 100644 index 0000000..7fc42e8 --- /dev/null +++ b/plugins/openav-ducka/gui/header.c @@ -0,0 +1,650 @@ +/* GIMP RGBA C-Source image dump (header.c) */ + +static const struct { + unsigned int width; + unsigned int height; + unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */ + unsigned char pixel_data[160 * 29 * 4 + 1]; +} header = { + 160, 29, 4, + "000\377000\377000\377000\377000\377000\377000\377000\377000\377000\37700" + "0\377000\377000\377000\377000\377000\377000\377000\377000\377000\377000\377" + "000\377000\377000\377000\377000\377000\377000\377000\377000\377000\37700" + "0\377000\377000\377000\377000\377000\377000\377000\377000\377000\377000\377" + "000\377000\377000\377000\377000\377000\377000\377000\377000\377000\37700" + "0\377000\377000\377000\377000\377000\377000\377000\377000\377000\377000\377" + "000\377000\377000\377000\377000\377000\377000\377000\377000\377000\37700" + "0\377000\377000\377000\377000\377000\377000\377000\377000\377000\377000\377" + "000\377000\377000\377000\377000\377000\377000\377000\377000\377000\37700" + "0\377000\377000\377000\377000\377000\377000\377000\377000\377000\377000\377" + "000\377000\377000\377000\377000\377000\377000\377000\377000\377000\37700" + "0\377000\377000\377000\377000\377000\377000\377000\377000\377000\377000\377" + "000\377000\377000\377000\377000\377000\377000\377000\377000\377000\37700" + "0\377000\377000\377000\377000\377000\377000\377000\377000\377000\377000\377" + "000\377000\377000\377000\377000\377000\377000\377000\377000\377000\37700" + "0\377000\377000\377///\377///\377///\377///\377///\377///\377///\377///\377" + "///\377///\377///\377///\377///\377///\377///\377///\377///\377///\377//" + "/\377///\377///\377///\377///\377///\377///\377///\377///\377///\377///\377" + "///\377///\377///\377///\377///\377///\377///\377///\377///\377///\377//" + "/\377///\377///\377///\377///\377///\377///\377///\377///\377///\377///\377" + "///\377///\377///\377///\377///\377///\377///\377///\377///\377///\377//" + "/\377///\377///\377///\377///\377///\377///\377///\377///\377///\377///\377" + "///\377///\377///\377///\377///\377///\377///\377///\377///\377///\377//" + "/\377///\377///\377///\377///\377///\377///\377///\377///\377///\377///\377" + "///\377///\377///\377///\377///\377///\377///\377///\377///\377///\377//" + "/\377///\377///\377///\377///\377///\377///\377///\377///\377///\377///\377" + "///\377///\377///\377///\377///\377///\377///\377///\377///\377///\377//" + "/\377///\377///\377///\377///\377///\377///\377///\377///\377///\377///\377" + "///\377///\377///\377///\377///\377///\377///\377///\377///\377///\377//" + "/\377///\377///\377///\377///\377///\377///\377///\377///\377///\377///\377" + "///\377///\377///\377///\377///\377...\377...\377...\377...\377...\377.." + ".\377...\377...\377...\377...\377...\377...\377...\377...\377...\377...\377" + "...\377...\377...\377...\377...\377...\377...\377...\377...\377...\377.." + ".\377...\377...\377...\377...\377...\377...\377...\377...\377...\377...\377" + "...\377...\377...\377...\377...\377...\377...\377...\377...\377...\377.." + ".\377...\377...\377...\377...\377...\377...\377...\377...\377...\377...\377" + "...\377...\377...\377...\377...\377...\377...\377...\377...\377...\377.." + ".\377...\377...\377...\377...\377...\377...\377...\377...\377...\377...\377" + "...\377...\377...\377...\377...\377...\377...\377...\377...\377...\377.." + ".\377...\377...\377...\377...\377...\377...\377...\377...\377...\377...\377" + "...\377...\377...\377...\377...\377...\377...\377...\377...\377...\377.." + ".\377...\377...\377...\377...\377...\377...\377...\377...\377...\377...\377" + "...\377...\377...\377...\377...\377...\377...\377...\377...\377...\377.." + ".\377...\377...\377...\377...\377...\377...\377...\377...\377...\377...\377" + "...\377...\377...\377...\377...\377...\377...\377...\377...\377...\377.." + ".\377...\377...\377...\377...\377...\377...\377...\377---\377---\377---\377" + "---\377---\377---\377---\377---\377---\377---\377---\377---\377---\377--" + "-\377---\377---\377---\377---\377---\377---\377---\377---\377---\377---\377" + "---\377---\377---\377---\377---\377---\377---\377---\377---\377---\377--" + "-\377---\377---\377---\377---\377---\377---\377---\377---\377---\377---\377" + "---\377---\377---\377---\377---\377---\377---\377---\377---\377---\377--" + "-\377---\377---\377---\377---\377---\377---\377---\377---\377---\377---\377" + "---\377---\377---\377---\377---\377---\377---\377---\377---\377---\377--" + "-\377---\377---\377---\377---\377---\377---\377---\377---\377---\377---\377" + "---\377---\377---\377---\377---\377---\377---\377---\377---\377---\377--" + "-\377---\377---\377---\377---\377---\377---\377---\377---\377---\377---\377" + "---\377---\377---\377---\377---\377---\377---\377---\377---\377---\377--" + "-\377---\377---\377---\377---\377---\377---\377---\377---\377---\377---\377" + "---\377---\377---\377---\377---\377---\377---\377---\377---\377---\377--" + "-\377---\377---\377---\377---\377---\377---\377---\377---\377---\377---\377" + "---\377---\377---\377---\377---\377---\377---\377---\377---\377---\377,," + ",\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377" + ",,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,," + ",\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377" + ",,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,," + ",\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377" + ",,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,," + ",\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377" + ",,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,," + ",\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377" + ",,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,," + ",\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377" + ",,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,," + ",\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377" + ",,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,," + ",\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377,,,\377" + ",,,\377,,,\377+++\377+*+\377+++\377+++\377*++\377+++\377+++\377+++\377*+" + "+\377+++\377+++\377+*+\377*++\377**+\377+*+\377+*+\377+*+\377*++\377++*\377" + "+*+\377+*+\377*++\377++*\377++*\377+++\377*++\377*++\377++*\377++*\377++" + "+\377+*+\377+++\377+++\377+++\377++*\377+++\377*+*\377*+*\377+++\377+++\377" + "**+\377++*\377++*\377+*+\377+++\377+*+\377+*+\377+++\377*+*\377+++\377++" + "*\377*+*\377+*+\377*++\377+**\377**+\377+++\377+**\377+++\377+*+\377+++\377" + "++*\377+*+\377++*\377*++\377++*\377**+\377*+*\377+**\377++*\377+**\377++" + "*\377++*\377+++\377*++\377++*\377*++\377*++\377++*\377+*+\377*++\377**+\377" + "+*+\377+++\377++*\377++*\377+++\377+++\377*+*\377+*+\377++*\377+++\377++" + "+\377***\377+++\377+*+\377*++\377*++\377+**\377*++\377+++\377+++\377*+*\377" + "**+\377+*+\377+*+\377*+*\377+*+\377+*+\377*++\377+++\377***\377+++\377*+" + "+\377+++\377+++\377+*+\377++*\377+*+\377*+*\377+++\377+++\377+*+\377+*+\377" + "+*+\377+**\377***\377+++\377++*\377++*\377+*+\377*++\377**+\377+++\377++" + "+\377+++\377*+*\377+**\377*+*\377+*+\377+++\377++*\377+*+\377++*\377++*\377" + "+**\377**+\377*++\377+++\377*++\377+++\377+++\377+++\377+*+\377+++\377++" + "+\377++*\377++*\377+++\377++*\377)))\377)))\377)))\377)))\377)))\377)))\377" + ")))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377))" + ")\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377" + ")))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377))" + ")\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377" + ")))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377))" + ")\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377" + ")))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377))" + ")\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377" + ")))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377))" + ")\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377" + ")))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377))" + ")\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377" + ")))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377))" + ")\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377)))\377" + ")))\377)))\377)))\377)))\377)))\377)))\377)))\377(((\377(((\377(((\377((" + "(\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377" + "(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377((" + "(\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377" + "(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377((" + "(\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377" + "(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377((" + "(\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377" + "(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377((" + "(\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377" + "(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377((" + "(\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377" + "(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377((" + "(\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377" + "(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377((" + "(\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377(((\377'''\377" + "'''\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377''" + "'\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\232I\22\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377'''\377'''\377'''" + "\377'''\377'''\377'''\377'''\377'&&\377\244L\20\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\314X\11\377'''\377'''\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377'''\377'''\377'''\377'''\377'''\377'''\377\233I\21\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\314X\11\3773+$\377''" + "'\377'''\377'''\377'''\377'''\377'''\377('&\377\242L\20\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377'''\377" + "'''\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377''" + "'\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377'''\377" + "'''\377'''\377'''\377'''\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&" + "&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377" + "&&&\377&&&\377&&&\377&&&\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\251M\16\377'&%\377&&&\377" + "&&&\377&&&\377&&&\377&&&\377&&&\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\374f\0\377&&&\377&&&\377&&&\377&&&\377&&&\377" + "&&&\377&&&\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377'&%\377\252N" + "\16\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\314W\10\377&&&\377&&&\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377&&&\377&&&\377&&&\377&&&\377" + "'&%\377\252N\16\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\300T\12\377-($\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377" + "/($\377\275S\13\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377&&&\377&&&\377&&&\377&&&\377&&&\377" + "&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&" + "&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377&&&\377" + "%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%" + "%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\270R\13\377*&#\377%%%\377%%%\377%%%\377%%%" + "\377%%%\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\372e\0\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377%%%\377" + "%%%\377%%%\377%%%\377%%%\377&%$\377\256O\15\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\313W\10" + "\377%%%\377%%%\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377%%%\377%%%\377%%%\377*&#\377\271R\13\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\262P\14\377(%$\377" + "%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377;+!\377\325Z\6\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%" + "%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%" + "\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377%%%\377$$$\377$$$\377$$$\377" + "$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$" + "$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\304V\11\377-&\"\377$$$\377$$$\377$$$\377$$$\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\370f\0\377" + "$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377$$$\377$$$\377$$$\377" + "$$$\377&%#\377\261P\14\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\313W\10\377$$$\377" + "$$$\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377$$$\377$$$\377-&\"\377\305U\11\377\377h\0\377\377h\0\377\377h" + "\0\377\377h\0\377\377h\0\377\377h\0\377\242J\17\377$##\377$$$\377$$$\377" + "$$$\377$$$\377$$$\377$$$\377L0\35\377\346_\3\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$" + "$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$" + "\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377$$$\377###\377###\377###\377" + "###\377###\377###\377###\377###\377###\377###\377###\377###\377###\377##" + "#\377###\377###\377###\377###\377###\377###\377###\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\320X\7\3772'\40\377###\377###\377###\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\367e\1" + "\377###\377###\377###\377###\377###\377###\377###\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377###\377###\377###" + "\377&#\"\377\266P\13\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\313W\10" + "\377###\377###\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377###\3773'\40\377\320X\7\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\222E\21\377###\377###\377###\377" + "###\377###\377###\377###\377c7\30\377\363c\1\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377###\377###\377###\377###\377###\377###\377###\377" + "###\377###\377###\377###\377###\377###\377###\377###\377###\377###\377##" + "#\377###\377###\377###\377###\377###\377###\377###\377###\377\"\"\"\377\"" + "\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"" + "\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"" + "\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\"\"\"\377\"\"" + "\"\377\"\"\"\377\"\"\"\377\"\"\"\377\202@\23\377\375g\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\332[\5\3779(\36\377\"\"\"\377\"" + "\"\"\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\365e\1\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"" + "\"\"\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\"\"\"\377\"\"\"\377&\"!\377\272Q\12\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\373g\0\377r;\25\377\"\"\"\377\"\"\"\377" + "\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"" + "\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377:)\36\377\333]\5\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\375g\0\377\200?\23\377" + "\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\177" + "?\23\377\373g\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\364d\1\377d7\27\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"" + "\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"" + "\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"" + "\377\"\"\"\377\"\"\"\377\"\"\"\377\"\"\"\377!!!\377\40!!\377\40!!\377!!\40" + "\377!\40!\377\40!!\377\40!!\377\40!!\377!\40!\377!!!\377!\40!\377\40!!\377" + "!!\40\377\40!!\377\40!!\377!!!\377\40\40!\377\40\40!\377!\40!\377!!!\377" + "!!\40\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377!!!\377!\40!\377\40!!\377!!!\377!\40!\377\40!!\377{=\23\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\344_\3\377" + "\40!\40\377!!!\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\363c\1\377!!\40\377!!\40\377\40!!\377\40!!\377!!\40\377!!\40" + "\377!!\40\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\40\40\40\377!!!\377\276R\11\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377e7\26\377\40!!\377!!!\377\40" + "\40!\377\40!!\377!!\40\377\40!!\377!!!\377!!!\377!!\40\377\40!\40\377\40" + "!!\377!\40!\377!!\40\377!!!\377!\40!\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\344_\3\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\177=\22\377!\40!\377!\40" + "!\377!\40!\377!\40\40\377!!!\377!!!\377!!!\377!!!\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\311V\7\377\255M\14" + "\377\273R\11\377\312V\7\377\331\\\5\377\350`\3\377\367e\1\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377!!\40\377" + "!\40!\377\40!\40\377!!!\377\40\40\40\377\40!\40\377!\40!\377!\40!\377\40" + "!!\377!!!\377!!\40\377!!!\377!\40!\377!\40!\377!!!\377!!\40\377!!!\377\40" + "!\40\377!!!\377\40!\40\377\40!!\377!!!\377\40\40!\377!!!\377!!!\377!!!\377" + "\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37" + "\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37" + "\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377" + "\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\37\37\37\377\37\37" + "\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377<(\32\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\37\37\37\377\37\37\37\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\362d\1\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37" + "\37\377\37\37\37\377\37\37\37\377\37\37\37\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\37\37\37\377\37\37\37" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377" + "\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37" + "\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\326[\5\3771$\34\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37" + "\377\37\37\37\377\37\37\37\377\37\37\37\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\37\37\37\377\37\37" + "\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377" + "\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37" + "\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37" + "\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377\37\37\37\377" + "\37\37\37\377\37\37\37\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36" + "\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36" + "\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377" + "\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377" + "\36\36\36\3776&\32\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\36\36\36\377\36\36\36\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\360c\1\377\36\36\36\377\36\36" + "\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\36\36\36\377\36\36\36\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\36\36\36\377\36\36\36\377\36\36\36\377" + "\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36" + "\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36" + "\36\36\377\36\36\36\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h" + "\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\332\\\4\3774%\32\377\36\36\36" + "\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377" + "\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36" + "\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36" + "\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377" + "\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\35\35\35\377\35\35\35" + "\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35" + "\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377" + "\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35" + "\377\35\35\35\377\35\35\35\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\35\35\35\377\35\35\35\377\35\35\35\377" + "\35\35\35\377\35\35\35\377\35\35\35\3770#\32\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\35\35\35\377\35\35\35" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\357" + "b\1\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377" + "\35\35\35\377\35\35\35\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\35\35\35\377\35\35\35\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\35\35\35\377" + "\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35" + "\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35" + "\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\337]\3\3776%\31\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35" + "\377\35\35\35\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35" + "\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377" + "\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35" + "\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35" + "\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377\35\35\35\377" + "\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34" + "\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34" + "\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377" + "\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\34\34\34\377\34\34" + "\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377)\40\32\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\34\34\34\377\34\34\34\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\356b\1\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34" + "\34\377\34\34\34\377\34\34\34\377\34\34\34\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\34\34\34\377\34\34\34" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377" + "\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34" + "\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\342]\3\3779%\30\377\34\34\34\377\34" + "\34\34\377\34\34\34\377\34\34\34\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\34\34\34\377\34\34\34\377" + "\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34" + "\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34" + "\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377" + "\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34\377\34\34\34" + "\377\34\34\34\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33" + "\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377" + "\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33" + "\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33" + "\377#\35\31\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\33\33\33\377\33\33\33\377\234G\13\377\377h\0\377\377h" + "\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\227D\14\377\33\33\33\377" + "\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\33" + "\33\33\377\33\33\33\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h" + "\0\377\377h\0\377\377h\0\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33" + "\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377" + "\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33" + "\377\33\33\33\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377+\40\30\377+\40\30\377+\40\30\377+\40\30\377P-\24\377" + "\356a\1\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\345^\2" + "\377<&\26\377\33\33\33\377\33\33\33\377\33\33\33\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\33\33\33\377\33\33" + "\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33" + "\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377" + "\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33" + "\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\33" + "\33\33\377\33\33\33\377\33\33\33\377\33\33\33\377\32\32\32\377\32\32\32\377" + "\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32" + "\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32" + "\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377" + "\32\32\32\377\32\32\32\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32" + "\32\377\32\32\32\377\32\32\32\377\33\32\31\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\32\32\32\377\32\32\32" + "\377\32\32\32\377\231E\13\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\230D\13\377\32\32\32\377\32\32\32\377\32\32\32\377" + "\32\32\32\377\32\32\32\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\32\32\32\377\32\32\32\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\32\32\32\377" + "\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32" + "\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32" + "\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\32\32\32\377\32\32\32" + "\377\32\32\32\377\32\32\32\377\32\32\32\377C'\25\377\353`\2\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\351`\2\377?'\25\377\32\32\32" + "\377\32\32\32\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377" + "\32\32\32\377\32\32\32\377\32\32\32\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\32\32\32\377\32\32\32\377\32" + "\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377" + "\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32" + "\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32" + "\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377\32\32\32\377" + "\32\32\32\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31" + "\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\31" + "\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377" + "\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\227D\13\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\31\31\31\377\31\31\31\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\311T\5\377\31\31\31\377\31\31\31\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\31\31\31\377\31\31\31\377\31\31" + "\31\377\31\31\31\377\31\31\31\377\31\31\31\377N*\23\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\354a\1\377\31\31\31\377" + "\31\31\31\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\31" + "\31\31\377\31\31\31\377\31\31\31\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\31\31\31\377\31\31\31\377\31\31" + "\31\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377" + "\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31" + "\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\31" + "\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377\31\31\31\377" + "\31\31\31\377\30\30\27\377\27\27\27\377\30\30\27\377\27\27\30\377\27\30\30" + "\377\27\30\27\377\27\30\27\377\30\27\30\377\27\27\27\377\27\27\30\377\27" + "\27\27\377\27\30\27\377\30\27\27\377\27\30\27\377\30\27\30\377\27\27\27\377" + "\27\27\27\377\27\27\27\377\30\27\27\377\27\30\30\377\27\27\27\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\27\27\27\377\27\27\27\377\30\30\30\377\27\27\27\377\30\27\30\377\224" + "B\12\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\27\27\30\377\27\27\30\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\310T\5\377\27\27\27\377\30\27\27\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\27\27\27\377\30\30\27\377\30\30" + "\27\377\30\30\27\377\27\30\27\377\30\27\27\3772\40\24\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\27\27\27\377" + "\30\30\27\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\30\30\30\377\27\30\27\377\27\27\27\377\27\30\30\377\30" + "\27\30\377\27\27\30\377\30\27\30\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\30\27\27\377\30\27\27\377\27\27" + "\30\377\27\27\27\377\30\30\27\377\27\27\27\377\27\30\27\377\27\27\30\377" + "\27\27\27\377\30\27\27\377\27\27\30\377\27\30\27\377\30\27\27\377\27\27\30" + "\377\30\30\27\377\27\30\27\377\27\30\27\377\27\27\27\377\30\27\27\377\30" + "\27\27\377\27\27\27\377\27\27\30\377\27\27\27\377\27\30\27\377\27\27\27\377" + "\27\27\30\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26" + "\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26" + "\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377" + "\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26" + "\26\26\377\220@\12\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\26\26\26\377\26\26\26" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\310T\5\377\26\26\26\377\26\26\26\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\26\26\26\377\26\26\26\377\26" + "\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377)\34\24\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\26\26\26\377" + "\26\26\26\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26" + "\26\26\377\26\26\26\377\26\26\26\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\26\26\26\377\26\26\26\377\26\26" + "\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377" + "\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26" + "\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26" + "\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377\26\26\26\377" + "\26\26\26\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25" + "\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25" + "\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377" + "\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25" + "\25\25\377\25\25\25\377\215?\12\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\25\25\25\377\25\25" + "\25\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\310T\4\377\25\25\25\377\25\25\25\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\25\25\25\377\25\25\25\377" + "\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\40\30\23\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\25" + "\25\25\377\25\25\25\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h" + "\0\377\377h\0\377\377h\0\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25" + "\25\377\25\25\25\377\25\25\25\377\25\25\25\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\25\25\25\377\25\25\25" + "\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25" + "\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377" + "\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25" + "\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25\25\25\377\25" + "\25\25\377\25\25\25\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377" + "\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24" + "\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24" + "\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24" + "\377\24\24\24\377\24\24\24\377\24\24\24\377\212>\11\377\377h\0\377\377h\0" + "\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\24\24\24\377" + "\24\24\24\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377" + "h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\377h\0\377\307S\4\377\24\24\24\377\24\24\24\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\24\24\24\377\24\24" + "\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\26\25\23\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0" + "\377\24\24\24\377\24\24\24\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\24\24\24\377\24\24\24\377\24\24\24\377" + "\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\377h\0\377\377h\0\377" + "\377h\0\377\377h\0\377\377h\0\377\377h\0\377\377h\0\377\24\24\24\377\24\24" + "\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377" + "\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24" + "\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24" + "\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377\24\24\24\377" + "\24\24\24\377\24\24\24\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23" + "\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377" + "\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23\377\23\23\23" + "\377\23\23\23\377\23\23\23\377\23\23\23\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377" + "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" + "\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" + "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21" + "\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377" + "\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21\377\21\21\21" + "\377", +}; +