diff --git a/Makefile.in b/Makefile.in index bcd937dba..e1484a11d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. +# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. @@ -85,7 +85,7 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ autotools/ar-lib autotools/compile autotools/config.guess \ autotools/config.rpath autotools/config.sub autotools/depcomp \ autotools/install-sh autotools/missing autotools/ltmain.sh \ - $(top_srcdir)/autotools/ar-lib $(top_srcdir)/autotools/compile \ + $(top_srcdir)/autotools/ar-lib \ $(top_srcdir)/autotools/config.guess \ $(top_srcdir)/autotools/config.rpath \ $(top_srcdir)/autotools/config.sub \ @@ -355,6 +355,8 @@ LIBOBJS = @LIBOBJS@ LIBRESAMPLE_CFLAGS = @LIBRESAMPLE_CFLAGS@ LIBRESAMPLE_LIBS = @LIBRESAMPLE_LIBS@ LIBS = @LIBS@ +LIBSAMPLERATE_SYSTEM_CFLAGS = @LIBSAMPLERATE_SYSTEM_CFLAGS@ +LIBSAMPLERATE_SYSTEM_LIBS = @LIBSAMPLERATE_SYSTEM_LIBS@ LIBTOOL = @LIBTOOL@ LIBTWOLAME_CFLAGS = @LIBTWOLAME_CFLAGS@ LIBTWOLAME_LIBS = @LIBTWOLAME_LIBS@ @@ -844,16 +846,10 @@ dist-xz: distdir $(am__post_remove_distdir) dist-tarZ: distdir - @echo WARNING: "Support for shar distribution archives is" \ - "deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir - @echo WARNING: "Support for distribution archives compressed with" \ - "legacy program 'compress' is deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) @@ -895,10 +891,9 @@ distcheck: dist && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ - && ../configure \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ diff --git a/configure b/configure index 413e0e2eb..c9d0e9a9a 100755 --- a/configure +++ b/configure @@ -19702,6 +19702,8 @@ WX_LIBS=$($WX_CONFIG $wxconfigargs --libs) ac_configure_args="$ac_configure_args --enable-static=yes --enable-shared=no" +CXXFLAGS="$CXXFLAGS -I\$(top_srcdir)/include" + subdirs="$subdirs lib-src/FileDialog" @@ -23812,8 +23814,7 @@ $as_echo "#define HAVE_GTK 1" >>confdefs.h LIBS="$LIBS $GTK_LIBS" fi - use_vst="no" - ;; + ;; esac diff --git a/configure.ac b/configure.ac index 00952c9d4..8e11d944e 100644 --- a/configure.ac +++ b/configure.ac @@ -322,6 +322,9 @@ dnl Pull in library Cflags and so on for the non-optional libraries dnl All libraries in lib-src should build static libraries, but not shared ones. ac_configure_args="$ac_configure_args --enable-static=yes --enable-shared=no" +dnl Include "external" headers +CXXFLAGS="$CXXFLAGS -I\$(top_srcdir)/include" + dnl Include FileDialog AC_CONFIG_SUBDIRS([lib-src/FileDialog]) CXXFLAGS="$CXXFLAGS -I\$(top_srcdir)/lib-src/FileDialog" @@ -625,7 +628,7 @@ case "${host_os}" in dnl VST support on platforms other than Mac OS and Windows not enabled for dnl 2.0.6 release - use_vst="no" + dnl use_vst="no" ;; esac diff --git a/images/Arrow.xpm b/images/Arrow.xpm index 929739ab4..496821a25 100644 --- a/images/Arrow.xpm +++ b/images/Arrow.xpm @@ -20,231 +20,3 @@ static const char * arrow_xpm[] = { "....+....", ".........", "........."}; - -static const char * empty_9x16_xpm[] = { -"9 16 2 1", -"# c #000000", -". c #FFFFFF", -".........", -".........", -".........", -".........", -".........", -".........", -".........", -".........", -".........", -".........", -".........", -".........", -".........", -".........", -".........", -"........."}; - -/* XPM */ -static const char * arrow15x15_xpm[] = { -"15 15 24 1", -" c None", -". c #FFFFFF", -"+ c #929292", -"@ c #000000", -"# c #9F9F9F", -"$ c #262626", -"% c #D8D8D8", -"& c #5F5F5F", -"* c #FEFEFE", -"= c #4F4F4F", -"- c #888888", -"; c #808080", -"> c #828282", -", c #2A2A2A", -"' c #7F7F7F", -") c #D5D5D5", -"! c #111111", -"~ c #646464", -"{ c #B8B8B8", -"] c #989898", -"^ c #3A3A3A", -"/ c #9B9B9B", -"( c #EDEDED", -"_ c #C9C9C9", -"...............", -"...............", -"...............", -"......+@+......", -"......#@@$%....", -"......#@@@@&*..", -"@@@@@@@@@@@@@#.", -"@@@@@@@@@@@@@@@", -"@@@@@@@@@@@@@=-", -";;;;>-=@@@@,').", -"......#@@!~{*..", -"......]@^/(....", -"......_;_......", -"...............", -"..............."}; - -/* XPM */ -static const char * unchecked_xpm[] = { -"15 15 56 1", -" c None", -". c #FFFFFF", -"+ c #8E8F8F", -"@ c #F4F4F4", -"# c #AEB3B9", -"$ c #AFB4BA", -"% c #B4B9BD", -"& c #BBBEC1", -"* c #CBCFD5", -"= c #D0D3D8", -"- c #D5D8DC", -"; c #DBDDDF", -"> c #C1C3C5", -", c #CDD1D6", -"' c #D2D5DA", -") c #D8DBDE", -"! c #DDDFE1", -"~ c #E2E3E4", -"{ c #C6C7C8", -"] c #CDD1D7", -"^ c #D0D4D9", -"/ c #D4D7DB", -"( c #E1E2E3", -"_ c #E5E6E6", -": c #E8E8E8", -"< c #CCCDCD", -"[ c #B2B7BC", -"} c #DADCDF", -"| c #E0E1E3", -"1 c #ECECEC", -"2 c #EDEDED", -"3 c #D4D5D6", -"4 c #B8BBBF", -"5 c #E4E5E5", -"6 c #EAEAEA", -"7 c #EFEFEF", -"8 c #F2F2F2", -"9 c #DCDDDE", -"0 c #BCBFC2", -"a c #E3E4E5", -"b c #E9E9E9", -"c c #F5F5F5", -"d c #E1E2E2", -"e c #C2C4C6", -"f c #F0F0F0", -"g c #F6F6F6", -"h c #E6E6E6", -"i c #CACBCC", -"j c #D4D4D5", -"k c #DBDBDC", -"l c #E0E1E1", -"m c #E6E7E7", -"n c #EAEBEB", -"o c #EBECEC", -"p c #EBEBEC", -"q c #E9E9EA", -"...............", -".+++++++++++++.", -".+@@@@@@@@@@@+.", -".+@######$%&@+.", -".+@#****=-;>@+.", -".+@#**,')!~{@+.", -".+@#]^/;(_:<@+.", -".+@[-}|:1223@+.", -".+@4!5678889@+.", -".+@0ab28@c@d@+.", -".+@eb2f@gggh@+.", -".+@ijklmnopq@+.", -".+@@@@@@@@@@@+.", -".+++++++++++++.", -"..............."}; - -/* XPM */ -static const char * checked_xpm[] = { -"15 15 70 1", -" c #FFFFFF", -". c #8E8F8F", -"+ c #F4F4F4", -"@ c #F8F8F8", -"# c #F9F9F9", -"$ c #F6F6F6", -"% c #AEB3B9", -"& c #C9CCD0", -"* c #76DB7E", -"= c #45CE4F", -"- c #DCDFE4", -"; c #F5F5F5", -"> c #CBCFD5", -", c #C9D3D2", -"' c #EBEFEF", -") c #2EAF37", -"! c #289730", -"~ c #9CE5A2", -"{ c #CDD1D6", -"] c #E0E2E6", -"^ c #90E196", -"/ c #3DB351", -"( c #E4EAE5", -"_ c #ADB5B7", -": c #D5D9DD", -"< c #DFE2E5", -"[ c #D5D8DC", -"} c #EFF5F1", -"| c #30B93A", -"1 c #289B31", -"2 c #A1E6A6", -"3 c #DBDCDC", -"4 c #C5C9CD", -"5 c #B3EAB7", -"6 c #87D693", -"7 c #E9F1EA", -"8 c #A0E5A5", -"9 c #299E32", -"0 c #33C23D", -"a c #D5D5D6", -"b c #CDF2D0", -"c c #3ACB45", -"d c #299A33", -"e c #BFE9C6", -"f c #33C43E", -"g c #2A9F32", -"h c #9BE4A0", -"i c #F5F7F5", -"j c #DCDDDE", -"k c #C8D4CC", -"l c #D0EFD5", -"m c #299C31", -"n c #32BD3C", -"o c #F7FAF9", -"p c #DFE4E0", -"q c #C6C8CA", -"r c #E5F0E9", -"s c #62D56A", -"t c #2BA233", -"u c #93E299", -"v c #F7F9F8", -"w c #E5E7E5", -"x c #CACBCC", -"y c #D9DBDA", -"z c #DEE3E8", -"A c #76C38B", -"B c #F2F3F6", -"C c #ECEDED", -"D c #EBEBEC", -"E c #E9E9EA", -" ", -" ............. ", -" .+++++++@#$+. ", -" .+%%%%%&*=-;. ", -" .+%>>>,')!~$. ", -" .+%>>{]^!/(+. ", -" .+_:<[}|123+. ", -" .+4567890@a+. ", -" .+bcdefghij+. ", -" .+klm9gno+p+. ", -" .+qrs9tuv$w+. ", -" .+xyzsABCDE+. ", -" .+++;#@;++++. ", -" ............. ", -" "}; diff --git a/images/Arrow15x15.xpm b/images/Arrow15x15.xpm new file mode 100644 index 000000000..88718d64b --- /dev/null +++ b/images/Arrow15x15.xpm @@ -0,0 +1,42 @@ +/* XPM */ +static const char * arrow15x15_xpm[] = { +"15 15 24 1", +" c None", +". c #FFFFFF", +"+ c #929292", +"@ c #000000", +"# c #9F9F9F", +"$ c #262626", +"% c #D8D8D8", +"& c #5F5F5F", +"* c #FEFEFE", +"= c #4F4F4F", +"- c #888888", +"; c #808080", +"> c #828282", +", c #2A2A2A", +"' c #7F7F7F", +") c #D5D5D5", +"! c #111111", +"~ c #646464", +"{ c #B8B8B8", +"] c #989898", +"^ c #3A3A3A", +"/ c #9B9B9B", +"( c #EDEDED", +"_ c #C9C9C9", +"...............", +"...............", +"...............", +"......+@+......", +"......#@@$%....", +"......#@@@@&*..", +"@@@@@@@@@@@@@#.", +"@@@@@@@@@@@@@@@", +"@@@@@@@@@@@@@=-", +";;;;>-=@@@@,').", +"......#@@!~{*..", +"......]@^/(....", +"......_;_......", +"...............", +"..............."}; diff --git a/images/Checked.xpm b/images/Checked.xpm new file mode 100644 index 000000000..3a518ffda --- /dev/null +++ b/images/Checked.xpm @@ -0,0 +1,88 @@ +/* XPM */ +static const char * checked_xpm[] = { +"15 15 70 1", +" c #FFFFFF", +". c #8E8F8F", +"+ c #F4F4F4", +"@ c #F8F8F8", +"# c #F9F9F9", +"$ c #F6F6F6", +"% c #AEB3B9", +"& c #C9CCD0", +"* c #76DB7E", +"= c #45CE4F", +"- c #DCDFE4", +"; c #F5F5F5", +"> c #CBCFD5", +", c #C9D3D2", +"' c #EBEFEF", +") c #2EAF37", +"! c #289730", +"~ c #9CE5A2", +"{ c #CDD1D6", +"] c #E0E2E6", +"^ c #90E196", +"/ c #3DB351", +"( c #E4EAE5", +"_ c #ADB5B7", +": c #D5D9DD", +"< c #DFE2E5", +"[ c #D5D8DC", +"} c #EFF5F1", +"| c #30B93A", +"1 c #289B31", +"2 c #A1E6A6", +"3 c #DBDCDC", +"4 c #C5C9CD", +"5 c #B3EAB7", +"6 c #87D693", +"7 c #E9F1EA", +"8 c #A0E5A5", +"9 c #299E32", +"0 c #33C23D", +"a c #D5D5D6", +"b c #CDF2D0", +"c c #3ACB45", +"d c #299A33", +"e c #BFE9C6", +"f c #33C43E", +"g c #2A9F32", +"h c #9BE4A0", +"i c #F5F7F5", +"j c #DCDDDE", +"k c #C8D4CC", +"l c #D0EFD5", +"m c #299C31", +"n c #32BD3C", +"o c #F7FAF9", +"p c #DFE4E0", +"q c #C6C8CA", +"r c #E5F0E9", +"s c #62D56A", +"t c #2BA233", +"u c #93E299", +"v c #F7F9F8", +"w c #E5E7E5", +"x c #CACBCC", +"y c #D9DBDA", +"z c #DEE3E8", +"A c #76C38B", +"B c #F2F3F6", +"C c #ECEDED", +"D c #EBEBEC", +"E c #E9E9EA", +" ", +" ............. ", +" .+++++++@#$+. ", +" .+%%%%%&*=-;. ", +" .+%>>>,')!~$. ", +" .+%>>{]^!/(+. ", +" .+_:<[}|123+. ", +" .+4567890@a+. ", +" .+bcdefghij+. ", +" .+klm9gno+p+. ", +" .+qrs9tuv$w+. ", +" .+xyzsABCDE+. ", +" .+++;#@;++++. ", +" ............. ", +" "}; diff --git a/images/EditButtons/Effects.xpm b/images/EditButtons/Effects.xpm new file mode 100644 index 000000000..7d194be2a --- /dev/null +++ b/images/EditButtons/Effects.xpm @@ -0,0 +1,105 @@ +/* XPM */ +static const char *Effects_xpm[] = { +"26 24 78 1", +" c None", +". c #FFFFFF", +"+ c #F2F2F2", +"@ c #A1A1A1", +"# c #555555", +"$ c #545454", +"% c #9B9B9B", +"& c #FDFDFD", +"* c #BDBDBD", +"= c #000000", +"- c #353535", +"; c #515151", +"> c #9F9F9F", +", c #FAFAFA", +"' c #1E1E1E", +") c #0D0D0D", +"! c #D7D7D7", +"~ c #3C3C3C", +"{ c #E7E7E7", +"] c #3F3F3F", +"^ c #262626", +"/ c #D0D0D0", +"( c #363636", +"_ c #8B8B8B", +": c #EBEBEB", +"< c #090909", +"[ c #DEDEDE", +"} c #5F5F5F", +"| c #464646", +"1 c #494949", +"2 c #565656", +"3 c #E8E8E8", +"4 c #F8F8F8", +"5 c #5C5C5C", +"6 c #3A3A3A", +"7 c #080808", +"8 c #535353", +"9 c #F3F3F3", +"0 c #181818", +"a c #FCFCFC", +"b c #030303", +"c c #E5E5E5", +"d c #A0A0A0", +"e c #848484", +"f c #E6E6E6", +"g c #2A2A2A", +"h c #444444", +"i c #878787", +"j c #909090", +"k c #505050", +"l c #696969", +"m c #B2B2B2", +"n c #B5B5B5", +"o c #D5D5D5", +"p c #575757", +"q c #E2E2E2", +"r c #7E7E7E", +"s c #5B5B5B", +"t c #525252", +"u c #101010", +"v c #FEFEFE", +"w c #292929", +"x c #AFAFAF", +"y c #A4A4A4", +"z c #F5F5F5", +"A c #F4F4F4", +"B c #282828", +"C c #F6F6F6", +"D c #4F4F4F", +"E c #A9A9A9", +"F c #323232", +"G c #ECECEC", +"H c #CFCFCF", +"I c #7D7D7D", +"J c #727272", +"K c #C9C9C9", +"L c #C7C7C7", +"M c #CECECE", +" ", +" ", +" +@#$% ", +" &*=-===; ", +" >==,'==) ", +" !==~ {]^/ ", +" (==_ ", +" :<==[ ", +" }#|===1#23 ", +" 45#6==78$59 ", +" 8==0a ", +" b==- cd)e fgh ", +" :===i j= klm ", +" n===o =pq ", +" r=== 's ", +" t==k u~ ", +" cvv w==x v4 5y7z ", +" }==A ==Bv =bC!=DE ", +" ===F>=', G H ", +" I====JA ", +" KLM ", +" ", +" ", +" "}; diff --git a/images/EffectRack/EffectRack.h b/images/EffectRack/EffectRack.h new file mode 100644 index 000000000..11ce4015d --- /dev/null +++ b/images/EffectRack/EffectRack.h @@ -0,0 +1,9 @@ +#include "down-9x16.xpm" +#include "fav-down-16x16.xpm" +#include "fav-up-16x16.xpm" +#include "power-off-16x16.xpm" +#include "power-on-16x16.xpm" +#include "remove-16x16.xpm" +#include "settings-down-16x16.xpm" +#include "settings-up-16x16.xpm" +#include "up-9x16.xpm" diff --git a/images/EffectRack/down-9x16.xpm b/images/EffectRack/down-9x16.xpm new file mode 100644 index 000000000..c658eda4b --- /dev/null +++ b/images/EffectRack/down-9x16.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char *down_9x16_xpm[] = { +"9 16 2 1", +" c None", +". c #000000", +" ", +" ", +" ... ", +" ... ", +" ... ", +" ... ", +" ... ", +" ... ", +".........", +" ....... ", +" ..... ", +" ... ", +" . ", +" ", +" ", +" "}; diff --git a/images/EffectRack/fav-down-16x16.xpm b/images/EffectRack/fav-down-16x16.xpm new file mode 100644 index 000000000..102e1fa1c --- /dev/null +++ b/images/EffectRack/fav-down-16x16.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char *fav_down_16x16_xpm[] = { +"16 16 2 1", +" c None", +". c #000000", +" ", +" ..... ", +" ..... ", +" ... ", +" ... ", +" ... ", +" ... ", +" ..... ", +" ....... ", +" . ", +" . ", +" . ", +" . ", +" . ", +" . ", +" . "}; diff --git a/images/EffectRack/fav-up-16x16.xpm b/images/EffectRack/fav-up-16x16.xpm new file mode 100644 index 000000000..e612760a1 --- /dev/null +++ b/images/EffectRack/fav-up-16x16.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char *fav_up_16x16_xpm[] = { +"16 16 2 1", +" c None", +". c #000000", +" ", +" ", +" ", +" ", +" . ", +" .. .. ", +" ........ ", +"............... ", +" ........ ", +" .. .. ", +" . ", +" ", +" ", +" ", +" ", +" "}; diff --git a/images/EffectRack/power-off-16x16.xpm b/images/EffectRack/power-off-16x16.xpm new file mode 100644 index 000000000..afaf45bd4 --- /dev/null +++ b/images/EffectRack/power-off-16x16.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static const char *power_off_16x16_xpm[] = { +"16 16 4 1", +" c None", +"a c #FF0000", +"b c #000000", +"c c #707070", +" aa aaaa aaaa ", +" a a a a ", +" a a aaa aaa ", +" a a a a ", +" aa a a ", +" ", +" ", +" bb ", +" bbbccc ", +" bbbccc ", +" cbbbcc ", +" ccbbbc ", +" cccbbb ", +" cccbbb ", +" bb ", +" "}; diff --git a/images/EffectRack/power-on-16x16.xpm b/images/EffectRack/power-on-16x16.xpm new file mode 100644 index 000000000..b4ac365f4 --- /dev/null +++ b/images/EffectRack/power-on-16x16.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static const char *power_on_16x16_xpm[] = { +"16 16 4 1", +" c None", +"a c #00FF00", +"b c #000000", +"c c #707070", +" aa a a ", +" a a aa a ", +" a a a a a ", +" a a a aa ", +" aa a a ", +" ", +" ", +" bb ", +" cccbbb ", +" cccbbb ", +" ccbbbc ", +" cbbbcc ", +" bbbccc ", +" bbbccc ", +" bb ", +" "}; diff --git a/images/EffectRack/remove-16x16.xpm b/images/EffectRack/remove-16x16.xpm new file mode 100644 index 000000000..8d3f331f0 --- /dev/null +++ b/images/EffectRack/remove-16x16.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char *remove_16x16_xpm[] = { +"16 16 2 1", +" c None", +". c #FF0000", +" ", +" .... ", +" ........ ", +" .......... ", +" ............ ", +" .... .. ... ", +" .... .... ", +" ..... ..... ", +" ...... ...... ", +" .... .... ", +" .... .. .... ", +" ............ ", +" .......... ", +" ........ ", +" ...... ", +" "}; diff --git a/images/EffectRack/settings-down-16x16.xpm b/images/EffectRack/settings-down-16x16.xpm new file mode 100644 index 000000000..1b21d5441 --- /dev/null +++ b/images/EffectRack/settings-down-16x16.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static const char *settings_down_16x16_xpm[] = { +"16 16 3 1", +" c None", +". c #020202", +"+ c #010101", +" .+. ", +" +++ ", +" +++ ", +".. +++ .........", +" +++ ", +" .+. .+. ", +" +++ ", +"......... +++ ..", +"......... +++ ..", +" +++ ", +" .+. .+. ", +" +++ ", +" +++ ", +".. +++ .........", +" +++ ", +" .+. "}; diff --git a/images/EffectRack/settings-up-16x16.xpm b/images/EffectRack/settings-up-16x16.xpm new file mode 100644 index 000000000..7b5290c12 --- /dev/null +++ b/images/EffectRack/settings-up-16x16.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static const char *settings_up_16x16_xpm[] = { +"16 16 3 1", +" c None", +". c #020202", +"+ c #010101", +" .+. ", +" +++ ", +" +++ ", +"......... +++ ..", +" +++ ", +" .+. .+. ", +" +++ ", +".. +++ .........", +".. +++ .........", +" +++ ", +" .+. .+. ", +" +++ ", +" +++ ", +"......... +++ ..", +" +++ ", +" .+. "}; diff --git a/images/EffectRack/up-9x16.xpm b/images/EffectRack/up-9x16.xpm new file mode 100644 index 000000000..7ae59a868 --- /dev/null +++ b/images/EffectRack/up-9x16.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char *up_9x16_xpm[] = { +"9 16 2 1", +" c None", +". c #000000", +" ", +" ", +" ", +" . ", +" ... ", +" ..... ", +" ....... ", +".........", +" ... ", +" ... ", +" ... ", +" ... ", +" ... ", +" ... ", +" ", +" "}; diff --git a/images/Empty9x16.xpm b/images/Empty9x16.xpm new file mode 100644 index 000000000..48cfef414 --- /dev/null +++ b/images/Empty9x16.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char * empty9x16_xpm[] = { +"9 16 2 1", +"# c #000000", +". c #FFFFFF", +".........", +".........", +".........", +".........", +".........", +".........", +".........", +".........", +".........", +".........", +".........", +".........", +".........", +".........", +".........", +"........."}; diff --git a/images/Unchecked.xpm b/images/Unchecked.xpm new file mode 100644 index 000000000..7baa85be7 --- /dev/null +++ b/images/Unchecked.xpm @@ -0,0 +1,74 @@ +/* XPM */ +static const char * unchecked_xpm[] = { +"15 15 56 1", +" c None", +". c #FFFFFF", +"+ c #8E8F8F", +"@ c #F4F4F4", +"# c #AEB3B9", +"$ c #AFB4BA", +"% c #B4B9BD", +"& c #BBBEC1", +"* c #CBCFD5", +"= c #D0D3D8", +"- c #D5D8DC", +"; c #DBDDDF", +"> c #C1C3C5", +", c #CDD1D6", +"' c #D2D5DA", +") c #D8DBDE", +"! c #DDDFE1", +"~ c #E2E3E4", +"{ c #C6C7C8", +"] c #CDD1D7", +"^ c #D0D4D9", +"/ c #D4D7DB", +"( c #E1E2E3", +"_ c #E5E6E6", +": c #E8E8E8", +"< c #CCCDCD", +"[ c #B2B7BC", +"} c #DADCDF", +"| c #E0E1E3", +"1 c #ECECEC", +"2 c #EDEDED", +"3 c #D4D5D6", +"4 c #B8BBBF", +"5 c #E4E5E5", +"6 c #EAEAEA", +"7 c #EFEFEF", +"8 c #F2F2F2", +"9 c #DCDDDE", +"0 c #BCBFC2", +"a c #E3E4E5", +"b c #E9E9E9", +"c c #F5F5F5", +"d c #E1E2E2", +"e c #C2C4C6", +"f c #F0F0F0", +"g c #F6F6F6", +"h c #E6E6E6", +"i c #CACBCC", +"j c #D4D4D5", +"k c #DBDBDC", +"l c #E0E1E1", +"m c #E6E7E7", +"n c #EAEBEB", +"o c #EBECEC", +"p c #EBEBEC", +"q c #E9E9EA", +"...............", +".+++++++++++++.", +".+@@@@@@@@@@@+.", +".+@######$%&@+.", +".+@#****=-;>@+.", +".+@#**,')!~{@+.", +".+@#]^/;(_:<@+.", +".+@[-}|:1223@+.", +".+@4!5678889@+.", +".+@0ab28@c@d@+.", +".+@eb2f@gggh@+.", +".+@ijklmnopq@+.", +".+@@@@@@@@@@@+.", +".+++++++++++++.", +"..............."}; diff --git a/include/audacity/ConfigInterface.h b/include/audacity/ConfigInterface.h new file mode 100644 index 000000000..81cfdcf13 --- /dev/null +++ b/include/audacity/ConfigInterface.h @@ -0,0 +1,88 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + ConfigInterface.h + + Leland Lucius + + Copyright (c) 2014, Audacity Team + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +**********************************************************************/ + +#ifndef __AUDACITY_CONFIGINTERFACE_H__ +#define __AUDACITY_CONFIGINTERFACE_H__ + +#include "audacity/Types.h" + +class ConfigClientInterface +{ +public: + virtual ~ConfigClientInterface() {}; + + virtual bool GetSharedConfig(const wxString & group, const wxString & key, wxString & value, const wxString & defval) = 0; + virtual bool GetSharedConfig(const wxString & group, const wxString & key, int & value, int defval) = 0; + virtual bool GetSharedConfig(const wxString & group, const wxString & key, bool & value, bool defval) = 0; + virtual bool GetSharedConfig(const wxString & group, const wxString & key, float & value, float defval) = 0; + virtual bool GetSharedConfig(const wxString & group, const wxString & key, double & value, double defval) = 0; + virtual bool GetSharedConfig(const wxString & group, const wxString & key, sampleCount & value, sampleCount defval) = 0; + + virtual bool SetSharedConfig(const wxString & group, const wxString & key, const wxString & value) = 0; + virtual bool SetSharedConfig(const wxString & group, const wxString & key, const int & value) = 0; + virtual bool SetSharedConfig(const wxString & group, const wxString & key, const bool & value) = 0; + virtual bool SetSharedConfig(const wxString & group, const wxString & key, const float & value) = 0; + virtual bool SetSharedConfig(const wxString & group, const wxString & key, const double & value) = 0; + virtual bool SetSharedConfig(const wxString & group, const wxString & key, const sampleCount & value) = 0; + + virtual bool GetPrivateConfig(const wxString & group, const wxString & key, wxString & value, const wxString & defval) = 0; + virtual bool GetPrivateConfig(const wxString & group, const wxString & key, int & value, int defval) = 0; + virtual bool GetPrivateConfig(const wxString & group, const wxString & key, bool & value, bool defval) = 0; + virtual bool GetPrivateConfig(const wxString & group, const wxString & key, float & value, float defval) = 0; + virtual bool GetPrivateConfig(const wxString & group, const wxString & key, double & value, double defval) = 0; + virtual bool GetPrivateConfig(const wxString & group, const wxString & key, sampleCount & value, sampleCount defval) = 0; + + virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const wxString & value) = 0; + virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const int & value) = 0; + virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const bool & value) = 0; + virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const float & value) = 0; + virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const double & value) = 0; + virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const sampleCount & value) = 0; +}; + +class ConfigHostInterface +{ +public: + virtual ~ConfigHostInterface() {}; + +}; + +#endif // __AUDACITY_CONFIGINTERFACE_H__ diff --git a/include/audacity/EffectInterface.h b/include/audacity/EffectInterface.h new file mode 100644 index 000000000..b2d147465 --- /dev/null +++ b/include/audacity/EffectInterface.h @@ -0,0 +1,145 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + EffectInterface.h + + Leland Lucius + + Copyright (c) 2014, Audacity Team + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +**********************************************************************/ + +#ifndef __AUDACITY_EFFECTINTERFACE_H__ +#define __AUDACITY_EFFECTINTERFACE_H__ + +#include + +#include "audacity/Types.h" +#include "audacity/IdentInterface.h" +#include "audacity/ConfigInterface.h" + +typedef enum EffectType +{ + EffectTypeNone, + EffectTypeGenerate, + EffectTypeProcess, + EffectTypeAnalyze +} EffectType; + +class EffectIdentInterface : public IdentInterface +{ +public: + virtual ~EffectIdentInterface() {}; + + virtual EffectType GetType() = 0; + virtual wxString GetFamily() = 0; + + // These should move to the "EffectClientInterface" class once all + // effects have bee converted. + virtual bool IsInteractive() = 0; + + // I don't really like this, but couldn't think of a better way to force the + // effect to appear "above the line" in the menus. + virtual bool IsDefault() = 0; + + // This will go away when all Effects have been updated to the new + // interface. + virtual bool IsLegacy() = 0; + + // Whether the effect supports realtime processing (while audio is playing). + virtual bool IsRealtimeCapable() = 0; +}; + +class EffectHostInterface : public EffectIdentInterface, + public ConfigClientInterface +{ +public: + virtual ~EffectHostInterface() {}; + + // Both of these are pretty much hacks until everything has been converted and + // it's decided if the client will display the interface or if that'll be done + // by the host. + virtual bool Apply() = 0; + virtual void Preview() = 0; +}; + +typedef float * pfloat; +typedef std::vector pvec; + +class EffectClientInterface : public EffectIdentInterface +{ +public: + virtual ~EffectClientInterface() {}; + + virtual void SetHost(EffectHostInterface *host) = 0; + virtual bool Startup() = 0; + virtual bool Shutdown() = 0; + + virtual int GetAudioInCount() = 0; + virtual int GetAudioOutCount() = 0; + + virtual int GetMidiInCount() = 0; + virtual int GetMidiOutCount() = 0; + + virtual void SetSampleRate(sampleCount rate) = 0; + virtual sampleCount GetBlockSize(sampleCount maxBlockSize) = 0; + + virtual sampleCount GetLatency() = 0; + virtual sampleCount GetTailSize() = 0; + + virtual bool IsReady() = 0; + virtual bool ProcessInitialize() = 0; + virtual bool ProcessFinalize() = 0; + virtual sampleCount ProcessBlock(float **inbuf, float **outbuf, sampleCount size) = 0; + + virtual bool RealtimeInitialize(int numChannels, float sampleRate) = 0; + virtual bool RealtimeFinalize() = 0; + virtual bool RealtimeSuspend() = 0; + virtual bool RealtimeResume() = 0; + virtual sampleCount RealtimeProcess(float **inbuf, float **outbuf, sampleCount size) = 0; + + virtual bool ShowInterface(void *parent) = 0; +}; + +class EffectManagerInterface +{ +public: + virtual ~EffectManagerInterface() {}; + + virtual void FindFilesInPathList(const wxString & pattern, + const wxArrayString & pathList, + wxArrayString & files, + int searchFlags) = 0; +}; + +#endif // __AUDACITY_EFFECTINTERFACE_H__ diff --git a/include/audacity/IdentInterface.h b/include/audacity/IdentInterface.h new file mode 100644 index 000000000..7982b71eb --- /dev/null +++ b/include/audacity/IdentInterface.h @@ -0,0 +1,60 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + IdentInterface.h + + Leland Lucius + + Copyright (c) 2014, Audacity Team + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +**********************************************************************/ + +#ifndef __AUDACITY_IDENTINTERFACE_H__ +#define __AUDACITY_IDENTINTERFACE_H__ + +#include "audacity/Types.h" + +class IdentInterface +{ +public: + virtual ~IdentInterface() {}; + + virtual PluginID GetID() = 0; + virtual wxString GetPath() = 0; + virtual wxString GetName() = 0; + virtual wxString GetVendor() = 0; + virtual wxString GetVersion() = 0; + virtual wxString GetDescription() = 0; +}; + +#endif // __AUDACITY_IDENTINTERFACE_H__ diff --git a/include/audacity/ImporterInterface.h b/include/audacity/ImporterInterface.h new file mode 100644 index 000000000..aeecf7345 --- /dev/null +++ b/include/audacity/ImporterInterface.h @@ -0,0 +1,151 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + ImporterInterface.h + + Leland Lucius + + Copyright (c) 2014, Audacity Team + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +**********************************************************************/ + +#ifndef __AUDACITY_IMPORTERINTERFACE_H__ +#define __AUDACITY_IMPORTERINTERFACE_H__ + +#include "audacity/Types.h" +#include "audacity/ConfigInterface.h" +#include "audacity/IdentInterface.h" + +// ============================================================================ +// +// ImporterInterface class +// +// ============================================================================ + +class ImporterHostInterface; +class ImporterClientInterface; +class ImporterInterface : public IdentInterface +{ +public: + virtual ~ImporterInterface() {}; + + // Get unique string ID of this plugin, usually it corresponds + // to the underlying library, i.e. "libsndfile", "libflac", "libav" + // These MUST NOT change across Audacity versions (but new IDs can + // be added). + virtual wxString GetPluginStringID() = 0; + + // Get a description of the file type this importer can import. + // Examples: "Ogg Vorbis", "MP3", "Uncompressed PCM" + virtual wxString GetPluginFormatDescription() = 0; + + // Get a list of extensions this plugin expects to be able to + // import. If a filename matches any of these extensions, + // this importer will get first dibs on importing it. + virtual wxArrayString GetSupportedExtensions() = 0; + virtual bool SupportsExtension(const wxString & extension) = 0; + + // Create the client that will be used to import a file. + virtual ImporterClientInterface *CreateClient() = 0; +}; + + +// ============================================================================ +// +// ImporterHostInterface class +// +// ============================================================================ + +class ImporterHostInterface +{ +public: + virtual ~ImporterHostInterface() {}; + + // Called by the client to add a new stream to the import. + virtual bool AddStream(int stream, + sampleFormat sampleformat, + float sampleRate, + int numChannels, + ChannelName *channelMap) = 0; + + // Accepts interleaved samples from the client. + virtual bool PutSamples(int stream, sampleCount numSamples, samplePtr inBuffer) = 0; + + // Accepts non-interleaved samples from the client. + virtual bool PutSamples(int stream, int channel, sampleCount numSamples, samplePtr inBuffer) = 0; + + // The client will call this as the import progresses. + virtual bool UpdateProgress(float current, float total) = 0; +}; + +// ============================================================================ +// +// ImporterClientInterface class +// +// ============================================================================ + +class ImporterClientInterface +{ +public: + virtual ~ImporterClientInterface() {}; + + // Provides a pointer to the assocated host for this importer. + virtual void SetHost(ImporterHostInterface *host) = 0; + + // Open the given file, returning true if it is a recognized + // format, false otherwise. This puts the importer into the open + // state. + virtual bool Open(const wxString & fileName) = 0; + + // Do any processing necessary to close the file and release resources. + // This will be called only if Open() succeeded. + virtual void Close() = 0; + + // This is similar to GetImporterDescription, but if possible the + // importer will return a more specific description of the + // specific file that is open. + virtual wxString GetFileDescription() = 0; + + // Return stream descriptions list + virtual void GetStreamInfo(wxArrayString & streamInfo) = 0; + + // Set stream "import/don't import" flag + virtual void SetStreamUsage(int streamID, bool use) = 0; + + // do the actual import, creating whatever tracks are necessary with + // the TrackFactory and calling the progress callback every iteration + // through the importing loop + virtual bool Import() = 0; +}; + +#endif // __AUDACITY_IMPORTERINTERFACE_H__ diff --git a/include/audacity/ModuleInterface.h b/include/audacity/ModuleInterface.h new file mode 100644 index 000000000..dd0ebaf80 --- /dev/null +++ b/include/audacity/ModuleInterface.h @@ -0,0 +1,188 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + ModuleInterface.h + + Leland Lucius + + Copyright (c) 2014, Audacity Team + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +**********************************************************************/ + +#ifndef __AUDACITY_MODULEINTERFACE_H__ +#define __AUDACITY_MODULEINTERFACE_H__ + +#include "audacity/Types.h" +#include "audacity/IdentInterface.h" +#include "audacity/PluginInterface.h" + +// ============================================================================ +// +// Don't even think about adding module types, like effect, importer, etc. in +// here. The module interface should not have to change when new types of +// plugins are added to Audacity. +// +// In addition a single module may want to provide multiple plugin types. +// ============================================================================ + +// ============================================================================ +// +// ModuleInterface class +// +// ============================================================================ + +class ModuleInterface : public IdentInterface +{ +public: + virtual ~ModuleInterface() {}; + + // Called immediately after creation to give the instance a chance to + // initialize. Return "true" if initialziation was successful. + virtual bool Initialize() = 0; + + // Called just prior to deletion to allow releasing any resources. + virtual void Terminate() = 0; + + // Modules providing a single or static set of plugins may use + // AutoRegisterPlugins() to register those plugins. + virtual bool AutoRegisterPlugins(PluginManagerInterface & pluginManager) = 0; + + // For modules providing an interface to other dynamically loaded plugins, + // the module returns a list of path names that will be presented to the + // user for enablement. + virtual wxArrayString FindPlugins(PluginManagerInterface & pluginManager) = 0; + + // Once the user selects desired paths from FindPlugins(), a call to RegisterPlugin() + // will be made to request registration of that plugin. If the module must create + // an instance of the plugin to register it, then then instance should be deleted + // after registration. + virtual bool RegisterPlugin(PluginManagerInterface & pluginManager, + const wxString & path) = 0; + + // When appropriate, CreateInstance() will be called to instantiate the plugins. + virtual void *CreateInstance(const PluginID & ID, const wxString & path) = 0; +}; + +// ============================================================================ +// +// ModuleManagerInterface class +// +// ============================================================================ + +class ModuleManagerInterface +{ +public: + virtual ~ModuleManagerInterface() {}; + + // Modules call this to register their interface + virtual void RegisterModule(ModuleInterface *module) = 0; +}; + +// ---------------------------------------------------------------------------- +// The default entry point name and the name that will be searched for during +// load if the module has been built as a external library. +// ---------------------------------------------------------------------------- +#define MODULE_ENTRY AudacityModule + +// ---------------------------------------------------------------------------- +// The module entry point prototype +// ---------------------------------------------------------------------------- +typedef ModuleInterface *(*ModuleMain)(ModuleManagerInterface *moduleManager, + const wxString *path); + +// ---------------------------------------------------------------------------- +// If BUILDING_AUDACITY is defined during the current build, it is assumed +// that the module wishes to be embedded in the Audacity executable. +// ---------------------------------------------------------------------------- +#if defined(BUILDING_AUDACITY) + +// ---------------------------------------------------------------------------- +// Since there may be multiple embedded modules, the module entry function will +// be declared static so as not to interfere with other modules during link. +// ---------------------------------------------------------------------------- +#define DECLARE_MODULE_ENTRY(name) \ +static ModuleInterface * name(ModuleManagerInterface *moduleManager, const wxString *path) + +// ---------------------------------------------------------------------------- +// This will create a class and instnace that will register the module entry +// point during Audacity startup. At the appropriate time, the entry point +// will be called to create the module instance. +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +// Provides the base for embedded module registration. If used, a Register() +// method must be supplied explicitly. +// ---------------------------------------------------------------------------- +#define DECLARE_BUILTIN_MODULE_BASE(name) \ +extern void RegisterBuiltinModule(ModuleMain rtn); \ +class name \ +{ \ +public: \ + name() {Register();} \ + void Register(); \ +}; \ +static name name ## _instance; + +// ---------------------------------------------------------------------------- +// Provides the full embedded module registration process. Nothing further is +// required (other than supplying the module entry point function). +// ---------------------------------------------------------------------------- +#define DECLARE_BUILTIN_MODULE(name) \ +DECLARE_BUILTIN_MODULE_BASE(name) \ +void name::Register() \ +{ \ + RegisterBuiltinModule(MODULE_ENTRY); \ +} + +#else + +// ---------------------------------------------------------------------------- +// When building as an external module, the entry point must be declared with +// "C" linkage and whatever method is used to make the function externally +// visible. +// ---------------------------------------------------------------------------- +#define DECLARE_MODULE_ENTRY(name) \ +extern "C" __declspec(dllexport) \ + ModuleInterface * name(ModuleManagerInterface *moduleManager, \ + const wxString *path) + +// ---------------------------------------------------------------------------- +// Define these as empty will effectively remove the embedded registration +// functionality. +// ---------------------------------------------------------------------------- +#define DECLARE_BUILTIN_MODULE_BASE(name) +#define DECLARE_BUILTIN_MODULE(name) + +#endif + +#endif // __AUDACITY_MODULEINTERFACE_H__ diff --git a/include/audacity/PluginInterface.h b/include/audacity/PluginInterface.h new file mode 100644 index 000000000..3b126c259 --- /dev/null +++ b/include/audacity/PluginInterface.h @@ -0,0 +1,96 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + PluginInterface.h + + Leland Lucius + + Copyright (c) 2014, Audacity Team + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +**********************************************************************/ + +#ifndef __AUDACITY_PLUGININTERFACE_H__ +#define __AUDACITY_PLUGININTERFACE_H__ + +#include "audacity/Types.h" +#include "audacity/ConfigInterface.h" +#include "audacity/EffectInterface.h" +#include "audacity/IdentInterface.h" +#include "audacity/ImporterInterface.h" + +class IdentInterface; +class EffectIdentInterface; +class PluginManagerInterface +{ +public: + virtual ~PluginManagerInterface() {}; + + virtual void RegisterModulePlugin(IdentInterface *module) = 0; + virtual void RegisterEffectPlugin(IdentInterface *provider, EffectIdentInterface *effect) = 0; + virtual void RegisterImporterPlugin(IdentInterface *provider, ImporterInterface *importer) = 0; + + virtual void FindFilesInPathList(const wxString & pattern, + const wxArrayString & pathList, + wxArrayString & files, + bool directories = false) = 0; + + virtual bool GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, wxString & value, const wxString & defval = wxString()) = 0; + virtual bool GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, int & value, int defval = 0) = 0; + virtual bool GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, bool & value, bool defval = false) = 0; + virtual bool GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, float & value, float defval = 0.0) = 0; + virtual bool GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, double & value, double defval = 0.0) = 0; + virtual bool GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, sampleCount & value, sampleCount defval = 0) = 0; + + virtual bool SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const wxString & value) = 0; + virtual bool SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const int & value) = 0; + virtual bool SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const bool & value) = 0; + virtual bool SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const float & value) = 0; + virtual bool SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const double & value) = 0; + virtual bool SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const sampleCount & value) = 0; + + virtual bool GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, wxString & value, const wxString & defval = wxString()) = 0; + virtual bool GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, int & value, int defval = 0) = 0; + virtual bool GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, bool & value, bool defval = false) = 0; + virtual bool GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, float & value, float defval = 0.0) = 0; + virtual bool GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, double & value, double defval = 0.0) = 0; + virtual bool GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, sampleCount & value, sampleCount defval = 0) = 0; + + virtual bool SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const wxString & value) = 0; + virtual bool SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const int & value) = 0; + virtual bool SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const bool & value) = 0; + virtual bool SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const float & value) = 0; + virtual bool SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const double & value) = 0; + virtual bool SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const sampleCount & value) = 0; +}; + +#endif // __AUDACITY_PLUGININTERFACE_H__ diff --git a/include/audacity/Types.h b/include/audacity/Types.h new file mode 100644 index 000000000..03b93f2bc --- /dev/null +++ b/include/audacity/Types.h @@ -0,0 +1,130 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + Types.h + + Leland Lucius + + Copyright (c) 2014, Audacity Team + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +**********************************************************************/ + +#ifndef __AUDACITY_TYPES_H__ +#define __AUDACITY_TYPES_H__ + +#include +#include + +// ---------------------------------------------------------------------------- +// TODO: I'd imagine this header may be replaced by other public headers. But, +// to try and minimize more changes to the base code, we can use this +// until proper public headers are created for the stuff in here. +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +// A native 64-bit integer...used when referring to any number of samples +// ---------------------------------------------------------------------------- +#if (defined(__VISUALC__) && defined(__WIN32__)) +typedef __int64 sampleCount; +#else +typedef long long sampleCount; +#endif + +// ---------------------------------------------------------------------------- +// Supported sample formats +// ---------------------------------------------------------------------------- +typedef enum +{ + int16Sample = 0x00020001, + int24Sample = 0x00040001, + floatSample = 0x0004000F +} sampleFormat; + +// ---------------------------------------------------------------------------- +// Provide the number of bytes a specific sample will take +// ---------------------------------------------------------------------------- +#define SAMPLE_SIZE(SampleFormat) (SampleFormat >> 16) + +// ---------------------------------------------------------------------------- +// Generic pointer to sample data +// ---------------------------------------------------------------------------- +typedef char *samplePtr; + +// ---------------------------------------------------------------------------- +// The type for plugin IDs +// ---------------------------------------------------------------------------- +typedef wxString PluginID; + +// ---------------------------------------------------------------------------- +// Supported channel assignments +// ---------------------------------------------------------------------------- + +typedef enum +{ + // Use to mark end of list + ChannelNameEOL = -1, + // The default channel assignment + ChannelNameMono, + // From this point, the channels follow the 22.2 surround sound format + ChannelNameFrontLeft, + ChannelNameFrontRight, + ChannelNameFrontCenter, + ChannelNameLowFrequency1, + ChannelNameBackLeft, + ChannelNameBackRight, + ChannelNameFrontLeftCenter, + ChannelNameFrontRightCenter, + ChannelNameBackCenter, + ChannelNameLowFrequency2, + ChannelNameSideLeft, + ChannelNameSideRight, + ChannelNameTopFrontLeft, + ChannelNameTopFrontRight, + ChannelNameTopFrontCenter, + ChannelNameTopCenter, + ChannelNameTopBackLeft, + ChannelNameTopBackRight, + ChannelNameTopSideLeft, + ChannelNameTopSideRight, + ChannelNameTopBackCenter, + ChannelNameBottomFrontCenter, + ChannelNameBottomFrontLeft, + ChannelNameBottomFrontRight, +} ChannelName; + +// ---------------------------------------------------------------------------- +// Convenience macro to suppress unused parameter warnings +// ---------------------------------------------------------------------------- +#define AUNUSED(p) + +#endif // __AUDACITY_TYPES_H__ diff --git a/locale/Makefile.in b/locale/Makefile.in index f54cb2192..51742f909 100644 --- a/locale/Makefile.in +++ b/locale/Makefile.in @@ -35,29 +35,29 @@ INSTALL_DATA = ${INSTALL} -m 644 # We use $(mkdir_p). # In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as # "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions, -# ${SHELL} /home/yam/a/audacity/autotools/install-sh does not start with $(SHELL), so we add it. -# In automake >= 1.10, /usr/bin/mkdir -p is derived from ${MKDIR_P}, which is defined +# ${SHELL} /Users/yam/n/audacity/autotools/install-sh does not start with $(SHELL), so we add it. +# In automake >= 1.10, $(top_builddir)/autotools/install-sh -c -d is derived from ${MKDIR_P}, which is defined # either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake # versions, $(mkinstalldirs) and $(install_sh) are unused. -mkinstalldirs = $(SHELL) ${SHELL} /home/yam/a/audacity/autotools/install-sh -d -install_sh = $(SHELL) ${SHELL} /home/yam/a/audacity/autotools/install-sh -MKDIR_P = /usr/bin/mkdir -p -mkdir_p = /usr/bin/mkdir -p +mkinstalldirs = $(SHELL) ${SHELL} /Users/yam/n/audacity/autotools/install-sh -d +install_sh = $(SHELL) ${SHELL} /Users/yam/n/audacity/autotools/install-sh +MKDIR_P = ../autotools/install-sh -c -d +mkdir_p = $(top_builddir)/autotools/install-sh -c -d -GMSGFMT_ = /usr/bin/msgfmt -GMSGFMT_no = /usr/bin/msgfmt -GMSGFMT_yes = /usr/bin/msgfmt +GMSGFMT_ = /opt/local/bin/msgfmt +GMSGFMT_no = /opt/local/bin/msgfmt +GMSGFMT_yes = /opt/local/bin/msgfmt GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT)) -MSGFMT_ = /usr/bin/msgfmt -MSGFMT_no = /usr/bin/msgfmt -MSGFMT_yes = /usr/bin/msgfmt +MSGFMT_ = /opt/local/bin/msgfmt +MSGFMT_no = /opt/local/bin/msgfmt +MSGFMT_yes = /opt/local/bin/msgfmt MSGFMT = $(MSGFMT_$(USE_MSGCTXT)) -XGETTEXT_ = /usr/bin/xgettext -XGETTEXT_no = /usr/bin/xgettext -XGETTEXT_yes = /usr/bin/xgettext +XGETTEXT_ = /opt/local/bin/xgettext +XGETTEXT_no = /opt/local/bin/xgettext +XGETTEXT_yes = /opt/local/bin/xgettext XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT)) MSGMERGE = msgmerge -MSGMERGE_UPDATE = /usr/bin/msgmerge --update +MSGMERGE_UPDATE = /opt/local/bin/msgmerge --update MSGINIT = msginit MSGCONV = msgconv MSGFILTER = msgfilter @@ -96,7 +96,7 @@ CATALOGS = @CATALOGS@ mv t-$@ $@ -all: check-macro-version all-yes +all: check-macro-version all-no all-yes: stamp-po all-no: @@ -209,7 +209,7 @@ $(POFILES): $(srcdir)/$(DOMAIN).pot install: install-exec install-data install-exec: -install-data: install-data-yes +install-data: install-data-no if test "$(PACKAGE)" = "gettext-tools"; then \ $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ for file in $(DISTFILES.common) Makevars.template; do \ @@ -267,7 +267,7 @@ install-strip: install installdirs: installdirs-exec installdirs-data installdirs-exec: -installdirs-data: installdirs-data-yes +installdirs-data: installdirs-data-no if test "$(PACKAGE)" = "gettext-tools"; then \ $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ else \ @@ -311,7 +311,7 @@ installcheck: uninstall: uninstall-exec uninstall-data uninstall-exec: -uninstall-data: uninstall-data-yes +uninstall-data: uninstall-data-no if test "$(PACKAGE)" = "gettext-tools"; then \ for file in $(DISTFILES.common) Makevars.template; do \ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ diff --git a/mac/Audacity.xcodeproj/project.pbxproj b/mac/Audacity.xcodeproj/project.pbxproj index 6dfc71b02..d0a6957d7 100644 --- a/mac/Audacity.xcodeproj/project.pbxproj +++ b/mac/Audacity.xcodeproj/project.pbxproj @@ -476,6 +476,8 @@ 280828550A75E0D0000002EF /* LabelDialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 280828530A75E0D0000002EF /* LabelDialog.cpp */; }; 2808285A0A75E0EA000002EF /* Grid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 280828580A75E0EA000002EF /* Grid.cpp */; }; 2809C4B80BCB7E560006010F /* FileIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2809C4B60BCB7E560006010F /* FileIO.cpp */; }; + 280A8B4719F4403B0091DE70 /* ModuleManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 280A8B4519F4403B0091DE70 /* ModuleManager.cpp */; }; + 280A8B4A19F440880091DE70 /* EffectRack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 280A8B4819F440880091DE70 /* EffectRack.cpp */; }; 28105D9C0AD09FB200BB4269 /* portmixer.h in Headers */ = {isa = PBXBuildFile; fileRef = 28105D9B0AD09FB200BB4269 /* portmixer.h */; }; 28105DAA0AD09FC500BB4269 /* px_mac_coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 28105DA00AD09FC500BB4269 /* px_mac_coreaudio.c */; }; 28105DAB0AD09FC500BB4269 /* px_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = 28105DA10AD09FC500BB4269 /* px_mixer.c */; }; @@ -927,7 +929,6 @@ 28A96DC30E28642300F3CE01 /* strparse.h in Headers */ = {isa = PBXBuildFile; fileRef = 28F3A4010E28289500729866 /* strparse.h */; }; 28B3C5DC1833D23E0024BE6D /* libexpat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FADDEF1833C3C500BA4141 /* libexpat.a */; }; 28B3C5DF1833D24E0024BE6D /* libexpat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 28FADDEF1833C3C500BA4141 /* libexpat.a */; }; - 28B6ED8F0DE3D1B50046F0F3 /* LoadModules.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28B6ED8D0DE3D1B50046F0F3 /* LoadModules.cpp */; }; 28B97B890FBF771A0076CF28 /* VSTEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28B97B850FBF771A0076CF28 /* VSTEffect.cpp */; }; 28BD8AB1101DF4C700686679 /* BatchEvalCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28BD8AA9101DF4C600686679 /* BatchEvalCommand.cpp */; }; 28BD8AB2101DF4C700686679 /* CommandDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28BD8AAA101DF4C600686679 /* CommandDirectory.cpp */; }; @@ -1450,7 +1451,6 @@ ED663C3316543647007F53A5 /* SplashDialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28501E9F0CEECEF80029ABAA /* SplashDialog.cpp */; }; ED663C3416543647007F53A5 /* LoadVamp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28501E970CEECE910029ABAA /* LoadVamp.cpp */; }; ED663C3516543647007F53A5 /* VampEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28501E990CEECE920029ABAA /* VampEffect.cpp */; }; - ED663C3616543647007F53A5 /* LoadModules.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28B6ED8D0DE3D1B50046F0F3 /* LoadModules.cpp */; }; ED663C3716543647007F53A5 /* NonGuiThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 288052BC0DEA72F300671EA4 /* NonGuiThread.cpp */; }; ED663C3816543647007F53A5 /* HtmlWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28530C480DF2105200555C94 /* HtmlWindow.cpp */; }; ED663C3916543647007F53A5 /* ProgressDialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28530C4A0DF2105200555C94 /* ProgressDialog.cpp */; }; @@ -1778,7 +1778,6 @@ ED85B50B16A47353006DA21D /* SplashDialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28501E9F0CEECEF80029ABAA /* SplashDialog.cpp */; }; ED85B50C16A47353006DA21D /* LoadVamp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28501E970CEECE910029ABAA /* LoadVamp.cpp */; }; ED85B50D16A47353006DA21D /* VampEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28501E990CEECE920029ABAA /* VampEffect.cpp */; }; - ED85B50E16A47353006DA21D /* LoadModules.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28B6ED8D0DE3D1B50046F0F3 /* LoadModules.cpp */; }; ED85B50F16A47353006DA21D /* NonGuiThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 288052BC0DEA72F300671EA4 /* NonGuiThread.cpp */; }; ED85B51016A47353006DA21D /* HtmlWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28530C480DF2105200555C94 /* HtmlWindow.cpp */; }; ED85B51116A47353006DA21D /* ProgressDialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 28530C4A0DF2105200555C94 /* ProgressDialog.cpp */; }; @@ -3150,6 +3149,17 @@ 280828590A75E0EA000002EF /* Grid.h */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = Grid.h; sourceTree = ""; tabWidth = 3; }; 2809C4B60BCB7E560006010F /* FileIO.cpp */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = FileIO.cpp; sourceTree = ""; tabWidth = 3; }; 2809C4B70BCB7E560006010F /* FileIO.h */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = FileIO.h; sourceTree = ""; tabWidth = 3; }; + 280A8B3E19F440160091DE70 /* ConfigInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConfigInterface.h; path = ../include/audacity/ConfigInterface.h; sourceTree = SOURCE_ROOT; }; + 280A8B3F19F440160091DE70 /* EffectInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EffectInterface.h; path = ../include/audacity/EffectInterface.h; sourceTree = SOURCE_ROOT; }; + 280A8B4019F440160091DE70 /* IdentInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IdentInterface.h; path = ../include/audacity/IdentInterface.h; sourceTree = SOURCE_ROOT; }; + 280A8B4119F440160091DE70 /* ImporterInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ImporterInterface.h; path = ../include/audacity/ImporterInterface.h; sourceTree = SOURCE_ROOT; }; + 280A8B4219F440160091DE70 /* ModuleInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ModuleInterface.h; path = ../include/audacity/ModuleInterface.h; sourceTree = SOURCE_ROOT; }; + 280A8B4319F440160091DE70 /* PluginInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PluginInterface.h; path = ../include/audacity/PluginInterface.h; sourceTree = SOURCE_ROOT; }; + 280A8B4419F440160091DE70 /* Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Types.h; path = ../include/audacity/Types.h; sourceTree = SOURCE_ROOT; }; + 280A8B4519F4403B0091DE70 /* ModuleManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModuleManager.cpp; sourceTree = ""; }; + 280A8B4619F4403B0091DE70 /* ModuleManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModuleManager.h; sourceTree = ""; }; + 280A8B4819F440880091DE70 /* EffectRack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EffectRack.cpp; sourceTree = ""; }; + 280A8B4919F440880091DE70 /* EffectRack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EffectRack.h; sourceTree = ""; }; 28105D9B0AD09FB200BB4269 /* portmixer.h */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = portmixer.h; sourceTree = ""; tabWidth = 3; }; 28105DA00AD09FC500BB4269 /* px_mac_coreaudio.c */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.c.c; path = px_mac_coreaudio.c; sourceTree = ""; tabWidth = 3; }; 28105DA10AD09FC500BB4269 /* px_mixer.c */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.c.c; path = px_mixer.c; sourceTree = ""; tabWidth = 3; }; @@ -3669,8 +3679,6 @@ 28AA281F0F267A2D008AED9E /* tremolo.ny */ = {isa = PBXFileReference; explicitFileType = file; fileEncoding = 5; name = tremolo.ny; path = "../plug-ins/tremolo.ny"; sourceTree = SOURCE_ROOT; }; 28AA28200F267A2D008AED9E /* vocalremover.ny */ = {isa = PBXFileReference; explicitFileType = file; fileEncoding = 5; name = vocalremover.ny; path = "../plug-ins/vocalremover.ny"; sourceTree = SOURCE_ROOT; }; 28AA28210F267A2D008AED9E /* vocoder.ny */ = {isa = PBXFileReference; explicitFileType = file; fileEncoding = 5; name = vocoder.ny; path = "../plug-ins/vocoder.ny"; sourceTree = SOURCE_ROOT; }; - 28B6ED8D0DE3D1B50046F0F3 /* LoadModules.cpp */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = LoadModules.cpp; sourceTree = ""; tabWidth = 3; }; - 28B6ED8E0DE3D1B50046F0F3 /* LoadModules.h */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.c.h; path = LoadModules.h; sourceTree = ""; tabWidth = 3; }; 28B97B850FBF771A0076CF28 /* VSTEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; name = VSTEffect.cpp; path = VST/VSTEffect.cpp; sourceTree = ""; tabWidth = 3; }; 28B97B860FBF771A0076CF28 /* VSTEffect.h */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.c.h; name = VSTEffect.h; path = VST/VSTEffect.h; sourceTree = ""; tabWidth = 3; }; 28BD8AA9101DF4C600686679 /* BatchEvalCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 5; indentWidth = 3; lastKnownFileType = sourcecode.cpp.cpp; path = BatchEvalCommand.cpp; sourceTree = ""; tabWidth = 3; }; @@ -4891,6 +4899,7 @@ 17FC86F30994637C0061DC94 /* compile.txt */, 1790AFB109883B6D008A330A /* Products */, 287179EE0DF6383000E171DF /* Xcode Settings */, + 280A8B3A19F43FE30091DE70 /* includes */, 17072F220988D4F4008541CC /* lib-src */, 286D30AC0F264B58004E6E4A /* locale */, 178CF4FE098953FB0056CE58 /* mac */, @@ -5020,8 +5029,6 @@ 1790B0A209883BFD008A330A /* Languages.h */, 1790B0A309883BFD008A330A /* Legacy.cpp */, 1790B0A409883BFD008A330A /* Legacy.h */, - 28B6ED8D0DE3D1B50046F0F3 /* LoadModules.cpp */, - 28B6ED8E0DE3D1B50046F0F3 /* LoadModules.h */, 1865A9B41004490400946EE6 /* Lyrics.cpp */, 1865A9B51004490400946EE6 /* Lyrics.h */, 1865A9B61004490500946EE6 /* LyricsWindow.cpp */, @@ -5035,6 +5042,8 @@ 1790B0AC09883BFD008A330A /* Mix.h */, 289E75081006D0BD00CEF79B /* MixerBoard.cpp */, 289E75091006D0BD00CEF79B /* MixerBoard.h */, + 280A8B4519F4403B0091DE70 /* ModuleManager.cpp */, + 280A8B4619F4403B0091DE70 /* ModuleManager.h */, 1790B0AF09883BFD008A330A /* NoteTrack.cpp */, 1790B0B009883BFD008A330A /* NoteTrack.h */, EDF3B7AF1588C0D50032D35F /* Paulstretch.cpp */, @@ -5180,6 +5189,8 @@ ED3D7FED0DF73889000F43E3 /* EffectCategory.h */, ED3D7FEE0DF73889000F43E3 /* EffectManager.cpp */, ED3D7FEF0DF73889000F43E3 /* EffectManager.h */, + 280A8B4819F440880091DE70 /* EffectRack.cpp */, + 280A8B4919F440880091DE70 /* EffectRack.h */, 1790B01B09883BFD008A330A /* Equalization.cpp */, 1790B01C09883BFD008A330A /* Equalization.h */, EDFCEBB318894B9E00C98E51 /* Equalization48x.cpp */, @@ -5571,6 +5582,28 @@ path = ../nyquist/rawwaves; sourceTree = SOURCE_ROOT; }; + 280A8B3A19F43FE30091DE70 /* includes */ = { + isa = PBXGroup; + children = ( + 280A8B3D19F440010091DE70 /* audacity */, + ); + name = includes; + sourceTree = ""; + }; + 280A8B3D19F440010091DE70 /* audacity */ = { + isa = PBXGroup; + children = ( + 280A8B3E19F440160091DE70 /* ConfigInterface.h */, + 280A8B3F19F440160091DE70 /* EffectInterface.h */, + 280A8B4019F440160091DE70 /* IdentInterface.h */, + 280A8B4119F440160091DE70 /* ImporterInterface.h */, + 280A8B4219F440160091DE70 /* ModuleInterface.h */, + 280A8B4319F440160091DE70 /* PluginInterface.h */, + 280A8B4419F440160091DE70 /* Types.h */, + ); + name = audacity; + sourceTree = ""; + }; 28105D9A0AD09FB200BB4269 /* include */ = { isa = PBXGroup; children = ( @@ -8937,7 +8970,6 @@ 28501EA20CEECEF80029ABAA /* SplashDialog.cpp in Sources */, 28501EAA0CEED0670029ABAA /* LoadVamp.cpp in Sources */, 28501EAB0CEED0680029ABAA /* VampEffect.cpp in Sources */, - 28B6ED8F0DE3D1B50046F0F3 /* LoadModules.cpp in Sources */, 288052C20DEA73F500671EA4 /* NonGuiThread.cpp in Sources */, 28530C4C0DF2105200555C94 /* HtmlWindow.cpp in Sources */, 28530C4D0DF2105200555C94 /* ProgressDialog.cpp in Sources */, @@ -9085,6 +9117,8 @@ 28F67179197DFA1C00075C32 /* FormatClassifier.cpp in Sources */, 28F6717A197DFA1C00075C32 /* MultiFormatReader.cpp in Sources */, 28F6717B197DFA1C00075C32 /* SpecPowerMeter.cpp in Sources */, + 280A8B4719F4403B0091DE70 /* ModuleManager.cpp in Sources */, + 280A8B4A19F440880091DE70 /* EffectRack.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -9448,7 +9482,6 @@ ED663C3316543647007F53A5 /* SplashDialog.cpp in Sources */, ED663C3416543647007F53A5 /* LoadVamp.cpp in Sources */, ED663C3516543647007F53A5 /* VampEffect.cpp in Sources */, - ED663C3616543647007F53A5 /* LoadModules.cpp in Sources */, ED663C3716543647007F53A5 /* NonGuiThread.cpp in Sources */, ED663C3816543647007F53A5 /* HtmlWindow.cpp in Sources */, ED663C3916543647007F53A5 /* ProgressDialog.cpp in Sources */, @@ -9759,7 +9792,6 @@ ED85B50B16A47353006DA21D /* SplashDialog.cpp in Sources */, ED85B50C16A47353006DA21D /* LoadVamp.cpp in Sources */, ED85B50D16A47353006DA21D /* VampEffect.cpp in Sources */, - ED85B50E16A47353006DA21D /* LoadModules.cpp in Sources */, ED85B50F16A47353006DA21D /* NonGuiThread.cpp in Sources */, ED85B51016A47353006DA21D /* HtmlWindow.cpp in Sources */, ED85B51116A47353006DA21D /* ProgressDialog.cpp in Sources */, @@ -10419,7 +10451,7 @@ ); PRODUCT_NAME = Audacity; SKIP_INSTALL = NO; - USER_HEADER_SEARCH_PATHS = "$(TOPLEVEL)/mac $(TOPLEVEL)/src/** $(TOPLEVEL)/lib-src/FileDialog $(TOPLEVEL)/lib-src/libflac/include $(TOPLEVEL)/lib-src/libid3tag $(TOPLEVEL)/lib-src/lame $(TOPLEVEL)/lib-src/libmad $(TOPLEVEL)/lib-src/libogg/include $(TOPLEVEL)/lib-src/libnyquist/nyq $(TOPLEVEL)/lib-src/libresample/include $(TOPLEVEL)/lib-src/libsndfile/src $(TOPLEVEL)/lib-src/libvamp $(TOPLEVEL)/lib-src/libvorbis/include $(TOPLEVEL)/lib-src/portaudio-v19/include $(TOPLEVEL)/lib-src/portmixer/px_common $(TOPLEVEL)/lib-src/portsmf $(TOPLEVEL)/lib-src/soundtouch/include $(TOPLEVEL)/lib-src/lv2/include $(TOPLEVEL)/lib-src/twolame/libtwolame"; + USER_HEADER_SEARCH_PATHS = "$(TOPLEVEL)/include $(TOPLEVEL)/mac $(TOPLEVEL)/src/** $(TOPLEVEL)/lib-src/FileDialog $(TOPLEVEL)/lib-src/libflac/include $(TOPLEVEL)/lib-src/libid3tag $(TOPLEVEL)/lib-src/lame $(TOPLEVEL)/lib-src/libmad $(TOPLEVEL)/lib-src/libogg/include $(TOPLEVEL)/lib-src/libnyquist/nyq $(TOPLEVEL)/lib-src/libresample/include $(TOPLEVEL)/lib-src/libsndfile/src $(TOPLEVEL)/lib-src/libvamp $(TOPLEVEL)/lib-src/libvorbis/include $(TOPLEVEL)/lib-src/portaudio-v19/include $(TOPLEVEL)/lib-src/portmixer/px_common $(TOPLEVEL)/lib-src/portsmf $(TOPLEVEL)/lib-src/soundtouch/include $(TOPLEVEL)/lib-src/lv2/include $(TOPLEVEL)/lib-src/twolame/libtwolame"; }; name = "Debug Static"; }; @@ -10441,7 +10473,7 @@ INFOPLIST_PREPROCESS = YES; KEEP_PRIVATE_EXTERNS = YES; ONLY_LINK_ESSENTIAL_SYMBOLS = YES; - SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; SSE_CPPFLAGS = "-Xarch_i386 -DAPPLE_I386 -Xarch_ppc -DAPPLE_PPC"; TOPLEVEL = ..; WX_CFLAGS = "-I$(WX_PREFIX)/lib/wx/include/mac-unicode-debug-static-$(WX_VER) -I$(WX_PREFIX)/include/wx-$(WX_VER) -D__WXDEBUG__ -D__WXMAC__ -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -DNO_GCC_PRAGMA"; @@ -10700,7 +10732,7 @@ INFOPLIST_PREPROCESS = YES; KEEP_PRIVATE_EXTERNS = YES; ONLY_LINK_ESSENTIAL_SYMBOLS = YES; - SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; SSE_CPPFLAGS = "-Xarch_i386 -DAPPLE_I386 -Xarch_ppc -DAPPLE_PPC"; TOPLEVEL = ..; WX_CFLAGS = "-I$(WX_PREFIX)/lib/wx/include/mac-unicode-debug-$(WX_VER) -I$(WX_PREFIX)/include/wx-$(WX_VER) -D__WXDEBUG__ -D__WXMAC__ -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -DNO_GCC_PRAGMA"; @@ -10770,7 +10802,7 @@ ); PRODUCT_NAME = Audacity; SKIP_INSTALL = NO; - USER_HEADER_SEARCH_PATHS = "$(TOPLEVEL)/mac $(TOPLEVEL)/src/** $(TOPLEVEL)/lib-src/FileDialog $(TOPLEVEL)/lib-src/libflac/include $(TOPLEVEL)/lib-src/libid3tag $(TOPLEVEL)/lib-src/lame $(TOPLEVEL)/lib-src/libmad $(TOPLEVEL)/lib-src/libogg/include $(TOPLEVEL)/lib-src/libnyquist/nyq $(TOPLEVEL)/lib-src/libresample/include $(TOPLEVEL)/lib-src/libsndfile/src $(TOPLEVEL)/lib-src/libvamp $(TOPLEVEL)/lib-src/libvorbis/include $(TOPLEVEL)/lib-src/portaudio-v19/include $(TOPLEVEL)/lib-src/portmixer/px_common $(TOPLEVEL)/lib-src/portsmf $(TOPLEVEL)/lib-src/soundtouch/include $(TOPLEVEL)/lib-src/lv2/include $(TOPLEVEL)/lib-src/twolame/libtwolame"; + USER_HEADER_SEARCH_PATHS = "$(TOPLEVEL)/include $(TOPLEVEL)/mac $(TOPLEVEL)/src/** $(TOPLEVEL)/lib-src/FileDialog $(TOPLEVEL)/lib-src/libflac/include $(TOPLEVEL)/lib-src/libid3tag $(TOPLEVEL)/lib-src/lame $(TOPLEVEL)/lib-src/libmad $(TOPLEVEL)/lib-src/libogg/include $(TOPLEVEL)/lib-src/libnyquist/nyq $(TOPLEVEL)/lib-src/libresample/include $(TOPLEVEL)/lib-src/libsndfile/src $(TOPLEVEL)/lib-src/libvamp $(TOPLEVEL)/lib-src/libvorbis/include $(TOPLEVEL)/lib-src/portaudio-v19/include $(TOPLEVEL)/lib-src/portmixer/px_common $(TOPLEVEL)/lib-src/portsmf $(TOPLEVEL)/lib-src/soundtouch/include $(TOPLEVEL)/lib-src/lv2/include $(TOPLEVEL)/lib-src/twolame/libtwolame"; }; name = "Debug Shared"; }; @@ -11015,7 +11047,7 @@ INFOPLIST_PREPROCESS = YES; KEEP_PRIVATE_EXTERNS = YES; ONLY_LINK_ESSENTIAL_SYMBOLS = YES; - SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; SSE_CPPFLAGS = "-Xarch_i386 -DAPPLE_I386 -Xarch_ppc -DAPPLE_PPC"; TOPLEVEL = ..; WX_CFLAGS = "-I$(WX_PREFIX)/lib/wx/include/mac-unicode-release-$(WX_VER) -I$(WX_PREFIX)/include/wx-$(WX_VER) -D__WXMAC__ -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -DNO_GCC_PRAGMA"; @@ -11087,7 +11119,7 @@ ); PRODUCT_NAME = Audacity; SKIP_INSTALL = NO; - USER_HEADER_SEARCH_PATHS = "$(TOPLEVEL)/mac $(TOPLEVEL)/src/** $(TOPLEVEL)/lib-src/FileDialog $(TOPLEVEL)/lib-src/libflac/include $(TOPLEVEL)/lib-src/libid3tag $(TOPLEVEL)/lib-src/lame $(TOPLEVEL)/lib-src/libmad $(TOPLEVEL)/lib-src/libogg/include $(TOPLEVEL)/lib-src/libnyquist/nyq $(TOPLEVEL)/lib-src/libresample/include $(TOPLEVEL)/lib-src/libsndfile/src $(TOPLEVEL)/lib-src/libvamp $(TOPLEVEL)/lib-src/libvorbis/include $(TOPLEVEL)/lib-src/portaudio-v19/include $(TOPLEVEL)/lib-src/portmixer/px_common $(TOPLEVEL)/lib-src/portsmf $(TOPLEVEL)/lib-src/soundtouch/include $(TOPLEVEL)/lib-src/lv2/include $(TOPLEVEL)/lib-src/twolame/libtwolame"; + USER_HEADER_SEARCH_PATHS = "$(TOPLEVEL)/include $(TOPLEVEL)/mac $(TOPLEVEL)/src/** $(TOPLEVEL)/lib-src/FileDialog $(TOPLEVEL)/lib-src/libflac/include $(TOPLEVEL)/lib-src/libid3tag $(TOPLEVEL)/lib-src/lame $(TOPLEVEL)/lib-src/libmad $(TOPLEVEL)/lib-src/libogg/include $(TOPLEVEL)/lib-src/libnyquist/nyq $(TOPLEVEL)/lib-src/libresample/include $(TOPLEVEL)/lib-src/libsndfile/src $(TOPLEVEL)/lib-src/libvamp $(TOPLEVEL)/lib-src/libvorbis/include $(TOPLEVEL)/lib-src/portaudio-v19/include $(TOPLEVEL)/lib-src/portmixer/px_common $(TOPLEVEL)/lib-src/portsmf $(TOPLEVEL)/lib-src/soundtouch/include $(TOPLEVEL)/lib-src/lv2/include $(TOPLEVEL)/lib-src/twolame/libtwolame"; }; name = "Release Shared"; }; @@ -11595,7 +11627,7 @@ ); PRODUCT_NAME = Audacity; SKIP_INSTALL = NO; - USER_HEADER_SEARCH_PATHS = "$(TOPLEVEL)/mac $(TOPLEVEL)/src/** $(TOPLEVEL)/lib-src/FileDialog $(TOPLEVEL)/lib-src/libflac/include $(TOPLEVEL)/lib-src/libid3tag $(TOPLEVEL)/lib-src/lame $(TOPLEVEL)/lib-src/libmad $(TOPLEVEL)/lib-src/libogg/include $(TOPLEVEL)/lib-src/libnyquist/nyq $(TOPLEVEL)/lib-src/libresample/include $(TOPLEVEL)/lib-src/libsndfile/src $(TOPLEVEL)/lib-src/libvamp $(TOPLEVEL)/lib-src/libvorbis/include $(TOPLEVEL)/lib-src/portaudio-v19/include $(TOPLEVEL)/lib-src/portmixer/px_common $(TOPLEVEL)/lib-src/portsmf $(TOPLEVEL)/lib-src/soundtouch/include $(TOPLEVEL)/lib-src/lv2/include $(TOPLEVEL)/lib-src/twolame/libtwolame"; + USER_HEADER_SEARCH_PATHS = "$(TOPLEVEL)/include $(TOPLEVEL)/mac $(TOPLEVEL)/src/** $(TOPLEVEL)/lib-src/FileDialog $(TOPLEVEL)/lib-src/libflac/include $(TOPLEVEL)/lib-src/libid3tag $(TOPLEVEL)/lib-src/lame $(TOPLEVEL)/lib-src/libmad $(TOPLEVEL)/lib-src/libogg/include $(TOPLEVEL)/lib-src/libnyquist/nyq $(TOPLEVEL)/lib-src/libresample/include $(TOPLEVEL)/lib-src/libsndfile/src $(TOPLEVEL)/lib-src/libvamp $(TOPLEVEL)/lib-src/libvorbis/include $(TOPLEVEL)/lib-src/portaudio-v19/include $(TOPLEVEL)/lib-src/portmixer/px_common $(TOPLEVEL)/lib-src/portsmf $(TOPLEVEL)/lib-src/soundtouch/include $(TOPLEVEL)/lib-src/lv2/include $(TOPLEVEL)/lib-src/twolame/libtwolame"; }; name = "Release Static"; }; @@ -11621,7 +11653,7 @@ INFOPLIST_PREPROCESS = YES; KEEP_PRIVATE_EXTERNS = YES; ONLY_LINK_ESSENTIAL_SYMBOLS = YES; - SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + SDKROOT = /Developer/SDKs/MacOSX10.5.sdk; SSE_CPPFLAGS = "-Xarch_i386 -DAPPLE_I386 -Xarch_ppc -DAPPLE_PPC"; TOPLEVEL = ..; WX_CFLAGS = "-I$(WX_PREFIX)/lib/wx/include/mac-unicode-release-static-$(WX_VER) -I$(WX_PREFIX)/include/wx-$(WX_VER) -D__WXMAC__ -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -DNO_GCC_PRAGMA"; diff --git a/src/AllThemeResources.h b/src/AllThemeResources.h index d953f41db..097c19f4c 100644 --- a/src/AllThemeResources.h +++ b/src/AllThemeResources.h @@ -214,6 +214,9 @@ from there. Audacity will look for a file called "Pause.png". DEFINE_IMAGE( bmpSyncLockSelTile, wxImage(20, 22), wxT("SyncLockSelTile")); DEFINE_IMAGE( bmpSyncLockIcon, wxImage(12, 12), wxT("SyncLockIcon")); + SET_THEME_FLAGS( resFlagNone ); + DEFINE_IMAGE( bmpEditEffects, wxImage(21, 20), wxT("EditEffects")); + #if defined(EXPERIMENTAL_THEMING) DEFINE_COLOUR( clrBlank, wxColour( 64, 64, 64), wxT("Blank")); DEFINE_COLOUR( clrUnselected, wxColour( 30, 30, 30), wxT("Unselected")); diff --git a/src/AudacityApp.cpp b/src/AudacityApp.cpp index 3f33bcb9e..d7ad648a8 100644 --- a/src/AudacityApp.cpp +++ b/src/AudacityApp.cpp @@ -68,12 +68,12 @@ It handles initialization and termination by subclassing wxApp. #include "commands/AppCommandEvent.h" #include "effects/LoadEffects.h" #include "effects/Contrast.h" -#include "effects/VST/VSTEffect.h" #include "widgets/ASlider.h" #include "FFmpeg.h" #include "Internat.h" #include "LangChoice.h" #include "Languages.h" +#include "PluginManager.h" #include "Prefs.h" #include "Project.h" #include "Screenshot.h" @@ -95,7 +95,7 @@ It handles initialization and termination by subclassing wxApp. //temporarilly commented out till it is added to all projects //#include "Profiler.h" -#include "LoadModules.h" +#include "ModuleManager.h" #include "import/Import.h" @@ -274,7 +274,7 @@ void QuitAudacity(bool bForce) LWSlider::DeleteSharedTipPanel(); - ModuleManager::Dispatch(AppQuiting); + ModuleManager::Get().Dispatch(AppQuiting); if (gParentFrame) gParentFrame->Destroy(); @@ -1008,6 +1008,7 @@ int AudacityApp::FilterEvent(wxEvent & event) return -1; } #endif +#include "effects/VST/VSTEffect.h" // The `main program' equivalent, creating the windows and returning the // main frame @@ -1042,16 +1043,6 @@ bool AudacityApp::OnInit() wxTheApp->SetVendorName(vendorName); wxTheApp->SetAppName(appName); -#ifdef USE_VST // if no VST support, answer is always no - // Have we been started to check a plugin? - if (argc == 3 && wxStrcmp(argv[1], VSTCMDKEY) == 0) { - wxHandleFatalExceptions(); - - VSTEffect::Check(argv[2]); - return false; - } -#endif - // Unused strings that we want to be translated, even though // we're not using them yet... wxString future1 = _("Master Gain Control"); @@ -1183,9 +1174,12 @@ bool AudacityApp::OnInit() // Initialize the CommandHandler InitCommandHandler(); - // Initialize the ModuleManager, including loading found modules - ModuleManager::Initialize(*mCmdHandler); + // Initialize the PluginManager + PluginManager::Get().Initialize(); + + // Initialize the ModuleManager, including loading found modules + ModuleManager::Get().Initialize(*mCmdHandler); #if !wxCHECK_VERSION(3, 0, 0) FinishInits(); @@ -1248,7 +1242,6 @@ void AudacityApp::FinishInits() LoadEffects(); - #ifdef __WXMAC__ // On the Mac, users don't expect a program to quit when you close the last window. @@ -1310,7 +1303,7 @@ void AudacityApp::FinishInits() FFmpegStartup(); #endif - mImporter = new Importer; + Importer::Get().Initialize(); // // Auto-recovery @@ -1474,7 +1467,7 @@ void AudacityApp::FinishInits() gInited = true; - ModuleManager::Dispatch(AppInitialized); + ModuleManager::Get().Dispatch(AppInitialized); mWindowRectAlreadySaved = FALSE; } @@ -1823,8 +1816,7 @@ int AudacityApp::OnExit() delete mIPCServ; #endif - if (mImporter) - delete mImporter; + Importer::Get().Terminate(); if(gPrefs) { @@ -1856,6 +1848,9 @@ int AudacityApp::OnExit() DeinitAudioIO(); + // Terminate the PluginManager (must be done before deleting the locale) + PluginManager::Get().Terminate(); + if (mLocale) delete mLocale; delete mChecker; diff --git a/src/AudacityApp.h b/src/AudacityApp.h index d1390fe4b..3558a1fdc 100644 --- a/src/AudacityApp.h +++ b/src/AudacityApp.h @@ -194,8 +194,6 @@ class AudacityApp:public wxApp { AudacityLogger *GetLogger(); - Importer *mImporter; - #if defined(__WXGTK__) /** \brief This flag is set true when in a keyboard event handler. * Used to work around a hang issue with ibus (bug 154) */ diff --git a/src/AudacityHeaders.h b/src/AudacityHeaders.h index 14754edfc..667d64b18 100644 --- a/src/AudacityHeaders.h +++ b/src/AudacityHeaders.h @@ -43,6 +43,8 @@ #include #endif +#include "audacity/Types.h" + #include "AColor.h" #include "AudacityApp.h" #include "AudioIO.h" @@ -68,11 +70,9 @@ #include "ViewInfo.h" #include "WaveTrack.h" #include "widgets/ASlider.h" -#include "widgets/Ruler.h" -#include "xml/XMLTagHandler.h" -#include "widgets/ASlider.h" #include "widgets/ProgressDialog.h" #include "widgets/Ruler.h" +#include "xml/XMLTagHandler.h" // PRL: These lines allow you to remove Project.h above. // They must be included before the definition of macro new below. diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 1079c593e..1723887d9 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -1371,6 +1371,13 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks, while( mAudioThreadShouldCallFillBuffersOnce == true ) wxMilliSleep( 50 ); +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + if (mNumPlaybackChannels > 0) + { + EffectManager::Get().RealtimeInitialize(1, sampleRate); + } +#endif + #ifdef EXPERIMENTAL_MIDI_OUT // if no playback, reset the midi time to zero to roughly sync // with recording (or if recording is not going to happen, just @@ -1419,6 +1426,10 @@ int AudioIO::StartStream(WaveTrackArray playbackTracks, void AudioIO::StartStreamCleanup(bool bOnlyBuffers) { +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + EffectManager::Get().RealtimeFinalize(); +#endif + if(mPlaybackBuffers) { for( unsigned int i = 0; i < mPlaybackTracks.GetCount(); i++ ) @@ -1600,6 +1611,11 @@ void AudioIO::StopStream() if (mStopStreamCount != 1) return; +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + // No longer need effects processing + EffectManager::Get().RealtimeFinalize(); +#endif + // // We got here in one of two ways: // @@ -1827,6 +1843,20 @@ void AudioIO::StopStream() void AudioIO::SetPaused(bool state) { +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + if (state != mPaused) + { + if (state) + { + EffectManager::Get().RealtimeSuspend(); + } + else + { + EffectManager::Get().RealtimeResume(); + } + } +#endif + mPaused = state; } @@ -3536,6 +3566,10 @@ int audacityAudioCallback(const void *inputBuffer, void *outputBuffer, if (cut) // no samples to process, they've been discarded continue; #endif + +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + EffectManager::Get().RealtimeProcessMono(tempFloats, len); +#endif if (vt->GetChannel() == Track::LeftChannel || vt->GetChannel() == Track::MonoChannel) diff --git a/src/AudioIO.h b/src/AudioIO.h index bfb73ac8e..483edd6dc 100644 --- a/src/AudioIO.h +++ b/src/AudioIO.h @@ -15,6 +15,7 @@ #include "portaudio.h" #include "Audacity.h" +#include "effects/Effect.h" #include "Experimental.h" #ifdef USE_MIDI diff --git a/src/BatchCommandDialog.cpp b/src/BatchCommandDialog.cpp index d88cb9a5d..91a8b3965 100644 --- a/src/BatchCommandDialog.cpp +++ b/src/BatchCommandDialog.cpp @@ -169,25 +169,24 @@ void BatchCommandDialog::OnItemSelected(wxListEvent &event) mCommand->SetValue( command ); wxString params = BatchCommands::GetCurrentParamsFor( command ); mParameters->SetValue( params ); - Effect * f = EffectManager::Get().GetEffectByIdentifier( command ); - mEditParams->Enable( f != NULL ); + PluginID ID = EffectManager::Get().GetEffectByIdentifier( command ); + mEditParams->Enable( !ID.empty() ); } void BatchCommandDialog::OnEditParams(wxCommandEvent & WXUNUSED(event)) { wxString command = mCommand->GetValue(); wxString params = mParameters->GetValue(); - Effect * f = EffectManager::Get().GetEffectByIdentifier( command ); - if( f==NULL ) - return; - BatchCommands::SetCurrentParametersFor( f, command, params ); - if( BatchCommands::PromptForParamsFor( command, this )) + if (BatchCommands::SetCurrentParametersFor( command, params )) { - // we've just prompted for the parameters, so the values - // that are current have changed. - params = BatchCommands::GetCurrentParamsFor( command ); - mParameters->SetValue( params.Strip(wxString::trailing) ); - mParameters->Refresh(); + if( BatchCommands::PromptForParamsFor( command, this )) + { + // we've just prompted for the parameters, so the values + // that are current have changed. + params = BatchCommands::GetCurrentParamsFor( command ); + mParameters->SetValue( params.Strip(wxString::trailing) ); + mParameters->Refresh(); + } } } diff --git a/src/BatchCommands.cpp b/src/BatchCommands.cpp index 85450a82d..13538530c 100644 --- a/src/BatchCommands.cpp +++ b/src/BatchCommands.cpp @@ -30,6 +30,7 @@ See also BatchCommandDialog and BatchProcessDialog. #include "effects/EffectManager.h" #include "FileNames.h" #include "Internat.h" +#include "PluginManager.h" #include "Prefs.h" #include "Shuttle.h" #include "export/ExportFLAC.h" @@ -264,9 +265,10 @@ wxArrayString BatchCommands::GetAllCommands() AudacityProject *project = GetActiveProject(); if (!project) + { return commands; + } - EffectArray * effects; unsigned int i; // CLEANSPEECH remnant @@ -276,18 +278,18 @@ wxArrayString BatchCommands::GetAllCommands() } // end CLEANSPEECH remnant - int additionalEffects=ADVANCED_EFFECT; - - effects = EffectManager::Get().GetEffects(PROCESS_EFFECT | BUILTIN_EFFECT | PLUGIN_EFFECT | additionalEffects); - for(i=0; iGetCount(); i++) { - if ((*effects)[i]->SupportsChains()) { - command=(*effects)[i]->GetEffectIdentifier(); - if (!command.IsEmpty()) { + PluginManager & pm = PluginManager::Get(); + EffectManager & em = EffectManager::Get(); + const PluginDescriptor *plug = pm.GetFirstPlugin(PluginTypeEffect); + while (plug) + { + command = em.GetEffectIdentifier(plug->GetID()); + if (!command.IsEmpty()) + { commands.Add( command); - } } + plug = pm.GetNextPlugin(PluginTypeEffect); } - delete effects; /* This is for later in development: include the menu commands. CommandManager * mManager = project->GetCommandManager(); @@ -304,29 +306,25 @@ wxArrayString BatchCommands::GetAllCommands() wxString BatchCommands::GetCurrentParamsFor(wxString command) { - Effect * f = EffectManager::Get().GetEffectByIdentifier( command ); - if( f==NULL ) - return wxT("");// effect not found. - ShuttleCli shuttle; - shuttle.mbStoreInClient=false; - f->TransferParameters( shuttle ); - if( shuttle.mParams.IsEmpty() ) - return wxT("");// effect had no parameters. + const PluginID & ID = EffectManager::Get().GetEffectByIdentifier(command); + if( ID.empty() ) + { + return wxEmptyString; // effect not found. + } - return shuttle.mParams; + return EffectManager::Get().GetEffectParameters(ID); } bool BatchCommands::PromptForParamsFor(wxString command, wxWindow *parent) { - Effect * f = EffectManager::Get().GetEffectByIdentifier(command); - if( f==NULL ) - return false; + const PluginID & ID = EffectManager::Get().GetEffectByIdentifier(command); - //mFactory = factory; - //mProjectRate = projectRate; - f->mParent = parent; - //mTracks = list; - return f->PromptUser(); + if (ID.empty()) + { + return false; + } + + return EffectManager::Get().PromptUser(ID, parent); } double BatchCommands::GetEndTime() @@ -469,9 +467,9 @@ bool BatchCommands::ApplySpecialCommand(int WXUNUSED(iCommand), const wxString c return WriteMp3File(filename, 56); } else if (command == wxT("StereoToMono")) { // StereoToMono is an effect masquerading as a menu item. - Effect * f = EffectManager::Get().GetEffectByIdentifier(wxT("StereoToMono")); - if (f != NULL) { - return ApplyEffectCommand(f, command, params); + const PluginID & ID = EffectManager::Get().GetEffectByIdentifier(wxT("StereoToMono")); + if (!ID.empty()) { + return ApplyEffectCommand(ID, command, params); } wxMessageBox(_("Stereo to Mono Effect not found")); return false; @@ -514,15 +512,17 @@ bool BatchCommands::ApplySpecialCommand(int WXUNUSED(iCommand), const wxString c } // end CLEANSPEECH remnant -bool BatchCommands::SetCurrentParametersFor( Effect * f, const wxString command, const wxString params) +bool BatchCommands::SetCurrentParametersFor(const wxString command, const wxString params) { // transfer the parameters to the effect... if( !params.IsEmpty() ) { - ShuttleCli shuttle; - shuttle.mParams = params; - shuttle.mbStoreInClient=true; - if( !f->TransferParameters( shuttle )) + const PluginID & ID = EffectManager::Get().GetEffectByIdentifier(command); + if (ID.empty()) + { + return false; + } + if (!EffectManager::Get().SetEffectParameters(ID, params)) { wxMessageBox( wxString::Format( @@ -533,7 +533,7 @@ bool BatchCommands::SetCurrentParametersFor( Effect * f, const wxString command, return true; } -bool BatchCommands::ApplyEffectCommand( Effect * f, const wxString command, const wxString params) +bool BatchCommands::ApplyEffectCommand(const PluginID & ID, const wxString command, const wxString params) { //Possibly end processing here, if in batch-debug if( ReportAndSkip(command, params)) @@ -547,7 +547,7 @@ bool BatchCommands::ApplyEffectCommand( Effect * f, const wxString command, co project->SelectAllIfNone(); // NOW actually apply the effect. - return project->OnEffect(ALL_EFFECTS | CONFIGURED_EFFECT , f, params, false); + return project->OnEffect(ALL_EFFECTS | CONFIGURED_EFFECT , ID, params, false); } bool BatchCommands::ApplyCommand(const wxString command, const wxString params) @@ -564,13 +564,16 @@ bool BatchCommands::ApplyCommand(const wxString command, const wxString params) // end CLEANSPEECH remnant // Test for an effect. - Effect * f = EffectManager::Get().GetEffectByIdentifier( command ); - if( f!=NULL ) - return ApplyEffectCommand( f, command, params ); + const PluginID & ID = EffectManager::Get().GetEffectByIdentifier( command ); + if (!ID.empty()) + { + return ApplyEffectCommand(ID, command, params); + } wxMessageBox( wxString::Format( _("Your batch command of %s was not recognized."), command.c_str() )); + return false; } diff --git a/src/BatchCommands.h b/src/BatchCommands.h index c88b20899..6e696d987 100644 --- a/src/BatchCommands.h +++ b/src/BatchCommands.h @@ -28,7 +28,7 @@ class BatchCommands { bool ApplyCommand( const wxString command, const wxString params ); bool ApplyCommandInBatchMode(const wxString & command, const wxString ¶ms); bool ApplySpecialCommand(int iCommand, const wxString command,const wxString params); - bool ApplyEffectCommand(Effect * f, const wxString command, const wxString params); + bool ApplyEffectCommand(const PluginID & ID, const wxString command, const wxString params); bool ReportAndSkip( const wxString command, const wxString params ); void AbortBatch(); @@ -41,7 +41,7 @@ class BatchCommands { wxArrayString GetNames(); static bool PromptForParamsFor( wxString command, wxWindow *parent ); static wxString GetCurrentParamsFor( wxString command ); - static bool SetCurrentParametersFor( Effect * f, const wxString command, const wxString params); + static bool SetCurrentParametersFor(const wxString command, const wxString params); static wxArrayString GetAllCommands(); // These commands do depend on the command list. diff --git a/src/BatchProcessDialog.cpp b/src/BatchProcessDialog.cpp index d87805da0..aec154e5a 100644 --- a/src/BatchProcessDialog.cpp +++ b/src/BatchProcessDialog.cpp @@ -39,6 +39,7 @@ #include "commands/CommandManager.h" #include "effects/Effect.h" #include "../images/Arrow.xpm" +#include "../images/Empty9x16.xpm" #include "BatchCommands.h" #include "UndoManager.h" @@ -211,12 +212,12 @@ void BatchProcessDialog::OnApplyToFiles(wxCommandEvent & WXUNUSED(event)) wxString all; l.DeleteContents(true); - wxGetApp().mImporter->GetSupportedImportFormats(&l); + Importer::Get().GetSupportedImportFormats(&l); for (FormatList::compatibility_iterator n = l.GetFirst(); n; n = n->GetNext()) { Format *f = n->GetData(); wxString newfilter = f->formatName + wxT("|"); - for (size_t i = 0; i < f->formatExtensions.GetCount(); i++) { + for (size_t i = 0; i < f->formatExtensions.size(); i++) { if (!newfilter.Contains(wxT("*.") + f->formatExtensions[i] + wxT(";"))) newfilter += wxT("*.") + f->formatExtensions[i] + wxT(";"); if (!all.Contains(wxT("*.") + f->formatExtensions[i] + wxT(";"))) @@ -271,7 +272,7 @@ void BatchProcessDialog::OnApplyToFiles(wxCommandEvent & WXUNUSED(event)) S.StartStatic(_("Applying..."), 1); { wxImageList *imageList = new wxImageList(9, 16); - imageList->Add(wxIcon(empty_9x16_xpm)); + imageList->Add(wxIcon(empty9x16_xpm)); imageList->Add(wxIcon(arrow_xpm)); S.SetStyle(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | diff --git a/src/Experimental.h b/src/Experimental.h index 34fc14f73..b25f0521d 100644 --- a/src/Experimental.h +++ b/src/Experimental.h @@ -175,4 +175,11 @@ // Module prefs provides a panel in prefs where users can choose which modules // to enable. #define EXPERIMENTAL_MODULE_PREFS + +// Define to include realtime effects processing. +#define EXPERIMENTAL_REALTIME_EFFECTS + +// Define to include the effects rack (such as it is). +#define EXPERIMENTAL_EFFECTS_RACK + #endif diff --git a/src/FileNames.cpp b/src/FileNames.cpp index 07f95e316..9663a23b8 100644 --- a/src/FileNames.cpp +++ b/src/FileNames.cpp @@ -167,7 +167,39 @@ wxString FileNames::PlugInDir() wxString FileNames::PluginsCache() { - return wxFileName( DataDir(), wxT("plugins.cfg") ).GetFullPath(); + return wxFileName( DataDir(), wxT("pluginregistry.cfg") ).GetFullPath(); +} + +wxString FileNames::BaseDir() +{ + wxFileName baseDir; + +#if defined(__WXMAC__) + baseDir = PlatformCompatibility::GetExecutablePath(); + + // This removes (for instance) "Audacity.app/Contents/MacOSX/" + baseDir.RemoveLastDir(); + baseDir.RemoveLastDir(); + baseDir.RemoveLastDir(); +#elif defined(__WXMSW__) + // Don't use wxStandardPaths::Get().GetDataDir() since it removes + // the "Debug" directory in debug builds. + baseDir = PlatformCompatibility::GetExecutablePath(); +#else + // Linux goes into /*prefix*/share/audacity/ + baseDir = wxStandardPaths::Get().GetDataDir(); +#endif + + return baseDir.GetPath(); +} + +wxString FileNames::ModulesDir() +{ + wxFileName modulesDir(BaseDir(), wxEmptyString); + + modulesDir.AppendDir(wxT("modules")); + + return modulesDir.GetFullPath(); } wxString FileNames::ThemeDir() diff --git a/src/FileNames.h b/src/FileNames.h index f5b4bb641..1e310371a 100644 --- a/src/FileNames.h +++ b/src/FileNames.h @@ -12,6 +12,7 @@ #define __AUDACITY_FILE_NAMES__ #include +#include "Audacity.h" class wxFileName; class wxArrayString; @@ -41,6 +42,9 @@ public: static wxString NRPFile(); static wxString PluginsCache(); + static wxString BaseDir(); + static wxString ModulesDir(); + /** \brief The user plug-in directory (not a system one) * * This returns the string path to where the user may have put plug-ins diff --git a/src/HistoryWindow.cpp b/src/HistoryWindow.cpp index 56e51b908..31cd38f6b 100644 --- a/src/HistoryWindow.cpp +++ b/src/HistoryWindow.cpp @@ -30,6 +30,7 @@ undo memory so as to free up space. #include #include "../images/Arrow.xpm" +#include "../images/Empty9x16.xpm" #include "HistoryWindow.h" #include "UndoManager.h" #include "Project.h" @@ -58,7 +59,7 @@ HistoryWindow::HistoryWindow(AudacityProject *parent, UndoManager *manager): mSelected = 0; wxImageList *imageList = new wxImageList(9, 16); - imageList->Add(wxIcon(empty_9x16_xpm)); + imageList->Add(wxIcon(empty9x16_xpm)); imageList->Add(wxIcon(arrow_xpm)); //------------------------- Main section -------------------- diff --git a/src/LoadModules.cpp b/src/LoadModules.cpp index 2ddc694ef..e69de29bb 100644 --- a/src/LoadModules.cpp +++ b/src/LoadModules.cpp @@ -1,313 +0,0 @@ -/********************************************************************** - - Audacity: A Digital Audio Editor - - LoadModules.cpp - - Dominic Mazzoni - James Crook - - -*******************************************************************//*! - -\file LoadModules.cpp -\brief Based on LoadLadspa, this code loads pluggable Audacity -extension modules. It also has the code to (a) invoke a script -server and (b) invoke a function returning a replacement window, -i.e. an alternative to the usual interface, for Audacity. - -*//*******************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include "Audacity.h" -#include "AudacityApp.h" -#include "Internat.h" - -#include "commands/ScriptCommandRelay.h" -#include // header from libwidgetextra - -#ifdef EXPERIMENTAL_MODULE_PREFS -#include "Prefs.h" -#include "./prefs/ModulePrefs.h" -#endif - -#include "LoadModules.h" -#include "widgets/MultiDialog.h" - -#define initFnName "ExtensionModuleInit" -#define versionFnName "GetVersionString" -#define scriptFnName "RegScriptServerFunc" -#define mainPanelFnName "MainPanelFunc" - -typedef wxWindow * pwxWindow; -typedef int (*tModuleInit)(int); -//typedef wxString (*tVersionFn)(); -typedef wxChar * (*tVersionFn)(); -typedef pwxWindow (*tPanelFn)(int); - -// This variable will hold the address of a subroutine in -// a DLL that can hijack the normal panel. -static tPanelFn pPanelHijack=NULL; - -// Next two commented out lines are handy when investigating -// strange DLL behaviour. Instead of dynamic linking, -// link the library which has the replacement panel statically. -// Give the address of the routine here. -// This is a great help in identifying missing -// symbols which otherwise cause a dll to unload after loading -// without an explanation as to why! -//extern wxWindow * MainPanelFunc( int i ); -//tPanelFn pPanelHijack=&MainPanelFunc; - -/// IF pPanelHijack has been found in a module DLL -/// THEN when this function is called we'll go and -/// create that window instead of the normal one. -wxWindow * MakeHijackPanel() -{ - if( pPanelHijack == NULL ) - return NULL; - return pPanelHijack(0); -} - -// This variable will hold the address of a subroutine in a DLL that -// starts a thread and reads script commands. -static tpRegScriptServerFunc scriptFn; - -Module::Module(const wxString & name) -{ - mName = name; - mLib = new wxDynamicLibrary(); - mDispatch = NULL; -} - -Module::~Module() -{ - delete mLib; -} - -bool Module::Load() -{ - if (mLib->IsLoaded()) { - if (mDispatch) { - return true; - } - return false; - } - - if (!mLib->Load(mName, wxDL_LAZY)) { - return false; - } - - // Check version string matches. (For now, they must match exactly) - tVersionFn versionFn = (tVersionFn)(mLib->GetSymbol(wxT(versionFnName))); - if (versionFn == NULL){ - wxString ShortName = wxFileName( mName ).GetName(); - wxMessageBox(wxString::Format(_("The module %s does not provide a version string.\nIt will not be loaded."), ShortName.c_str()), _("Module Unsuitable")); - wxLogMessage(wxString::Format(_("The module %s does not provide a version string. It will not be loaded."), mName.c_str())); - mLib->Unload(); - return false; - } - - wxString moduleVersion = versionFn(); - if( !moduleVersion.IsSameAs(AUDACITY_VERSION_STRING)) { - wxString ShortName = wxFileName( mName ).GetName(); - wxMessageBox(wxString::Format(_("The module %s is matched with Audacity version %s.\n\nIt will not be loaded."), ShortName.c_str(), moduleVersion.c_str()), _("Module Unsuitable")); - wxLogMessage(wxString::Format(_("The module %s is matched with Audacity version %s. It will not be loaded."), mName.c_str(), moduleVersion.c_str())); - mLib->Unload(); - return false; - } - - mDispatch = (fnModuleDispatch) mLib->GetSymbol(wxT(ModuleDispatchName)); - if (!mDispatch) { - // Module does not provide a dispatch function... - // That can be OK, as long as we never try to call it. - return true; - } - - // However if we do have it and it does not work, - // then the module is bad. - bool res = ((mDispatch(ModuleInitialize))!=0); - if (res) { - return true; - } - - mDispatch = NULL; - return false; -} - -void Module::Unload() -{ - if (mLib->IsLoaded()) { - mDispatch(ModuleTerminate); - } - - mLib->Unload(); -} - -int Module::Dispatch(ModuleDispatchTypes type) -{ - if (mLib->IsLoaded()) - if( mDispatch != NULL ) - return mDispatch(type); - - return 0; -} - -void * Module::GetSymbol(wxString name) -{ - return mLib->GetSymbol(name); -} - -// -// Module Manager -// -ModuleManager *ModuleManager::mInstance; - -bool ModuleManager::OnInit() -{ - mInstance = this; - - return true; -} - -void ModuleManager::OnExit() -{ - size_t cnt = mModules.GetCount(); - - for (size_t ndx = 0; ndx < cnt; ndx++) { - delete (Module *) mModules[ndx]; - } - mModules.Clear(); -} - -void ModuleManager::Initialize(CommandHandler &cmdHandler) -{ - wxArrayString audacityPathList = wxGetApp().audacityPathList; - wxArrayString pathList; - wxArrayString files; - wxString pathVar; - size_t i; - - // Code from LoadLadspa that might be useful in load modules. - pathVar = wxGetenv(wxT("AUDACITY_MODULES_PATH")); - if (pathVar != wxT("")) - wxGetApp().AddMultiPathsToPathList(pathVar, pathList); - - for (i = 0; i < audacityPathList.GetCount(); i++) { - wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH; - wxGetApp().AddUniquePathToPathList(prefix + wxT("modules"), - pathList); - } - - #if defined(__WXMSW__) - wxGetApp().FindFilesInPathList(wxT("*.dll"), pathList, files); - #else - wxGetApp().FindFilesInPathList(wxT("*.so"), pathList, files); - #endif - - for (i = 0; i < files.GetCount(); i++) { - // As a courtesy to some modules that might be bridges to - // open other modules, we set the current working - // directory to be the module's directory. - wxString saveOldCWD = ::wxGetCwd(); - wxString prefix = ::wxPathOnly(files[i]); - ::wxSetWorkingDirectory(prefix); - -#ifdef EXPERIMENTAL_MODULE_PREFS - int iModuleStatus = ModulePrefs::GetModuleStatus( files[i] ); - if( iModuleStatus == kModuleDisabled ) - continue; - if( iModuleStatus == kModuleFailed ) - continue; - // New module? You have to go and explicitly enable it. - if( iModuleStatus == kModuleNew ){ - // To ensure it is noted in config file and so - // appears on modules page. - ModulePrefs::SetModuleStatus( files[i], kModuleNew); - continue; - } - - if( iModuleStatus == kModuleAsk ) -#endif - // JKC: I don't like prompting for the plug-ins individually - // I think it would be better to show the module prefs page, - // and let the user decide for each one. - { - wxString ShortName = wxFileName( files[i] ).GetName(); - wxString msg; - msg.Printf(_("Module \"%s\" found."), ShortName.c_str()); - msg += _("\n\nOnly use modules from trusted sources"); - const wxChar *buttons[] = {_("Yes"), _("No"), NULL}; // could add a button here for 'yes and remember that', and put it into the cfg file. Needs more thought. - int action; - action = ShowMultiDialog(msg, _("Audacity Module Loader"), buttons, _("Try and load this module?"), false); -#ifdef EXPERIMENTAL_MODULE_PREFS - // If we're not prompting always, accept the answer permanantly - if( iModuleStatus == kModuleNew ){ - iModuleStatus = (action==1)?kModuleDisabled : kModuleEnabled; - ModulePrefs::SetModuleStatus( files[i], iModuleStatus ); - } -#endif - if(action == 1){ // "No" - continue; - } - } -#ifdef EXPERIMENTAL_MODULE_PREFS - // Before attempting to load, we set the state to bad. - // That way, if we crash, we won't try again. - ModulePrefs::SetModuleStatus( files[i], kModuleFailed ); -#endif - - Module *module = new Module(files[i]); - if (module->Load()) // it will get rejected if there are version problems - { - mInstance->mModules.Add(module); - // We've loaded and initialised OK. - // So look for special case functions: - wxLogNull logNo; // Don't show wxWidgets errors if we can't do these. (Was: Fix bug 544.) - // (a) for scripting. - if( scriptFn == NULL ) - scriptFn = (tpRegScriptServerFunc)(module->GetSymbol(wxT(scriptFnName))); - // (b) for hijacking the entire Audacity panel. - if( pPanelHijack==NULL ) - { - pPanelHijack = (tPanelFn)(module->GetSymbol(wxT(mainPanelFnName))); - } -#ifdef EXPERIMENTAL_MODULE_PREFS - // Loaded successfully, restore the status. - ModulePrefs::SetModuleStatus( files[i], iModuleStatus); -#endif - } - else { - // No need to save status, as we already set kModuleFailed. - delete module; - } - ::wxSetWorkingDirectory(saveOldCWD); - } - // After loading all the modules, we may have a registered scripting function. - if(scriptFn) - { - ScriptCommandRelay::SetCommandHandler(cmdHandler); - ScriptCommandRelay::SetRegScriptServerFunc(scriptFn); - NonGuiThread::StartChild(&ScriptCommandRelay::Run); - } -} - -int ModuleManager::Dispatch(ModuleDispatchTypes type) -{ - size_t cnt = mInstance->mModules.GetCount(); - - for (size_t ndx = 0; ndx < cnt; ndx++) { - Module *module = (Module *)mInstance->mModules[ndx]; - - module->Dispatch(type); - } - return 0; -} - -IMPLEMENT_DYNAMIC_CLASS(ModuleManager, wxModule); diff --git a/src/LoadModules.h b/src/LoadModules.h index bb9cbb461..e69de29bb 100644 --- a/src/LoadModules.h +++ b/src/LoadModules.h @@ -1,79 +0,0 @@ -/********************************************************************** - - Audacity: A Digital Audio Editor - - LoadModules.h - - Dominic Mazzoni - James Crook - -**********************************************************************/ - -#ifndef __AUDACITY_LOADMODULES_H__ -#define __AUDACITY_LOADMODULES_H__ - -#include -#include - -class CommandHandler; - -wxWindow * MakeHijackPanel(); - -// -// Module Manager -// -// wxPluginManager would be MUCH better, but it's an "undocumented" framework. -// -#define ModuleDispatchName "ModuleDispatch" - -typedef enum -{ - ModuleInitialize, - ModuleTerminate, - AppInitialized, - AppQuiting, - ProjectInitialized, - ProjectClosing, - MenusRebuilt -} ModuleDispatchTypes; - -typedef int (*fnModuleDispatch)(ModuleDispatchTypes type); - -class Module -{ -public: - Module(const wxString & name); - virtual ~Module(); - - bool Load(); - void Unload(); - int Dispatch(ModuleDispatchTypes type); - void * GetSymbol(wxString name); - -private: - wxString mName; - wxDynamicLibrary *mLib; - fnModuleDispatch mDispatch; -}; - -class ModuleManager:public wxModule -{ -public: - ModuleManager() {}; - virtual ~ModuleManager() {}; - - virtual bool OnInit(); - virtual void OnExit(); - - static void Initialize(CommandHandler &cmdHandler); - static int Dispatch(ModuleDispatchTypes type); - -private: - static ModuleManager *mInstance; - - wxArrayPtrVoid mModules; - - DECLARE_DYNAMIC_CLASS(ModuleManager); -}; - -#endif /* __AUDACITY_LOADMODULES_H__ */ diff --git a/src/Makefile.am b/src/Makefile.am index 8d5f153ee..bc28b6e39 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -149,8 +149,6 @@ audacity_SOURCES = \ Languages.h \ Legacy.cpp \ Legacy.h \ - LoadModules.cpp \ - LoadModules.h \ Lyrics.cpp \ Lyrics.h \ LyricsWindow.cpp \ @@ -164,6 +162,8 @@ audacity_SOURCES = \ Mix.h \ MixerBoard.cpp \ MixerBoard.h \ + ModuleManager.cpp \ + ModuleManager.h \ PitchName.cpp \ PitchName.h \ PlatformCompatibility.cpp \ @@ -318,6 +318,8 @@ audacity_SOURCES = \ effects/EffectCategory.h \ effects/EffectManager.cpp \ effects/EffectManager.h \ + effects/EffectRack.cpp \ + effects/EffectRack.h \ effects/Equalization.cpp \ effects/Equalization.h \ effects/Equalization48x.cpp \ diff --git a/src/Makefile.in b/src/Makefile.in index c07dc9450..ad29a9078 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -299,10 +299,10 @@ am__audacity_SOURCES_DIST = BlockFile.cpp BlockFile.h DirManager.cpp \ ImageManipulation.h InterpolateAudio.cpp InterpolateAudio.h \ LabelDialog.cpp LabelDialog.h LabelTrack.cpp LabelTrack.h \ LangChoice.cpp LangChoice.h Languages.cpp Languages.h \ - Legacy.cpp Legacy.h LoadModules.cpp LoadModules.h Lyrics.cpp \ - Lyrics.h LyricsWindow.cpp LyricsWindow.h MacroMagic.h \ - Matrix.cpp Matrix.h Menus.cpp Menus.h Mix.cpp Mix.h \ - MixerBoard.cpp MixerBoard.h PitchName.cpp PitchName.h \ + Legacy.cpp Legacy.h Lyrics.cpp Lyrics.h LyricsWindow.cpp \ + LyricsWindow.h MacroMagic.h Matrix.cpp Matrix.h Menus.cpp \ + Menus.h Mix.cpp Mix.h MixerBoard.cpp MixerBoard.h \ + ModuleManager.cpp ModuleManager.h PitchName.cpp PitchName.h \ PlatformCompatibility.cpp PlatformCompatibility.h \ PluginManager.cpp PluginManager.h Printing.cpp Printing.h \ Profiler.cpp Profiler.h Project.cpp Project.h RealFFTf.cpp \ @@ -363,6 +363,7 @@ am__audacity_SOURCES_DIST = BlockFile.cpp BlockFile.h DirManager.cpp \ effects/Echo.h effects/Effect.cpp effects/Effect.h \ effects/EffectCategory.cpp effects/EffectCategory.h \ effects/EffectManager.cpp effects/EffectManager.h \ + effects/EffectRack.cpp effects/EffectRack.h \ effects/Equalization.cpp effects/Equalization.h \ effects/Equalization48x.cpp effects/Equalization48x.h \ effects/Fade.cpp effects/Fade.h effects/FindClipping.cpp \ @@ -538,10 +539,10 @@ am_audacity_OBJECTS = $(am__objects_1) audacity-AboutDialog.$(OBJEXT) \ audacity-InterpolateAudio.$(OBJEXT) \ audacity-LabelDialog.$(OBJEXT) audacity-LabelTrack.$(OBJEXT) \ audacity-LangChoice.$(OBJEXT) audacity-Languages.$(OBJEXT) \ - audacity-Legacy.$(OBJEXT) audacity-LoadModules.$(OBJEXT) \ - audacity-Lyrics.$(OBJEXT) audacity-LyricsWindow.$(OBJEXT) \ - audacity-Matrix.$(OBJEXT) audacity-Menus.$(OBJEXT) \ - audacity-Mix.$(OBJEXT) audacity-MixerBoard.$(OBJEXT) \ + audacity-Legacy.$(OBJEXT) audacity-Lyrics.$(OBJEXT) \ + audacity-LyricsWindow.$(OBJEXT) audacity-Matrix.$(OBJEXT) \ + audacity-Menus.$(OBJEXT) audacity-Mix.$(OBJEXT) \ + audacity-MixerBoard.$(OBJEXT) audacity-ModuleManager.$(OBJEXT) \ audacity-PitchName.$(OBJEXT) \ audacity-PlatformCompatibility.$(OBJEXT) \ audacity-PluginManager.$(OBJEXT) audacity-Printing.$(OBJEXT) \ @@ -602,6 +603,7 @@ am_audacity_OBJECTS = $(am__objects_1) audacity-AboutDialog.$(OBJEXT) \ effects/audacity-Effect.$(OBJEXT) \ effects/audacity-EffectCategory.$(OBJEXT) \ effects/audacity-EffectManager.$(OBJEXT) \ + effects/audacity-EffectRack.$(OBJEXT) \ effects/audacity-Equalization.$(OBJEXT) \ effects/audacity-Equalization48x.$(OBJEXT) \ effects/audacity-Fade.$(OBJEXT) \ @@ -1163,10 +1165,10 @@ audacity_SOURCES = $(libaudacity_la_SOURCES) AboutDialog.cpp \ ImageManipulation.h InterpolateAudio.cpp InterpolateAudio.h \ LabelDialog.cpp LabelDialog.h LabelTrack.cpp LabelTrack.h \ LangChoice.cpp LangChoice.h Languages.cpp Languages.h \ - Legacy.cpp Legacy.h LoadModules.cpp LoadModules.h Lyrics.cpp \ - Lyrics.h LyricsWindow.cpp LyricsWindow.h MacroMagic.h \ - Matrix.cpp Matrix.h Menus.cpp Menus.h Mix.cpp Mix.h \ - MixerBoard.cpp MixerBoard.h PitchName.cpp PitchName.h \ + Legacy.cpp Legacy.h Lyrics.cpp Lyrics.h LyricsWindow.cpp \ + LyricsWindow.h MacroMagic.h Matrix.cpp Matrix.h Menus.cpp \ + Menus.h Mix.cpp Mix.h MixerBoard.cpp MixerBoard.h \ + ModuleManager.cpp ModuleManager.h PitchName.cpp PitchName.h \ PlatformCompatibility.cpp PlatformCompatibility.h \ PluginManager.cpp PluginManager.h Printing.cpp Printing.h \ Profiler.cpp Profiler.h Project.cpp Project.h RealFFTf.cpp \ @@ -1227,6 +1229,7 @@ audacity_SOURCES = $(libaudacity_la_SOURCES) AboutDialog.cpp \ effects/Echo.h effects/Effect.cpp effects/Effect.h \ effects/EffectCategory.cpp effects/EffectCategory.h \ effects/EffectManager.cpp effects/EffectManager.h \ + effects/EffectRack.cpp effects/EffectRack.h \ effects/Equalization.cpp effects/Equalization.h \ effects/Equalization48x.cpp effects/Equalization48x.h \ effects/Fade.cpp effects/Fade.h effects/FindClipping.cpp \ @@ -1599,6 +1602,8 @@ effects/audacity-EffectCategory.$(OBJEXT): effects/$(am__dirstamp) \ effects/$(DEPDIR)/$(am__dirstamp) effects/audacity-EffectManager.$(OBJEXT): effects/$(am__dirstamp) \ effects/$(DEPDIR)/$(am__dirstamp) +effects/audacity-EffectRack.$(OBJEXT): effects/$(am__dirstamp) \ + effects/$(DEPDIR)/$(am__dirstamp) effects/audacity-Equalization.$(OBJEXT): effects/$(am__dirstamp) \ effects/$(DEPDIR)/$(am__dirstamp) effects/audacity-Equalization48x.$(OBJEXT): effects/$(am__dirstamp) \ @@ -2000,13 +2005,13 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-LangChoice.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Languages.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Legacy.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-LoadModules.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Lyrics.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-LyricsWindow.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Matrix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Menus.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-Mix.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-MixerBoard.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-ModuleManager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-NoteTrack.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-PitchName.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audacity-PlatformCompatibility.Po@am__quote@ @@ -2107,6 +2112,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/audacity-Effect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/audacity-EffectCategory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/audacity-EffectManager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/audacity-EffectRack.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/audacity-Equalization.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/audacity-Equalization48x.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@effects/$(DEPDIR)/audacity-Fade.Po@am__quote@ @@ -2991,20 +2997,6 @@ audacity-Legacy.obj: Legacy.cpp @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o audacity-Legacy.obj `if test -f 'Legacy.cpp'; then $(CYGPATH_W) 'Legacy.cpp'; else $(CYGPATH_W) '$(srcdir)/Legacy.cpp'; fi` -audacity-LoadModules.o: LoadModules.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-LoadModules.o -MD -MP -MF $(DEPDIR)/audacity-LoadModules.Tpo -c -o audacity-LoadModules.o `test -f 'LoadModules.cpp' || echo '$(srcdir)/'`LoadModules.cpp -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-LoadModules.Tpo $(DEPDIR)/audacity-LoadModules.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='LoadModules.cpp' object='audacity-LoadModules.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o audacity-LoadModules.o `test -f 'LoadModules.cpp' || echo '$(srcdir)/'`LoadModules.cpp - -audacity-LoadModules.obj: LoadModules.cpp -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-LoadModules.obj -MD -MP -MF $(DEPDIR)/audacity-LoadModules.Tpo -c -o audacity-LoadModules.obj `if test -f 'LoadModules.cpp'; then $(CYGPATH_W) 'LoadModules.cpp'; else $(CYGPATH_W) '$(srcdir)/LoadModules.cpp'; fi` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-LoadModules.Tpo $(DEPDIR)/audacity-LoadModules.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='LoadModules.cpp' object='audacity-LoadModules.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o audacity-LoadModules.obj `if test -f 'LoadModules.cpp'; then $(CYGPATH_W) 'LoadModules.cpp'; else $(CYGPATH_W) '$(srcdir)/LoadModules.cpp'; fi` - audacity-Lyrics.o: Lyrics.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-Lyrics.o -MD -MP -MF $(DEPDIR)/audacity-Lyrics.Tpo -c -o audacity-Lyrics.o `test -f 'Lyrics.cpp' || echo '$(srcdir)/'`Lyrics.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-Lyrics.Tpo $(DEPDIR)/audacity-Lyrics.Po @@ -3089,6 +3081,20 @@ audacity-MixerBoard.obj: MixerBoard.cpp @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o audacity-MixerBoard.obj `if test -f 'MixerBoard.cpp'; then $(CYGPATH_W) 'MixerBoard.cpp'; else $(CYGPATH_W) '$(srcdir)/MixerBoard.cpp'; fi` +audacity-ModuleManager.o: ModuleManager.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-ModuleManager.o -MD -MP -MF $(DEPDIR)/audacity-ModuleManager.Tpo -c -o audacity-ModuleManager.o `test -f 'ModuleManager.cpp' || echo '$(srcdir)/'`ModuleManager.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-ModuleManager.Tpo $(DEPDIR)/audacity-ModuleManager.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ModuleManager.cpp' object='audacity-ModuleManager.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o audacity-ModuleManager.o `test -f 'ModuleManager.cpp' || echo '$(srcdir)/'`ModuleManager.cpp + +audacity-ModuleManager.obj: ModuleManager.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-ModuleManager.obj -MD -MP -MF $(DEPDIR)/audacity-ModuleManager.Tpo -c -o audacity-ModuleManager.obj `if test -f 'ModuleManager.cpp'; then $(CYGPATH_W) 'ModuleManager.cpp'; else $(CYGPATH_W) '$(srcdir)/ModuleManager.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-ModuleManager.Tpo $(DEPDIR)/audacity-ModuleManager.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ModuleManager.cpp' object='audacity-ModuleManager.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o audacity-ModuleManager.obj `if test -f 'ModuleManager.cpp'; then $(CYGPATH_W) 'ModuleManager.cpp'; else $(CYGPATH_W) '$(srcdir)/ModuleManager.cpp'; fi` + audacity-PitchName.o: PitchName.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT audacity-PitchName.o -MD -MP -MF $(DEPDIR)/audacity-PitchName.Tpo -c -o audacity-PitchName.o `test -f 'PitchName.cpp' || echo '$(srcdir)/'`PitchName.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/audacity-PitchName.Tpo $(DEPDIR)/audacity-PitchName.Po @@ -4125,6 +4131,20 @@ effects/audacity-EffectManager.obj: effects/EffectManager.cpp @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o effects/audacity-EffectManager.obj `if test -f 'effects/EffectManager.cpp'; then $(CYGPATH_W) 'effects/EffectManager.cpp'; else $(CYGPATH_W) '$(srcdir)/effects/EffectManager.cpp'; fi` +effects/audacity-EffectRack.o: effects/EffectRack.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT effects/audacity-EffectRack.o -MD -MP -MF effects/$(DEPDIR)/audacity-EffectRack.Tpo -c -o effects/audacity-EffectRack.o `test -f 'effects/EffectRack.cpp' || echo '$(srcdir)/'`effects/EffectRack.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) effects/$(DEPDIR)/audacity-EffectRack.Tpo effects/$(DEPDIR)/audacity-EffectRack.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='effects/EffectRack.cpp' object='effects/audacity-EffectRack.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o effects/audacity-EffectRack.o `test -f 'effects/EffectRack.cpp' || echo '$(srcdir)/'`effects/EffectRack.cpp + +effects/audacity-EffectRack.obj: effects/EffectRack.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT effects/audacity-EffectRack.obj -MD -MP -MF effects/$(DEPDIR)/audacity-EffectRack.Tpo -c -o effects/audacity-EffectRack.obj `if test -f 'effects/EffectRack.cpp'; then $(CYGPATH_W) 'effects/EffectRack.cpp'; else $(CYGPATH_W) '$(srcdir)/effects/EffectRack.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) effects/$(DEPDIR)/audacity-EffectRack.Tpo effects/$(DEPDIR)/audacity-EffectRack.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='effects/EffectRack.cpp' object='effects/audacity-EffectRack.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -c -o effects/audacity-EffectRack.obj `if test -f 'effects/EffectRack.cpp'; then $(CYGPATH_W) 'effects/EffectRack.cpp'; else $(CYGPATH_W) '$(srcdir)/effects/EffectRack.cpp'; fi` + effects/audacity-Equalization.o: effects/Equalization.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(audacity_CPPFLAGS) $(CPPFLAGS) $(audacity_CXXFLAGS) $(CXXFLAGS) -MT effects/audacity-Equalization.o -MD -MP -MF effects/$(DEPDIR)/audacity-Equalization.Tpo -c -o effects/audacity-Equalization.o `test -f 'effects/Equalization.cpp' || echo '$(srcdir)/'`effects/Equalization.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) effects/$(DEPDIR)/audacity-Equalization.Tpo effects/$(DEPDIR)/audacity-Equalization.Po diff --git a/src/Menus.cpp b/src/Menus.cpp index 4ee4b8ab2..23ffc8170 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -74,7 +74,8 @@ simplifies construction of menu items. #include "MixerBoard.h" #include "Internat.h" #include "FileFormats.h" -#include "LoadModules.h" +#include "ModuleManager.h" +#include "PluginManager.h" #include "Prefs.h" #include "Printing.h" #ifdef USE_MIDI @@ -143,6 +144,7 @@ AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *pr mCommandFunction = commandFunction; mCommandKeyFunction = NULL; mCommandListFunction = NULL; + mCommandPluginFunction = NULL; } AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *project, @@ -152,6 +154,7 @@ AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *pr mCommandFunction = NULL; mCommandKeyFunction = commandFunction; mCommandListFunction = NULL; + mCommandPluginFunction = NULL; } AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *project, @@ -161,8 +164,22 @@ AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *pr mCommandFunction = NULL; mCommandKeyFunction = NULL; mCommandListFunction = commandFunction; + mCommandPluginFunction = NULL; } +AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *project, + audCommandPluginFunction commandFunction, + const PluginID & pluginID) +{ + mProject = project; + mCommandFunction = NULL; + mCommandKeyFunction = NULL; + mCommandListFunction = NULL; + mCommandPluginFunction = commandFunction; + mPluginID = pluginID; +} + +#if defined(EFFECT_CATEGORIES) AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *project, audCommandListFunction commandFunction, wxArrayInt explicitIndices) @@ -171,13 +188,19 @@ AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *pr mCommandFunction = NULL; mCommandKeyFunction = NULL; mCommandListFunction = commandFunction; + mCommandPluginFunction = NULL; mExplicitIndices = explicitIndices; } +#endif void AudacityProjectCommandFunctor::operator()(int index, const wxEvent * evt) { - if (mCommandListFunction && mExplicitIndices.GetCount() > 0) + if (mCommandPluginFunction) + (mProject->*(mCommandPluginFunction)) (mPluginID); +#if defined(EFFECT_CATEGORIES) + else if (mCommandListFunction && mExplicitIndices.GetCount() > 0) (mProject->*(mCommandListFunction)) (mExplicitIndices[index]); +#endif else if (mCommandListFunction) (mProject->*(mCommandListFunction)) (index); else if (mCommandKeyFunction) @@ -186,9 +209,14 @@ void AudacityProjectCommandFunctor::operator()(int index, const wxEvent * evt) (mProject->*(mCommandFunction)) (); } - #define FN(X) new AudacityProjectCommandFunctor(this, &AudacityProject:: X ) #define FNI(X, I) new AudacityProjectCommandFunctor(this, &AudacityProject:: X, I) +#define FNS(X, S) new AudacityProjectCommandFunctor(this, &AudacityProject:: X, S) + +static bool SortPlugs(const PluginDescriptor *a, const PluginDescriptor *b) +{ + return a->GetMenuName() < b->GetMenuName(); +} /// CreateMenusAndCommands builds the menus, and also rebuilds them after /// changes in configured preferences - for example changes in key-bindings @@ -832,6 +860,15 @@ void AudacityProject::CreateMenusAndCommands() c->EndMenu(); + // All of this is a bit hacky until we can get more things connected into + // the plugin manager...sorry! :-( + + wxArrayString defaults; + PluginManager & pm = PluginManager::Get(); + const PluginDescriptor *plug; + bool needsep; + + ////////////////////////////////////////////////////////////////////////// // Generate Menu ////////////////////////////////////////////////////////////////////////// @@ -839,29 +876,49 @@ void AudacityProject::CreateMenusAndCommands() c->BeginMenu(_("&Generate")); c->SetDefaultFlags(AudioIONotBusyFlag, AudioIONotBusyFlag); + typedef std::set SortedPlugs; + SortedPlugs defaultplugs(SortPlugs); + SortedPlugs extraplugs(SortPlugs); + #ifndef EFFECT_CATEGORIES - - effects = em.GetEffects(INSERT_EFFECT | BUILTIN_EFFECT); - if (effects->GetCount()) { - names.Clear(); - for (size_t i = 0; i < effects->GetCount(); i++) { - names.Add((*effects)[i]->GetEffectName()); + plug = pm.GetFirstPluginForEffectType(EffectTypeGenerate); + while (plug) { + if (plug->IsEffectDefault()) { + defaultplugs.insert(plug); } - c->AddItemList(wxT("Generate"), names, FN(OnGenerateEffect)); - } - delete effects; - - effects = em.GetEffects(INSERT_EFFECT | PLUGIN_EFFECT); - if (effects->GetCount()) { - c->AddSeparator(); - names.Clear(); - for (size_t i = 0; i < effects->GetCount(); i++) { - names.Add((*effects)[i]->GetEffectName()); + else { + extraplugs.insert(plug); } - c->AddItemList(wxT("GeneratePlugin"), names, FN(OnGeneratePlugin), true); + plug = pm.GetNextPluginForEffectType(EffectTypeGenerate); } - delete effects; + for (SortedPlugs::iterator iter = defaultplugs.begin(); iter != defaultplugs.end(); iter++) + { + const PluginDescriptor *plug = *iter; +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + int flags = plug->IsEffectRealtimeCapable() ? + AudioIONotBusyFlag : + TracksExistFlag; +#else + int flags = TracksExistFlag; +#endif + c->AddItem(plug->GetName(), + plug->GetMenuName(), + FNS(OnEffect, plug->GetID())); + } + + needsep = true; + for (SortedPlugs::iterator iter = extraplugs.begin(); iter != extraplugs.end(); iter++) + { + const PluginDescriptor *plug = *iter; + if (needsep) { + c->AddSeparator(); + needsep = false; + } + c->AddItem(plug->GetName(), + plug->GetMenuName(), + FNS(OnEffect, plug->GetID())); + } #else int flags; @@ -887,7 +944,7 @@ void AudacityProject::CreateMenusAndCommands() EffectSet::const_iterator iter; for (iter = unsorted.begin(); iter != unsorted.end(); ++iter) { names.Add((*iter)->GetEffectName()); - indices.Add((*iter)->GetID()); + indices.Add((*iter)->GetEffectID()); } c->AddItemList(wxT("Generate"), names, FNI(OnProcessAny, indices), true); @@ -903,12 +960,11 @@ void AudacityProject::CreateMenusAndCommands() ///////////////////////////////////////////////////////////////////////////// c->BeginMenu(_("Effe&ct")); - c->SetDefaultFlags(AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag, - AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag); wxString buildMenuLabel; if (mLastEffectType != 0) { - buildMenuLabel.Printf(_("Repeat %s"), mLastEffect->GetEffectName().c_str()); + buildMenuLabel.Printf(_("Repeat %s"), + EffectManager::Get().GetEffectName(mLastEffect).c_str()); } else buildMenuLabel.Printf(_("Repeat Last Effect")); @@ -925,30 +981,57 @@ void AudacityProject::CreateMenusAndCommands() // effects at all in the menu when EFFECT_CATEGORIES is undefined #ifndef EFFECT_CATEGORIES - - effects = em.GetEffects(PROCESS_EFFECT | BUILTIN_EFFECT | additionalEffects); - if (effects->GetCount()) { - names.Clear(); - for (size_t i = 0; i < effects->GetCount(); i++) { - names.Add((*effects)[i]->GetEffectName()); + defaultplugs.clear(); + extraplugs.clear(); + plug = pm.GetFirstPluginForEffectType(EffectTypeProcess); + while (plug) { + if (plug->IsEffectDefault()) { + defaultplugs.insert(plug); } - c->AddItemList(wxT("Effect"), names, FN(OnProcessEffect)); - } - delete effects; - - effects = em.GetEffects(PROCESS_EFFECT | PLUGIN_EFFECT); - if (effects->GetCount()) { - c->AddSeparator(); - names.Clear(); - for (size_t i = 0; i < effects->GetCount(); i++) { - names.Add((*effects)[i]->GetEffectName()); + else { + extraplugs.insert(plug); } - c->AddItemList(wxT("EffectPlugin"), names, FN(OnProcessPlugin), true); + plug = pm.GetNextPluginForEffectType(EffectTypeProcess); } - delete effects; - c->EndMenu(); + for (SortedPlugs::iterator iter = defaultplugs.begin(); iter != defaultplugs.end(); iter++) + { + const PluginDescriptor *plug = *iter; +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + int flags = plug->IsEffectRealtimeCapable() ? + TracksExistFlag : + AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag; +#else + int flags = AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag; +#endif + c->AddItem(plug->GetName(), + plug->GetMenuName(), + FNS(OnEffect, plug->GetID()), + flags, + flags); + } + needsep = true; + for (SortedPlugs::iterator iter = extraplugs.begin(); iter != extraplugs.end(); iter++) + { + const PluginDescriptor *plug = *iter; + if (needsep) { + c->AddSeparator(); + needsep = false; + } +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + int flags = plug->IsEffectRealtimeCapable() ? + TracksExistFlag : + AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag; +#else + int flags = AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag; +#endif + c->AddItem(plug->GetName(), + plug->GetMenuName(), + FNS(OnEffect, plug->GetID()), + flags, + flags); + } #else int flags = PROCESS_EFFECT | BUILTIN_EFFECT | PLUGIN_EFFECT | ADVANCED_EFFECT; // The categories form a DAG, so we start at the roots (the categories @@ -968,15 +1051,16 @@ void AudacityProject::CreateMenusAndCommands() EffectSet::const_iterator iter; for (iter = unsorted.begin(); iter != unsorted.end(); ++iter) { names.Add((*iter)->GetEffectName()); - indices.Add((*iter)->GetID()); + indices.Add((*iter)->GetEffectID()); } c->AddItemList(wxT("Effect"), names, FNI(OnProcessAny, indices), true); c->EndSubMenu(); } - c->EndMenu(); #endif + c->EndMenu(); + ////////////////////////////////////////////////////////////////////////// // Analyze Menu ////////////////////////////////////////////////////////////////////////// @@ -991,28 +1075,57 @@ void AudacityProject::CreateMenusAndCommands() AudioIONotBusyFlag | WaveTracksSelectedFlag | TimeSelectedFlag); #ifndef EFFECT_CATEGORIES - - effects = em.GetEffects(ANALYZE_EFFECT | BUILTIN_EFFECT); - if (effects->GetCount()) { - names.Clear(); - for (size_t i = 0; i < effects->GetCount(); i++) { - names.Add((*effects)[i]->GetEffectName()); + defaultplugs.clear(); + extraplugs.clear(); + plug = pm.GetFirstPluginForEffectType(EffectTypeAnalyze); + while (plug) { + if (plug->IsEffectDefault()) { + defaultplugs.insert(plug); } - c->AddItemList(wxT("Analyze"), names, FN(OnAnalyzeEffect)); - } - delete effects; - - effects = em.GetEffects(ANALYZE_EFFECT | PLUGIN_EFFECT); - if (effects->GetCount()) { - c->AddSeparator(); - names.Clear(); - for (size_t i = 0; i < effects->GetCount(); i++) { - names.Add((*effects)[i]->GetEffectName()); + else { + extraplugs.insert(plug); } - c->AddItemList(wxT("AnalyzePlugin"), names, FN(OnAnalyzePlugin), true); + plug = pm.GetNextPluginForEffectType(EffectTypeAnalyze); } - delete effects; + for (SortedPlugs::iterator iter = defaultplugs.begin(); iter != defaultplugs.end(); iter++) + { + const PluginDescriptor *plug = *iter; +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + int flags = plug->IsEffectRealtimeCapable() ? + TracksExistFlag : + AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag; +#else + int flags = AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag; +#endif + c->AddItem(plug->GetName(), + plug->GetMenuName(), + FNS(OnEffect, plug->GetID()), + flags, + flags); + } + + needsep = true; + for (SortedPlugs::iterator iter = extraplugs.begin(); iter != extraplugs.end(); iter++) + { + const PluginDescriptor *plug = *iter; + if (needsep) { + c->AddSeparator(); + needsep = false; + } +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + int flags = plug->IsEffectRealtimeCapable() ? + TracksExistFlag : + AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag; +#else + int flags = AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag; +#endif + c->AddItem(plug->GetName(), + plug->GetMenuName(), + FNS(OnEffect, plug->GetID()), + flags, + flags); + } #else flags = ANALYZE_EFFECT | BUILTIN_EFFECT | PLUGIN_EFFECT; @@ -1036,7 +1149,7 @@ void AudacityProject::CreateMenusAndCommands() EffectSet::const_iterator iter; for (iter = unsorted.begin(); iter != unsorted.end(); ++iter) { names.Add((*iter)->GetEffectName()); - indices.Add((*iter)->GetID()); + indices.Add((*iter)->GetEffectID()); } c->AddItemList(wxT("Analyze"), names, FNI(OnProcessAny, indices), true); @@ -1272,7 +1385,7 @@ void AudacityProject::AddEffectsToMenu(CommandManager* c, EffectSet::const_iterator iter; for (iter = effects.begin(); iter != effects.end(); ++iter) { names.Add((*iter)->GetEffectName()); - indices.Add((*iter)->GetID()); + indices.Add((*iter)->GetEffectID()); } c->AddItemList(wxT("Effects"), names, FNI(OnProcessAny, indices), true); } @@ -1377,7 +1490,7 @@ void AudacityProject::RebuildMenuBar() CreateMenusAndCommands(); - ModuleManager::Dispatch(MenusRebuilt); + ModuleManager::Get().Dispatch(MenusRebuilt); } void AudacityProject::RebuildOtherMenus() @@ -1484,7 +1597,7 @@ wxUint32 AudacityProject::GetUpdateFlags() if (mUndoManager.UnsavedChanges()) flags |= UnsavedChangesFlag; - if (mLastEffect != NULL) + if (!mLastEffect.empty()) flags |= HasLastEffectFlag; if (mUndoManager.UndoAvailable()) @@ -2638,27 +2751,7 @@ void AudacityProject::OnZeroCrossing() // Effect Menus // -void AudacityProject::OnEffect(int type, int index) -{ - EffectArray *effects; - Effect *f = NULL; - - effects = EffectManager::Get().GetEffects(type); - - f = (*effects)[index]; - delete effects; - - if (!f) - return; - //TIDY-ME: Effect Type parameters serve double duty. - // The type parameter is over used. - // It is being used: - // (a) to filter the list of effects - // (b) to specify whether to prompt for parameters. - OnEffect( type, f ); -} - -/// OnEffect() takes an Effect and executes it. +/// OnEffect() takes a PluginID and has the EffectManager execute the assocated effect. /// /// At the moment flags are used only to indicate /// whether to prompt for parameters or whether to @@ -2673,7 +2766,7 @@ void AudacityProject::OnEffect(int type, int index) /// DanH: I've added the third option as a temporary measure. I think this /// should eventually be done by having effects as Command objects. bool AudacityProject::OnEffect(int type, - Effect * f, + const PluginID & ID, wxString params, bool saveState) { @@ -2697,7 +2790,7 @@ bool AudacityProject::OnEffect(int type, if (count == 0) { // No tracks were selected... - if (f->GetEffectFlags() & INSERT_EFFECT) { + if (type & INSERT_EFFECT) { // Create a new track for the generated audio... newTrack = mTrackFactory->NewWaveTrack(); mTracks->Add(newTrack); @@ -2709,12 +2802,15 @@ bool AudacityProject::OnEffect(int type, } } - if (f->DoEffect(this, type, mRate, mTracks, mTrackFactory, - &mViewInfo.selectedRegion, params)) { + EffectManager & em = EffectManager::Get(); + + if (em.DoEffect(ID, this, type, mRate, mTracks, mTrackFactory, + &mViewInfo.selectedRegion, params)) + { if (saveState) { - wxString longDesc = f->GetEffectDescription(); - wxString shortDesc = f->GetEffectName(); + wxString longDesc = em.GetEffectDescription(ID); + wxString shortDesc = em.GetEffectName(ID); if (shortDesc.Length() > 3 && shortDesc.Right(3)==wxT("...")) shortDesc = shortDesc.Left(shortDesc.Length()-3); @@ -2723,8 +2819,8 @@ bool AudacityProject::OnEffect(int type, // Only remember a successful effect, don't rmemeber insert, // or analyze effects. - if ((f->GetEffectFlags() & (INSERT_EFFECT | ANALYZE_EFFECT))==0) { - mLastEffect = f; + if ((type & (INSERT_EFFECT | ANALYZE_EFFECT))==0) { + mLastEffect = ID; mLastEffectType = type; wxString lastEffectDesc; /* i18n-hint: %s will be the name of the effect which will be @@ -2737,7 +2833,7 @@ bool AudacityProject::OnEffect(int type, //The following automatically re-zooms after sound was generated. // IMO, it was disorienting, removing to try out without re-fitting //mchinen:12/14/08 reapplying for generate effects - if ( f->GetEffectFlags() & INSERT_EFFECT) + if ( type & INSERT_EFFECT) { if (count == 0 || (clean && mViewInfo.selectedRegion.t0() == 0.0)) OnZoomFit(); @@ -2761,36 +2857,79 @@ bool AudacityProject::OnEffect(int type, return true; } -void AudacityProject::OnGenerateEffect(int index) +void AudacityProject::OnEffect(const PluginID & pluginID) { - OnEffect(BUILTIN_EFFECT | INSERT_EFFECT, index); + PluginManager & pm = PluginManager::Get(); + const PluginDescriptor *plug = pm.GetPlugin(pluginID); + + int type; + switch (plug->GetEffectType()) + { + case EffectTypeGenerate: + type = INSERT_EFFECT; + break; + + case EffectTypeProcess: + type = PROCESS_EFFECT; + break; + + case EffectTypeAnalyze: + type = ANALYZE_EFFECT; + break; + } + + type |= plug->IsEffectDefault() ? BUILTIN_EFFECT : PLUGIN_EFFECT; + + OnEffect(type, pluginID); } -void AudacityProject::OnGeneratePlugin(int index) +// Warning...complete hackage ahead +void AudacityProject::OnEffect(const PluginID & pluginID, bool configured) { - OnEffect(PLUGIN_EFFECT | INSERT_EFFECT, index); + PluginManager & pm = PluginManager::Get(); + const PluginDescriptor *plug = pm.GetPlugin(pluginID); + + int type; + switch (plug->GetEffectType()) + { + case EffectTypeGenerate: + type = INSERT_EFFECT; + break; + + case EffectTypeProcess: + type = PROCESS_EFFECT; + break; + + case EffectTypeAnalyze: + type = ANALYZE_EFFECT; + break; + } + + type |= plug->IsEffectDefault() ? BUILTIN_EFFECT : PLUGIN_EFFECT; + type |= configured ? CONFIGURED_EFFECT : 0; + + OnStop(); + SelectAllIfNone(); + + OnEffect(type, pluginID); } void AudacityProject::OnRepeatLastEffect(int WXUNUSED(index)) { - if (mLastEffect != NULL) { + if (!mLastEffect.empty()) { // Setting the CONFIGURED_EFFECT bit prevents // prompting for parameters. OnEffect(mLastEffectType | CONFIGURED_EFFECT, mLastEffect); } } +#ifdef EFFECT_CATEGORIES void AudacityProject::OnProcessAny(int index) { Effect* e = EffectManager::Get().GetEffect(index); OnEffect(ALL_EFFECTS, e); } - -void AudacityProject::OnProcessEffect(int index) -{ - int additionalEffects=ADVANCED_EFFECT; - OnEffect(BUILTIN_EFFECT | PROCESS_EFFECT | additionalEffects, index); -} +#endif void AudacityProject::OnStereoToMono(int WXUNUSED(index)) { @@ -2798,21 +2937,6 @@ void AudacityProject::OnStereoToMono(int WXUNUSED(index)) EffectManager::Get().GetEffectByIdentifier(wxT("StereoToMono"))); } -void AudacityProject::OnProcessPlugin(int index) -{ - OnEffect(PLUGIN_EFFECT | PROCESS_EFFECT, index); -} - -void AudacityProject::OnAnalyzeEffect(int index) -{ - OnEffect(BUILTIN_EFFECT | ANALYZE_EFFECT, index); -} - -void AudacityProject::OnAnalyzePlugin(int index) -{ - OnEffect(PLUGIN_EFFECT | ANALYZE_EFFECT, index); -} - // // File Menu // diff --git a/src/Menus.h b/src/Menus.h index e263fe320..7f309e21a 100644 --- a/src/Menus.h +++ b/src/Menus.h @@ -343,16 +343,13 @@ void OnEditLabels(); // Effect Menu -bool OnEffect(int type, Effect * f, wxString params = wxEmptyString, bool saveState = true); -void OnEffect(int type, int index); -void OnGenerateEffect(int index); -void OnGeneratePlugin(int index); +bool OnEffect(int type, const PluginID & ID, wxString params = wxEmptyString, bool saveState = true); +void OnEffect(const PluginID & pluginID); +void OnEffect(const PluginID & pluginID, bool configured = false); void OnRepeatLastEffect(int index); +#ifdef EFFECT_CATEGORIES void OnProcessAny(int index); -void OnProcessEffect(int index); -void OnProcessPlugin(int index); -void OnAnalyzeEffect(int index); -void OnAnalyzePlugin(int index); +#endif void OnApplyChain(); void OnEditChains(); void OnStereoToMono(int index); diff --git a/src/ModuleManager.cpp b/src/ModuleManager.cpp new file mode 100644 index 000000000..f6cbb2405 --- /dev/null +++ b/src/ModuleManager.cpp @@ -0,0 +1,609 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + ModuleManager.cpp + + Dominic Mazzoni + James Crook + + +*******************************************************************//*! + +\file ModuleManager.cpp +\brief Based on LoadLadspa, this code loads pluggable Audacity +extension modules. It also has the code to (a) invoke a script +server and (b) invoke a function returning a replacement window, +i.e. an alternative to the usual interface, for Audacity. + +*//*******************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "Audacity.h" +#include "AudacityApp.h" +#include "FileNames.h" +#include "Internat.h" +#include "PluginManager.h" + +#include "commands/ScriptCommandRelay.h" +#include // header from libwidgetextra + +#include "audacity/PluginInterface.h" + +#ifdef EXPERIMENTAL_MODULE_PREFS +#include "Prefs.h" +#include "./prefs/ModulePrefs.h" +#endif + +#include "ModuleManager.h" +#include "widgets/MultiDialog.h" + +#define initFnName "ExtensionModuleInit" +#define versionFnName "GetVersionString" +#define scriptFnName "RegScriptServerFunc" +#define mainPanelFnName "MainPanelFunc" + +typedef wxWindow * pwxWindow; +typedef int (*tModuleInit)(int); +//typedef wxString (*tVersionFn)(); +typedef wxChar * (*tVersionFn)(); +typedef pwxWindow (*tPanelFn)(int); + +// This variable will hold the address of a subroutine in +// a DLL that can hijack the normal panel. +static tPanelFn pPanelHijack=NULL; + +// Next two commented out lines are handy when investigating +// strange DLL behaviour. Instead of dynamic linking, +// link the library which has the replacement panel statically. +// Give the address of the routine here. +// This is a great help in identifying missing +// symbols which otherwise cause a dll to unload after loading +// without an explanation as to why! +//extern wxWindow * MainPanelFunc( int i ); +//tPanelFn pPanelHijack=&MainPanelFunc; + +/// IF pPanelHijack has been found in a module DLL +/// THEN when this function is called we'll go and +/// create that window instead of the normal one. +wxWindow * MakeHijackPanel() +{ + if( pPanelHijack == NULL ) + return NULL; + return pPanelHijack(0); +} + +// This variable will hold the address of a subroutine in a DLL that +// starts a thread and reads script commands. +static tpRegScriptServerFunc scriptFn; + +Module::Module(const wxString & name) +{ + mName = name; + mLib = new wxDynamicLibrary(); + mDispatch = NULL; +} + +Module::~Module() +{ + delete mLib; +} + +bool Module::Load() +{ + if (mLib->IsLoaded()) { + if (mDispatch) { + return true; + } + return false; + } + + if (!mLib->Load(mName, wxDL_LAZY)) { + return false; + } + + // Check version string matches. (For now, they must match exactly) + tVersionFn versionFn = (tVersionFn)(mLib->GetSymbol(wxT(versionFnName))); + if (versionFn == NULL){ + wxString ShortName = wxFileName( mName ).GetName(); + wxMessageBox(wxString::Format(_("The module %s does not provide a version string.\nIt will not be loaded."), ShortName.c_str()), _("Module Unsuitable")); + wxLogMessage(wxString::Format(_("The module %s does not provide a version string. It will not be loaded."), mName.c_str())); + mLib->Unload(); + return false; + } + + wxString moduleVersion = versionFn(); + if( !moduleVersion.IsSameAs(AUDACITY_VERSION_STRING)) { + wxString ShortName = wxFileName( mName ).GetName(); + wxMessageBox(wxString::Format(_("The module %s is matched with Audacity version %s.\n\nIt will not be loaded."), ShortName.c_str(), moduleVersion.c_str()), _("Module Unsuitable")); + wxLogMessage(wxString::Format(_("The module %s is matched with Audacity version %s. It will not be loaded."), mName.c_str(), moduleVersion.c_str())); + mLib->Unload(); + return false; + } + + mDispatch = (fnModuleDispatch) mLib->GetSymbol(wxT(ModuleDispatchName)); + if (!mDispatch) { + // Module does not provide a dispatch function... + // That can be OK, as long as we never try to call it. + return true; + } + + // However if we do have it and it does not work, + // then the module is bad. + bool res = ((mDispatch(ModuleInitialize))!=0); + if (res) { + return true; + } + + mDispatch = NULL; + return false; +} + +void Module::Unload() +{ + if (mLib->IsLoaded()) { + mDispatch(ModuleTerminate); + } + + mLib->Unload(); +} + +int Module::Dispatch(ModuleDispatchTypes type) +{ + if (mLib->IsLoaded()) + if( mDispatch != NULL ) + return mDispatch(type); + + return 0; +} + +void * Module::GetSymbol(wxString name) +{ + return mLib->GetSymbol(name); +} + +// ============================================================================ +// +// ModuleManager +// +// ============================================================================ + +// The one and only ModuleManager +ModuleManager ModuleManager::mInstance; + +// Provide builtin modules a means to identify themselves +static wxArrayPtrVoid *Builtins = NULL; +void RegisterBuiltinModule(ModuleMain moduleMain) +{ + static bool allocated = false; + + if (!allocated) + { + Builtins = new wxArrayPtrVoid; + allocated = true; + } + + Builtins->Add((void *)moduleMain); + + return; +} + +// ---------------------------------------------------------------------------- +// Creation/Destruction +// ---------------------------------------------------------------------------- + +ModuleManager::ModuleManager() +{ +} + +ModuleManager::~ModuleManager() +{ + size_t cnt = mModules.GetCount(); + + for (size_t ndx = 0; ndx < cnt; ndx++) { + delete (Module *) mModules[ndx]; + } + mModules.Clear(); + + for (ModuleMap::iterator iter = mDynModules.begin(); iter != mDynModules.end(); iter++) + { + ModuleInterface *mod = iter->second; + delete mod; + } + mDynModules.clear(); +} + +// static +void ModuleManager::Initialize(CommandHandler &cmdHandler) +{ + wxArrayString audacityPathList = wxGetApp().audacityPathList; + wxArrayString pathList; + wxArrayString files; + wxString pathVar; + size_t i; + + // Code from LoadLadspa that might be useful in load modules. + pathVar = wxGetenv(wxT("AUDACITY_MODULES_PATH")); + if (pathVar != wxT("")) + wxGetApp().AddMultiPathsToPathList(pathVar, pathList); + + for (i = 0; i < audacityPathList.GetCount(); i++) { + wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH; + wxGetApp().AddUniquePathToPathList(prefix + wxT("modules"), + pathList); + } + + #if defined(__WXMSW__) + wxGetApp().FindFilesInPathList(wxT("*.dll"), pathList, files); + #else + wxGetApp().FindFilesInPathList(wxT("*.so"), pathList, files); + #endif + + for (i = 0; i < files.GetCount(); i++) { + // As a courtesy to some modules that might be bridges to + // open other modules, we set the current working + // directory to be the module's directory. + wxString saveOldCWD = ::wxGetCwd(); + wxString prefix = ::wxPathOnly(files[i]); + ::wxSetWorkingDirectory(prefix); + +#ifdef EXPERIMENTAL_MODULE_PREFS + int iModuleStatus = ModulePrefs::GetModuleStatus( files[i] ); + if( iModuleStatus == kModuleDisabled ) + continue; + if( iModuleStatus == kModuleFailed ) + continue; + // New module? You have to go and explicitly enable it. + if( iModuleStatus == kModuleNew ){ + // To ensure it is noted in config file and so + // appears on modules page. + ModulePrefs::SetModuleStatus( files[i], kModuleNew); + continue; + } + + if( iModuleStatus == kModuleAsk ) +#endif + // JKC: I don't like prompting for the plug-ins individually + // I think it would be better to show the module prefs page, + // and let the user decide for each one. + { + wxString ShortName = wxFileName( files[i] ).GetName(); + wxString msg; + msg.Printf(_("Module \"%s\" found."), ShortName.c_str()); + msg += _("\n\nOnly use modules from trusted sources"); + const wxChar *buttons[] = {_("Yes"), _("No"), NULL}; // could add a button here for 'yes and remember that', and put it into the cfg file. Needs more thought. + int action; + action = ShowMultiDialog(msg, _("Audacity Module Loader"), buttons, _("Try and load this module?"), false); +#ifdef EXPERIMENTAL_MODULE_PREFS + // If we're not prompting always, accept the answer permanantly + if( iModuleStatus == kModuleNew ){ + iModuleStatus = (action==1)?kModuleDisabled : kModuleEnabled; + ModulePrefs::SetModuleStatus( files[i], iModuleStatus ); + } +#endif + if(action == 1){ // "No" + continue; + } + } +#ifdef EXPERIMENTAL_MODULE_PREFS + // Before attempting to load, we set the state to bad. + // That way, if we crash, we won't try again. + ModulePrefs::SetModuleStatus( files[i], kModuleFailed ); +#endif + + Module *module = new Module(files[i]); + if (module->Load()) // it will get rejected if there are version problems + { + Get().mModules.Add(module); + // We've loaded and initialised OK. + // So look for special case functions: + wxLogNull logNo; // Don't show wxWidgets errors if we can't do these. (Was: Fix bug 544.) + // (a) for scripting. + if( scriptFn == NULL ) + scriptFn = (tpRegScriptServerFunc)(module->GetSymbol(wxT(scriptFnName))); + // (b) for hijacking the entire Audacity panel. + if( pPanelHijack==NULL ) + { + pPanelHijack = (tPanelFn)(module->GetSymbol(wxT(mainPanelFnName))); + } +#ifdef EXPERIMENTAL_MODULE_PREFS + // Loaded successfully, restore the status. + ModulePrefs::SetModuleStatus( files[i], iModuleStatus); +#endif + } + else { + // No need to save status, as we already set kModuleFailed. + delete module; + } + ::wxSetWorkingDirectory(saveOldCWD); + } + // After loading all the modules, we may have a registered scripting function. + if(scriptFn) + { + ScriptCommandRelay::SetCommandHandler(cmdHandler); + ScriptCommandRelay::SetRegScriptServerFunc(scriptFn); + NonGuiThread::StartChild(&ScriptCommandRelay::Run); + } +} + +// static +int ModuleManager::Dispatch(ModuleDispatchTypes type) +{ + size_t cnt = Get().mModules.GetCount(); + + for (size_t ndx = 0; ndx < cnt; ndx++) { + Module *module = (Module *)Get().mModules[ndx]; + + module->Dispatch(type); + } + return 0; +} + +// ============================================================================ +// +// Return reference to singleton +// +// (Thread-safe...no active threading during construction or after destruction) +// ============================================================================ +ModuleManager & ModuleManager::Get() +{ + return mInstance; +} + +void ModuleManager::InitializeBuiltins() +{ + PluginManager & pm = PluginManager::Get(); + + if (!Builtins) + { + return; + } + + for (size_t i = 0, cnt = Builtins->GetCount(); i < cnt; i++) + { + ModuleMain audacityMain = (ModuleMain) (*Builtins)[i]; + ModuleInterface *module = audacityMain(this, NULL); + + mDynModules[module->GetID()] = module; + + module->Initialize(); + + // First, we need to remember it + pm.RegisterModulePlugin(module); + + // Now, allow the module to auto-register children + module->AutoRegisterPlugins(pm); + } +} + +// static +void ModuleManager::EarlyInit() +{ + InitializeBuiltins(); +} + +bool ModuleManager::DiscoverProviders(wxArrayString & providers) +{ + wxArrayString provList; + wxArrayString pathList; + + // Code from LoadLadspa that might be useful in load modules. + wxString pathVar = wxString::FromUTF8(getenv("AUDACITY_MODULES_PATH")); + + if (pathVar != wxT("")) + { + wxGetApp().AddMultiPathsToPathList(pathVar, pathList); + } + else + { + wxGetApp().AddUniquePathToPathList(FileNames::ModulesDir(), pathList); + } + +#if defined(__WXMSW__) + wxGetApp().FindFilesInPathList(wxT("*.dll"), pathList, provList); +#elif defined(__WXMAC__) + wxGetApp().FindFilesInPathList(wxT("*.dylib"), pathList, provList); +#else + wxGetApp().FindFilesInPathList(wxT("*.so"), pathList, provList); +#endif + + for (int i = 0, cnt = provList.GetCount(); i < cnt; i++) + { + wxPrintf(wxT("provider %s\n"), provList[i].c_str()); + providers.push_back(provList[i]); + } + + return true; +} + +bool ModuleManager::DiscoverProvider(const wxString & path) +{ + ModuleInterface *module = LoadModule(path); + if (module) + { + PluginManager & pm = PluginManager::Get(); + + // First, we need to remember it + pm.RegisterModulePlugin(module); + + // Now, allow the module to auto-register children + module->AutoRegisterPlugins(pm); + +// UnloadModule(module); + } + + return true; +} + +ModuleInterface *ModuleManager::LoadModule(const wxString & path) +{ + wxDynamicLibrary *lib = new wxDynamicLibrary(); + + if (lib->Load(path, wxDL_NOW)) + { + bool success = false; + ModuleMain audacityMain = (ModuleMain) lib->GetSymbol(wxSTRINGIZE_T(MODULE_ENTRY), + &success); + if (success && audacityMain) + { + ModuleInterface *module = audacityMain(this, &path); + if (module) + { + if (module->Initialize()) + { + + mDynModules[module->GetID()] = module; + mLibs[module] = lib; + + return module; + } + module->Terminate(); + delete module; + } + } + + lib->Unload(); + } + + delete lib; + + return NULL; +} + +void ModuleManager::UnloadModule(ModuleInterface *module) +{ + if (module) + { + const PluginID & modID = module->GetID(); + + module->Terminate(); + + delete module; + + mDynModules.erase(modID); + + if (mLibs.find(module) != mLibs.end()) + { + mLibs[module]->Unload(); + mLibs.erase(module); + } + } +} + +void ModuleManager::InitializePlugins() +{ + InitializeBuiltins(); + + // Look for dynamic modules here + + for (ModuleMap::iterator iter = mDynModules.begin(); iter != mDynModules.end(); iter++) + { + ModuleInterface *mod = iter->second; + mod->Initialize(); + } +} + +void ModuleManager::RegisterModule(ModuleInterface *module) +{ + wxString id = module->GetID(); + + if (mDynModules.find(id) != mDynModules.end()) + { + // TODO: Should we complain about a duplicate registeration???? + return; + } + + mDynModules[id] = module; + + PluginManager::Get().RegisterModulePlugin(module); +} + +void ModuleManager::FindAllPlugins(PluginIDList & providers, wxArrayString & paths) +{ + PluginManager & pm = PluginManager::Get(); + + wxArrayString modIDs; + wxArrayString modPaths; + const PluginDescriptor *plug = pm.GetFirstPlugin(PluginTypeModule); + while (plug) + { + modIDs.push_back(plug->GetID()); + modPaths.push_back(plug->GetPath()); + plug = pm.GetNextPlugin(PluginTypeModule); + } + + for (size_t i = 0, cnt = modIDs.size(); i < cnt; i++) + { + PluginID providerID = modIDs[i]; + + ModuleInterface *module = + static_cast(CreateProviderInstance(providerID, modPaths[i])); + + wxArrayString newpaths = module->FindPlugins(pm); + for (size_t i = 0, cnt = newpaths.size(); i < cnt; i++) + { + providers.push_back(providerID); + paths.push_back(newpaths[i]); + } + } +} + +wxArrayString ModuleManager::FindPluginsForProvider(const PluginID & providerID, + const wxString & path) +{ + // Instantiate if it hasn't already been done + if (mDynModules.find(providerID) == mDynModules.end()) + { + // If it couldn't be created, just give up and return an empty list + if (!CreateProviderInstance(providerID, path)) + { + return wxArrayString(); + } + } + + return mDynModules[providerID]->FindPlugins(PluginManager::Get()); +} + +bool ModuleManager::RegisterPlugin(const PluginID & providerID, const wxString & path) +{ + if (mDynModules.find(providerID) == mDynModules.end()) + { + return false; + } + + return mDynModules[providerID]->RegisterPlugin(PluginManager::Get(), path); +} + +bool ModuleManager::IsProviderBuiltin(const PluginID & providerID) +{ + return mModuleMains.find(providerID) != mModuleMains.end(); +} + +void *ModuleManager::CreateProviderInstance(const PluginID & providerID, + const wxString & path) +{ + if (path.empty() && mDynModules.find(providerID) != mDynModules.end()) + { + return mDynModules[providerID]; + } + + return LoadModule(path); +} + +void *ModuleManager::CreateInstance(const PluginID & providerID, + const PluginID & ID, + const wxString & path) +{ + if (mDynModules.find(providerID) == mDynModules.end()) + { + return NULL; + } + + return mDynModules[providerID]->CreateInstance(ID, path); +} diff --git a/src/ModuleManager.h b/src/ModuleManager.h new file mode 100644 index 000000000..f98e6cfe8 --- /dev/null +++ b/src/ModuleManager.h @@ -0,0 +1,118 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + ModuleManager.h + + Dominic Mazzoni + James Crook + +**********************************************************************/ + +#ifndef __AUDACITY_MODULEMANAGER_H__ +#define __AUDACITY_MODULEMANAGER_H__ + +#include + +#include +#include + +#include "audacity/ModuleInterface.h" + +class CommandHandler; + +wxWindow * MakeHijackPanel(); + +// +// Module Manager +// +// wxPluginManager would be MUCH better, but it's an "undocumented" framework. +// +#define ModuleDispatchName "ModuleDispatch" + +typedef enum +{ + ModuleInitialize, + ModuleTerminate, + AppInitialized, + AppQuiting, + ProjectInitialized, + ProjectClosing, + MenusRebuilt +} ModuleDispatchTypes; + +typedef int (*fnModuleDispatch)(ModuleDispatchTypes type); + +class Module +{ +public: + Module(const wxString & name); + virtual ~Module(); + + bool Load(); + void Unload(); + int Dispatch(ModuleDispatchTypes type); + void * GetSymbol(wxString name); + +private: + wxString mName; + wxDynamicLibrary *mLib; + fnModuleDispatch mDispatch; +}; + +typedef std::map ModuleMainMap; +typedef std::map ModuleMap; +typedef std::map LibraryMap; + +class ModuleManager : public ModuleManagerInterface +{ +public: + ModuleManager(); + virtual ~ModuleManager(); + + // ------------------------------------------------------------------------- + // ModuleManagerInterface implementation + // ------------------------------------------------------------------------- + + virtual void RegisterModule(ModuleInterface *module); + + // ------------------------------------------------------------------------- + // ModuleManager implementation + // ------------------------------------------------------------------------- + + static ModuleManager & Get(); + + void Initialize(CommandHandler & cmdHandler); + int Dispatch(ModuleDispatchTypes type); + + void EarlyInit(); + + // PluginManager use + bool DiscoverProviders(wxArrayString & providers); + bool DiscoverProvider(const wxString & path); + + void FindAllPlugins(PluginIDList & providers, wxArrayString & paths); + wxArrayString FindPluginsForProvider(const PluginID & provider, const wxString & path); + bool RegisterPlugin(const PluginID & provider, const wxString & path); + + void InitializePlugins(); + bool IsProviderBuiltin(const PluginID & provider); + void *CreateProviderInstance(const PluginID & ID, const wxString & path); + void *CreateInstance(const PluginID & provider, const PluginID & ID, const wxString & path); + +private: + void InitializeBuiltins(); + ModuleInterface *LoadModule(const wxString & path); + void UnloadModule(ModuleInterface *module); + +private: + static ModuleManager mInstance; + + ModuleMainMap mModuleMains; + ModuleMap mDynModules; + LibraryMap mLibs; + + wxArrayPtrVoid mModules; +}; + +#endif /* __AUDACITY_MODULEMANAGER_H__ */ diff --git a/src/PluginManager.cpp b/src/PluginManager.cpp index 9b4519d24..da0dcdd9c 100644 --- a/src/PluginManager.cpp +++ b/src/PluginManager.cpp @@ -13,18 +13,34 @@ *//*******************************************************************/ +#include + #include "Audacity.h" #include +#include +#include #include #include #include +#include +#include #include +#include #include #include +#include #include +#include "audacity/EffectInterface.h" + +#include "AudacityApp.h" +#include "effects/EffectManager.h" #include "FileNames.h" +#include "ModuleManager.h" +#include "PlatformCompatibility.h" +#include "Prefs.h" +#include "ShuttleGui.h" #include "xml/XMLFileReader.h" #include "xml/XMLWriter.h" @@ -32,259 +48,1697 @@ #include +// ============================================================================ +// +// +// +// ============================================================================ +#if wxUSE_ACCESSIBILITY + +class CheckListAx: public wxWindowAccessible +{ +public: + CheckListAx(wxListCtrl * window); + + virtual ~ CheckListAx(); + + // Retrieves the address of an IDispatch interface for the specified child. + // All objects must support this property. + virtual wxAccStatus GetChild( int childId, wxAccessible **child ); + + // Gets the number of children. + virtual wxAccStatus GetChildCount( int *childCount ); + + // Gets the default action for this object (0) or > 0 (the action for a child). + // Return wxACC_OK even if there is no action. actionName is the action, or the empty + // string if there is no action. + // The retrieved string describes the action that is performed on an object, + // not what the object does as a result. For example, a toolbar button that prints + // a document has a default action of "Press" rather than "Prints the current document." + virtual wxAccStatus GetDefaultAction( int childId, wxString *actionName ); + + // Returns the description for this object or a child. + virtual wxAccStatus GetDescription( int childId, wxString *description ); + + // Gets the window with the keyboard focus. + // If childId is 0 and child is NULL, no object in + // this subhierarchy has the focus. + // If this object has the focus, child should be 'this'. + virtual wxAccStatus GetFocus( int *childId, wxAccessible **child ); + + // Returns help text for this object or a child, similar to tooltip text. + virtual wxAccStatus GetHelpText( int childId, wxString *helpText ); + + // Returns the keyboard shortcut for this object or child. + // Return e.g. ALT+K + virtual wxAccStatus GetKeyboardShortcut( int childId, wxString *shortcut ); + + // Returns the rectangle for this object (id = 0) or a child element (id > 0). + // rect is in screen coordinates. + virtual wxAccStatus GetLocation( wxRect& rect, int elementId ); + + // Gets the name of the specified object. + virtual wxAccStatus GetName( int childId, wxString *name ); + + // Returns a role constant. + virtual wxAccStatus GetRole( int childId, wxAccRole *role ); + + // Gets a variant representing the selected children + // of this object. + // Acceptable values: + // - a null variant (IsNull() returns TRUE) + // - a list variant (GetType() == wxT("list")) + // - an integer representing the selected child element, + // or 0 if this object is selected (GetType() == wxT("long")) + // - a "void*" pointer to a wxAccessible child object + virtual wxAccStatus GetSelections( wxVariant *selections ); + + // Returns a state constant. + virtual wxAccStatus GetState( int childId, long* state ); + + // Returns a localized string representing the value for the object + // or child. + virtual wxAccStatus GetValue( int childId, wxString *strValue ); + + void SetSelected( int item ); + +private: + wxListCtrl *mParent; + int mLastId; +}; + +CheckListAx::CheckListAx( wxListCtrl * window ): + wxWindowAccessible( window ) +{ + mParent = window; + mLastId = -1; +} + +CheckListAx::~CheckListAx() +{ + } + +void CheckListAx::SetSelected( int item ) +{ + if (mLastId != -1) { + NotifyEvent( wxACC_EVENT_OBJECT_SELECTIONREMOVE, + mParent, + wxOBJID_CLIENT, + mLastId ); + mLastId = -1; +} + + if (item != -1) +{ + NotifyEvent( wxACC_EVENT_OBJECT_FOCUS, + mParent, + wxOBJID_CLIENT, + item + 1 ); + + NotifyEvent( wxACC_EVENT_OBJECT_SELECTION, + mParent, + wxOBJID_CLIENT, + item + 1 ); + + mLastId = item + 1; + } +} + +// Retrieves the address of an IDispatch interface for the specified child. +// All objects must support this property. +wxAccStatus CheckListAx::GetChild( int childId, wxAccessible** child ) +{ + if( childId == wxACC_SELF ) + { + *child = this; + } + else + { + *child = NULL; + } + + return wxACC_OK; +} + +// Gets the number of children. +wxAccStatus CheckListAx::GetChildCount( int *childCount ) +{ + *childCount = mParent->GetItemCount(); + + return wxACC_OK; +} + +// Gets the default action for this object (0) or > 0 (the action for a child). +// Return wxACC_OK even if there is no action. actionName is the action, or the empty +// string if there is no action. +// The retrieved string describes the action that is performed on an object, +// not what the object does as a result. For example, a toolbar button that prints +// a document has a default action of "Press" rather than "Prints the current document." +wxAccStatus CheckListAx::GetDefaultAction( int WXUNUSED(childId), wxString *actionName ) +{ + actionName->Clear(); + + return wxACC_OK; +} + +// Returns the description for this object or a child. +wxAccStatus CheckListAx::GetDescription( int WXUNUSED(childId), wxString *description ) +{ + description->Clear(); + + return wxACC_OK; +} + +// Gets the window with the keyboard focus. +// If childId is 0 and child is NULL, no object in +// this subhierarchy has the focus. +// If this object has the focus, child should be 'this'. +wxAccStatus CheckListAx::GetFocus( int *childId, wxAccessible **child ) +{ + *childId = 0; + *child = this; + + return wxACC_OK; +} + +// Returns help text for this object or a child, similar to tooltip text. +wxAccStatus CheckListAx::GetHelpText( int WXUNUSED(childId), wxString *helpText ) +{ + helpText->Clear(); + + return wxACC_OK; +} + +// Returns the keyboard shortcut for this object or child. +// Return e.g. ALT+K +wxAccStatus CheckListAx::GetKeyboardShortcut( int WXUNUSED(childId), wxString *shortcut ) +{ + shortcut->Clear(); + + return wxACC_OK; +} + +// Returns the rectangle for this object (id = 0) or a child element (id > 0). +// rect is in screen coordinates. +wxAccStatus CheckListAx::GetLocation( wxRect& rect, int elementId ) + { + if( elementId == wxACC_SELF ) + { + rect = mParent->GetRect(); + rect.SetPosition( mParent->GetParent()->ClientToScreen( rect.GetPosition() ) ); + } + else + { + if( elementId <= mParent->GetItemCount() ) + { + mParent->GetItemRect( elementId - 1, rect, wxLIST_RECT_LABEL ); + rect.SetPosition( mParent->ClientToScreen( rect.GetPosition() ) ); + } + } + + return wxACC_OK; +} + +// Gets the name of the specified object. +wxAccStatus CheckListAx::GetName( int WXUNUSED(childId), wxString *name ) +{ + *name = mParent->GetName(); + + return wxACC_OK; +} + +// Returns a role constant. +wxAccStatus CheckListAx::GetRole( int childId, wxAccRole *role ) +{ + if( childId == wxACC_SELF ) + { + *role = wxROLE_SYSTEM_LIST; + } + else + { + *role = wxROLE_SYSTEM_LISTITEM; + } + + return wxACC_OK; +} + +// Gets a variant representing the selected children +// of this object. +// Acceptable values: +// - a null variant (IsNull() returns TRUE) +// - a list variant (GetType() == wxT("list")) +// - an integer representing the selected child element, +// or 0 if this object is selected (GetType() == wxT("long")) +// - a "void*" pointer to a wxAccessible child object +wxAccStatus CheckListAx::GetSelections( wxVariant * WXUNUSED(selections) ) +{ + return wxACC_NOT_IMPLEMENTED; +} + +// Returns a state constant. +wxAccStatus CheckListAx::GetState( int childId, long *state ) +{ + int flag = wxACC_STATE_SYSTEM_FOCUSABLE; + + if( childId == wxACC_SELF ) + { + flag |= wxACC_STATE_SYSTEM_FOCUSED; + } + else + { + wxListItem item; + + item.SetId( childId - 1 ); + item.SetState( wxLIST_STATE_FOCUSED | wxLIST_STATE_SELECTED ); + item.SetMask( wxLIST_MASK_IMAGE | wxLIST_MASK_STATE ); + + if( mParent->GetItem( item ) ) + { + flag |= wxACC_STATE_SYSTEM_SELECTABLE; + + long state = item.GetState(); + + if( state & wxLIST_STATE_FOCUSED ) + { + flag |= wxACC_STATE_SYSTEM_FOCUSED; + } + + if( state & wxLIST_STATE_SELECTED ) + { + flag |= wxACC_STATE_SYSTEM_SELECTED; + } + + if( item.GetImage() != 0 ) + { + flag |= wxACC_STATE_SYSTEM_CHECKED; + } + } + } + + *state = flag; + + return wxACC_OK; +} + +// Returns a localized string representing the value for the object +// or child. +wxAccStatus CheckListAx::GetValue( int childId, wxString *strValue ) +{ + if( childId == 0 ) + { + return wxACC_OK; + } + else + { + *strValue = mParent->GetItemText( childId - 1 ); + } + + return wxACC_OK; +} + +#endif + +// ============================================================================ +// +// +// +// ============================================================================ + +#include "../images/Unchecked.xpm" +#include "../images/Checked.xpm" +#include "../images/Arrow15x15.xpm" + +#define EffectListID 7001 +#define EffectClearAllID 7002 +#define EffectSelectAllID 7003 + +class PluginRegistrationDialog : public wxDialog +{ +public: + // constructors and destructors + PluginRegistrationDialog(); + virtual ~PluginRegistrationDialog(); + +private: + void Populate(); + void PopulateOrExchange(ShuttleGui & S); + + void OnOK(wxCommandEvent & evt); + void OnCancel(wxCommandEvent & evt); + void OnListChar(wxKeyEvent & evt); + void OnListMouseDown(wxMouseEvent & evt); + void OnSelectAll(wxCommandEvent & evt); + void OnClearAll(wxCommandEvent & evt); + + void SetBoldOrRegular(int i); + void SetState(int i, int state); + void ToggleItem(int i); + +private: + ModuleInterface *mMod; + +#if wxUSE_ACCESSIBILITY + CheckListAx *mAx; +#endif + + wxListCtrl *mEffects; + PluginIDList mProvs; + wxArrayString mPaths; + std::vector miState; + + bool mCancelClicked; + + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE(PluginRegistrationDialog, wxDialog) + EVT_BUTTON(wxID_OK, PluginRegistrationDialog::OnOK) + EVT_BUTTON(wxID_CANCEL, PluginRegistrationDialog::OnCancel) + EVT_BUTTON(EffectClearAllID, PluginRegistrationDialog::OnClearAll) + EVT_BUTTON(EffectSelectAllID, PluginRegistrationDialog::OnSelectAll) +END_EVENT_TABLE() + +PluginRegistrationDialog::PluginRegistrationDialog() +: wxDialog(wxGetApp().GetTopWindow(), + wxID_ANY, + _("Register Effects"), + wxDefaultPosition, wxDefaultSize, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +{ + mEffects = NULL; + SetLabel(_("Register Effects")); // Provide visual label + SetName(_("Register Effects")); // Provide audible label + Populate(); + SetReturnCode(wxID_OK); +} + +PluginRegistrationDialog::~PluginRegistrationDialog() +{ + mEffects->Disconnect(wxEVT_LEFT_DOWN, + wxMouseEventHandler(PluginRegistrationDialog::OnListMouseDown), + NULL, + this); + mEffects->Disconnect(wxEVT_KEY_DOWN, + wxKeyEventHandler(PluginRegistrationDialog::OnListChar), + NULL, + this); +} + +void PluginRegistrationDialog::Populate() +{ + //------------------------- Main section -------------------- + ShuttleGui S(this, eIsCreating); + PopulateOrExchange(S); + // ----------------------- End of main section -------------- +} + +WX_DECLARE_STRING_HASH_MAP(wxString, ProviderMap); + +/// Defines the dialog and does data exchange with it. +void PluginRegistrationDialog::PopulateOrExchange(ShuttleGui &S) +{ + wxImageList * pImageList = new wxImageList( 15, 15 ); + +#define SHOW_UNCHECKED (0) +#define SHOW_CHECKED (1) +#define SHOW_ARROW (2) + +#define COL_NAME (0) +#define COL_PATH (1) + + pImageList->Add(wxBitmap(unchecked_xpm)); + pImageList->Add(wxBitmap(checked_xpm)); + pImageList->Add(wxBitmap(arrow15x15_xpm)); + + S.StartVerticalLay(true); + { + /*i18n-hint: The dialog shows a list of plugins with check-boxes + beside each one.*/ + S.StartStatic(_("&Select Plug-ins to Install or press ENTER to Install All"), true); + { + S.SetStyle(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_HRULES | wxLC_VRULES ); + mEffects = S.Id(EffectListID).AddListControlReportMode(); + mEffects->Connect(wxEVT_LEFT_DOWN, + wxMouseEventHandler(PluginRegistrationDialog::OnListMouseDown), + NULL, + this); + mEffects->Connect(wxEVT_KEY_DOWN, + wxKeyEventHandler(PluginRegistrationDialog::OnListChar), + NULL, + this); +#if wxUSE_ACCESSIBILITY + mAx = new CheckListAx(mEffects); + mEffects->SetAccessible(mAx); +#endif + mEffects->AssignImageList( pImageList, wxIMAGE_LIST_SMALL ); + mEffects->InsertColumn(COL_NAME, _("Plug-in Name")); + mEffects->InsertColumn(COL_PATH, _("Path")); + } + S.EndStatic(); + + S.StartHorizontalLay(wxALIGN_LEFT | wxEXPAND, false); + { + S.SetBorder(10); + S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + { + S.AddSpace(12); + S.SetBorder(6); + S.Id(EffectSelectAllID).AddButton(_("Select &All")); + S.Id(EffectClearAllID).AddButton(_("Clea&r All")); + } + S.EndHorizontalLay(); + + S.StartHorizontalLay(wxALIGN_CENTER | wxEXPAND); + { + S.AddSpace(1); + } + S.EndHorizontalLay(); + + S.AddStandardButtons(eOkButton | eCancelButton); + } + S.EndHorizontalLay(); + } + S.EndVerticalLay(); + + PluginManager & pm = PluginManager::Get(); + ModuleManager & mm = ModuleManager::Get(); + + // Capture all of the module IDs and paths so the iterate stays valid + ProviderMap provs; + wxArrayString keys; + wxArrayString paths; + wxString padding = L"0000000000"; + const PluginDescriptor *plug = pm.GetFirstPlugin(PluginTypeModule); + while (plug) + { + wxString key = wxString::Format(wxT("%d"), (int) provs.size()); + key.insert(0, padding.substr(0, padding.length() - key.length())); + provs[key] = plug->GetID(); + keys.push_back(key); + paths.push_back(plug->GetPath()); + + plug = pm.GetNextPlugin(PluginTypeModule); + } + + wxArrayString sortable; + for (size_t i = 0, icnt = paths.size(); i < icnt; i++) + { + wxString key = keys[i]; + PluginID provID = provs[key]; + wxString provPath = paths[i]; + + wxArrayString newPaths = mm.FindPluginsForProvider(provID, provPath); + + for (size_t j = 0, jcnt = newPaths.size(); j < jcnt; j++) + { + sortable.push_back(key + L" " + newPaths[j]); + } + } + + // With the index + sortable.Sort(); + + // The dc is used to compute the text width in pixels. + // FIXME: That works fine for PC, but apparently comes out too small for wxMAC. + // iLen is minimum width in pixels shown for the file names. 200 is reasonable. + int iNameLen = 0; + int iPathLen = 0; + int x, y; + wxRect iconrect; + for (int i = 0, cnt = sortable.size(); i < cnt; i++) + { + miState.push_back( SHOW_CHECKED ); + + wxString item = sortable[i]; + int split = item.find(L" "); + mProvs.push_back(provs[item.substr(0, split)]); + mPaths.push_back(item.substr(split + 1, wxString::npos)); + + wxFileName fn(mPaths.back()); + wxString name(fn.GetName()); + wxString path(fn.GetFullPath()); + + mEffects->InsertItem(i, name, SHOW_CHECKED); + mEffects->SetItem(i, COL_PATH, path); + + // Only need to get the icon width once + if (i == 0) + { +#if defined(__WXMAC__) + // wxMac doesn't return the ICON rectangle. It returns the + // rectangle for the first column and that even comes back + // with negative numbers sometimes. + // + // So, just guess. + wxIcon i1(unchecked_xpm); + wxIcon i2(checked_xpm); + wxIcon i3(arrow15x15_xpm); + iconrect.x = 4; + iconrect.width = wxMax(wxMax(i1.GetWidth(), i2.GetWidth()), i3.GetWidth()); +#else + mEffects->GetItemRect( i, iconrect, wxLIST_RECT_ICON ); +#endif + } + mEffects->GetTextExtent(name, &x, &y); + iNameLen = wxMax(iNameLen, x + iconrect.width + (iconrect.x * 2)); + mEffects->GetTextExtent(path, &x, &y ); + iPathLen = wxMax(iPathLen, x + iconrect.width + (iconrect.x * 2)); + } + + mEffects->SetColumnWidth(COL_NAME, iNameLen + /* fudge */ 5); + mEffects->SetColumnWidth(COL_PATH, iPathLen + /* fudge */ 5); + + mEffects->SetSizeHints(iNameLen + iPathLen + /* fudge */ 15, 200); + if (mPaths.size() > 0) + { + // Make sure first item is selected/focused. + mEffects->SetFocus(); + mEffects->SetItemState(0, wxLIST_STATE_FOCUSED|wxLIST_STATE_SELECTED, wxLIST_STATE_FOCUSED|wxLIST_STATE_SELECTED); +#if wxUSE_ACCESSIBILITY + mAx->SetSelected(0); +#endif + } + Layout(); + Fit(); + SetSizeHints(GetSize()); + // Parent window is usually not there yet, so centre on screen rather than on parent. + CenterOnScreen(); + +} + +void PluginRegistrationDialog::OnListMouseDown(wxMouseEvent & evt) +{ + wxPoint p = evt.GetPosition(); + int flags = wxLIST_HITTEST_ONITEM; + int item = mEffects->HitTest(p, flags); + + if (item != wxNOT_FOUND) + { + ToggleItem(item); + } + + evt.Skip(); +} + +void PluginRegistrationDialog::OnListChar(wxKeyEvent & evt) +{ + switch (evt.GetKeyCode()) + { + case WXK_SPACE: + { + int iItem = mEffects->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED); + + if (iItem != wxNOT_FOUND) + { + ToggleItem(iItem); + } + } + break; + + case WXK_RETURN: + // Don't know why wxListCtrls prevent default dialog action, + // but they do, so handle it. + EmulateButtonClickIfPresent(GetAffirmativeId()); + break; + + default: + evt.Skip(); + break; + } +} + +void PluginRegistrationDialog::SetBoldOrRegular(int i) +{ + wxFont Font = mEffects->GetItemFont(i); + Font.SetWeight( (miState[i] == SHOW_CHECKED) ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL); + mEffects->SetItemFont(i, Font); +} + +// We can't capture mouse clicks, only selected and deselected. +// Clicking on a selected item does not generate any event. +// Therefore our workaround solution is to NEVER actually select. +// So whenever the code tries to , we cancel the selection. +// That way we continue to get events. +void PluginRegistrationDialog::SetState(int i, int state) +{ + miState[i] = state; + mEffects->SetItemImage(i, miState[i]); +#if wxUSE_ACCESSIBILITY + mAx->SetSelected(i); +#endif +} + +void PluginRegistrationDialog::ToggleItem(int i) +{ + SetState(i, miState[i] == SHOW_CHECKED ? SHOW_UNCHECKED : SHOW_CHECKED); +} + +void PluginRegistrationDialog::OnSelectAll(wxCommandEvent & WXUNUSED(evt)) +{ + for (size_t i = 0, cnt = miState.size(); i < cnt; i++) + { + SetState(i, SHOW_CHECKED); + } +} + +void PluginRegistrationDialog::OnClearAll(wxCommandEvent & WXUNUSED(evt)) +{ + for (size_t i = 0, cnt = miState.size(); i < cnt; i++) + { + SetState(i, SHOW_UNCHECKED); + } +} + +void PluginRegistrationDialog::OnOK(wxCommandEvent & WXUNUSED(evt)) +{ + mCancelClicked = false; + FindWindowById(wxID_OK)->Disable(); + FindWindowById(EffectListID)->Disable(); + FindWindowById(EffectClearAllID)->Disable(); + FindWindowById(EffectSelectAllID)->Disable(); + + for (size_t i = 0, cnt = mPaths.size(); i < cnt && !mCancelClicked; i++) + { + mEffects->EnsureVisible(i); + if (miState[i] == SHOW_CHECKED) + { + mEffects->SetItemImage(i, SHOW_ARROW); + ModuleManager::Get().RegisterPlugin(mProvs[i], wxString(mPaths[i])); + mEffects->SetItemImage(i, SHOW_CHECKED); + } + wxYield(); + } + + EndModal(mCancelClicked ? wxID_CANCEL : wxID_OK); +} + +void PluginRegistrationDialog::OnCancel(wxCommandEvent & WXUNUSED(evt)) +{ + mCancelClicked = true; + + EndModal(mCancelClicked ? wxID_CANCEL : wxID_OK); +} + + + +/////////////////////////////////////////////////////////////////////////////// +// +// Plugindescriptor +// +/////////////////////////////////////////////////////////////////////////////// + +PluginDescriptor::PluginDescriptor() +{ + mPluginType = PluginTypeNone; + mEnabled = false; + mInstance = NULL; + + mEffectType = EffectTypeNone; + mEffectInteractive = false; + mEffectDefault = false; + mEffectLegacy = false; +} + +PluginDescriptor::~PluginDescriptor() +{ + if (mInstance) + { + switch (mPluginType) + { + case PluginTypeEffect: + EffectHostInterface *e = reinterpret_cast(mInstance); + delete e; + break; + } + } +} + +void *PluginDescriptor::GetInstance() +{ + if (!mInstance) + { + if (GetPluginType() == PluginTypeModule) + { + mInstance = ModuleManager::Get().CreateProviderInstance(GetID(), GetPath()); + } + else + { + mInstance = ModuleManager::Get().CreateInstance(GetProviderID(), GetID(), GetPath()); + } + } + + return mInstance; +} + +void PluginDescriptor::SetInstance(void *instance) +{ + mInstance = instance; + + return; +} + +PluginType PluginDescriptor::GetPluginType() const +{ + return mPluginType; +} + +const wxString & PluginDescriptor::GetPath() const +{ + return mPath; +} + +const wxString & PluginDescriptor::GetName() const +{ + return mName; +} + +const wxString & PluginDescriptor::GetVersion() const +{ + return mVersion; +} + +const wxString & PluginDescriptor::GetVendor() const +{ + return mVendor; +} + +const wxString & PluginDescriptor::GetDescription() const +{ + return mDescription; +} + +const PluginID & PluginDescriptor::GetID() const +{ + return mID; +} + +const PluginID & PluginDescriptor::GetProviderID() const +{ + return mProviderID; +} + +const wxString & PluginDescriptor::GetDateTime() const +{ + return mDateTime; +} + +bool PluginDescriptor::IsEnabled() const +{ + return mEnabled; +} + +wxString PluginDescriptor::GetMenuName() const +{ + // This probably shouldn't be here...but it was easy + wxString name; + mName.EndsWith(wxT("..."), &name); + + return (mVendor.IsEmpty() ? wxT("") : mVendor + wxT(": ")) + + (name.IsEmpty() ? mName : name) + + (mEffectInteractive ? wxT("...") : wxT("")); +} + +void PluginDescriptor::SetPluginType(PluginType type) +{ + mPluginType = type; +} + +void PluginDescriptor::SetPath(const wxString & path) +{ + mPath = path; +} + +void PluginDescriptor::SetName(const wxString & name) +{ + mName = name; +} + +void PluginDescriptor::SetVersion(const wxString & version) +{ + mVersion = version; +} + +void PluginDescriptor::SetVendor(const wxString & vendor) +{ + mVendor = vendor; +} + +void PluginDescriptor::SetDescription(const wxString & description) +{ + mDescription = description; +} + +void PluginDescriptor::SetID(const PluginID & ID) +{ + mID = ID; +} + +void PluginDescriptor::SetProviderID(const PluginID & providerID) +{ + mProviderID = providerID; +} + +void PluginDescriptor::SetDateTime(const wxString & dateTime) +{ + mDateTime = dateTime; +} + +void PluginDescriptor::SetEnabled(bool enable) +{ + mEnabled = enable; +} + +// Effects + +const wxString & PluginDescriptor::GetEffectFamily() const +{ + return mEffectFamily; +} + +EffectType PluginDescriptor::GetEffectType() const +{ + return mEffectType; +} + +bool PluginDescriptor::IsEffectInteractive() const +{ + return mEffectInteractive; +} + +bool PluginDescriptor::IsEffectDefault() const +{ + return mEffectDefault; +} + +bool PluginDescriptor::IsEffectLegacy() const +{ + return mEffectLegacy; +} + +bool PluginDescriptor::IsEffectRealtimeCapable() const +{ + return mEffectRealtimeCapable; +} + +void PluginDescriptor::SetEffectFamily(const wxString & family) +{ + mEffectFamily = family; +} + +void PluginDescriptor::SetEffectType(EffectType type) +{ + mEffectType = type; +} + +void PluginDescriptor::SetEffectInteractive(bool interactive) +{ + mEffectInteractive = interactive; +} + +void PluginDescriptor::SetEffectDefault(bool dflt) +{ + mEffectDefault = dflt; +} + +void PluginDescriptor::SetEffectLegacy(bool legacy) +{ + mEffectLegacy = legacy; +} + +void PluginDescriptor::SetEffectRealtimeCapable(bool realtime) +{ + mEffectRealtimeCapable = realtime; +} + +// Importer + +const wxString & PluginDescriptor::GetImporterIdentifier() const +{ + return mImporterIdentifier; +} + +void PluginDescriptor::SetImporterIdentifier(const wxString & identifier) +{ + mImporterIdentifier = identifier; +} + +const wxString & PluginDescriptor::GetImporterFilterDescription() const +{ + return mImporterFilterDesc; +} + +void PluginDescriptor::SetImporterFilterDescription(const wxString & filterDesc) +{ + mImporterFilterDesc = filterDesc; +} + +const wxArrayString & PluginDescriptor::GetImporterExtensions() const +{ + return mImporterExtensions; +} + +void PluginDescriptor::SetImporterExtensions(const wxArrayString & extensions) +{ + mImporterExtensions = extensions; +} + /////////////////////////////////////////////////////////////////////////////// // // PluginManager // /////////////////////////////////////////////////////////////////////////////// -static PluginManager mInstance; +#define CACHEROOT wxString(wxT("/plugincache/")) + +#define KEY_ID wxT("ID") +#define KEY_NAME wxT("Name") +#define KEY_PATH wxT("Path") +#define KEY_VENDOR wxT("Vendor") +#define KEY_VERSION wxT("Version") +#define KEY_DESCRIPTION wxT("Description") +#define KEY_LASTUPDATED wxT("LastUpdated") +#define KEY_ENABLED wxT("Enabled") +#define KEY_PROVIDERID wxT("ProviderID") +#define KEY_EFFECTTYPE wxT("EffectType") +#define KEY_EFFECTFAMILY wxT("EffectFamily") +#define KEY_EFFECTDEFAULT wxT("EffectDefault") +#define KEY_EFFECTINTERACTIVE wxT("EffectInteractive") +#define KEY_EFFECTREALTIMECAPABLE wxT("EffectRealtimeCapable") +#define KEY_EFFECTTYPE_ANALYZE wxT("Analyze") +#define KEY_EFFECTTYPE_GENERATE wxT("Generate") +#define KEY_EFFECTTYPE_PROCESS wxT("Process") +#define KEY_IMPORTERIDENT wxT("ImporterIdent") +#define KEY_IMPORTERFILTER wxT("ImporterFilter") +#define KEY_IMPORTEREXTENSIONS wxT("ImporterExtensions") + +// ============================================================================ +// +// PluginManagerInterface implementation +// +// ============================================================================ + +void PluginManager::RegisterModulePlugin(IdentInterface *module) +{ + CreatePlugin(module, PluginTypeModule); +} + +void PluginManager::RegisterEffectPlugin(IdentInterface *provider, EffectIdentInterface *effect) +{ + PluginDescriptor & plug = CreatePlugin(effect, PluginTypeEffect); + + plug.SetProviderID(provider->GetID()); + + plug.SetEffectType(effect->GetType()); + plug.SetEffectFamily(effect->GetFamily()); + plug.SetEffectInteractive(effect->IsInteractive()); + plug.SetEffectDefault(effect->IsDefault()); + plug.SetEffectRealtimeCapable(effect->IsRealtimeCapable()); + + plug.SetEnabled(true); +} + +void PluginManager::RegisterImporterPlugin(IdentInterface *provider, ImporterInterface *importer) +{ + PluginDescriptor & plug = CreatePlugin(importer, PluginTypeImporter); + + plug.SetProviderID(provider->GetID()); + + plug.SetImporterIdentifier(importer->GetPluginStringID()); + plug.SetImporterFilterDescription(importer->GetPluginFormatDescription()); + plug.SetImporterExtensions(importer->GetSupportedExtensions()); +} + +void PluginManager::FindFilesInPathList(const wxString & pattern, + const wxArrayString & pathList, + wxArrayString & files, + bool directories) +{ + + wxLogNull nolog; + + // Why bother... + if (pattern.empty()) + { + return; + } + + // TODO: We REALLY need to figure out the "Audacity" plug-in path(s) + + wxFileName f; + wxArrayString paths; + + // Add the "per-user" plug-ins directory + f = FileNames::PlugInDir(); + paths.Add(f.GetFullPath()); + + // Add the "Audacity" plug-ins directory + f = PlatformCompatibility::GetExecutablePath(); +#if defined(__WXMAC__) + f.RemoveLastDir(); + f.RemoveLastDir(); + f.RemoveLastDir(); +#endif + f.AppendDir(wxT("plug-ins")); + paths.Add(f.GetPath()); + + // Weed out duplicates + for (size_t i = 0, cnt = pathList.size(); i < cnt; i++) + { + f = pathList[i]; + wxString path = f.GetFullPath(); + if (paths.Index(path, wxFileName::IsCaseSensitive()) == wxNOT_FOUND) + { + paths.Add(path); + } + } + + // Find all matching files in each path + for (size_t i = 0, cnt = paths.GetCount(); i < cnt; i++) + { + f = paths[i] + wxFILE_SEP_PATH + pattern; + wxString a = f.GetFullPath(); + wxDir::GetAllFiles(f.GetPath(), &files, f.GetFullName(), directories ? wxDIR_DEFAULT : wxDIR_FILES); + } + + return; +} + +bool PluginManager::GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, wxString & value, const wxString & defval) +{ + return GetConfig(SharedKey(ID, group, key), value, defval); +} + +bool PluginManager::GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, int & value, int defval) +{ + return GetConfig(SharedKey(ID, group, key), value, defval); +} + +bool PluginManager::GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, bool & value, bool defval) +{ + return GetConfig(SharedKey(ID, group, key), value, defval); +} + +bool PluginManager::GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, float & value, float defval) +{ + return GetConfig(SharedKey(ID, group, key), value, defval); +} + +bool PluginManager::GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, double & value, double defval) +{ + return GetConfig(SharedKey(ID, group, key), value, defval); +} + +bool PluginManager::GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, sampleCount & value, sampleCount defval) +{ + return GetConfig(SharedKey(ID, group, key), value, defval); +} + +bool PluginManager::SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const wxString & value) +{ + return SetConfig(SharedKey(ID, group, key), value); +} + +bool PluginManager::SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const int & value) +{ + return SetConfig(SharedKey(ID, group, key), value); +} + +bool PluginManager::SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const bool & value) +{ + return SetConfig(SharedKey(ID, group, key), value); +} + +bool PluginManager::SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const float & value) +{ + return SetConfig(SharedKey(ID, group, key), value); +} + +bool PluginManager::SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const double & value) +{ + return SetConfig(SharedKey(ID, group, key), value); +} + +bool PluginManager::SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const sampleCount & value) +{ + return SetConfig(SharedKey(ID, group, key), value); +} + +bool PluginManager::GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, wxString & value, const wxString & defval) +{ + return GetConfig(PrivateKey(ID, group, key), value, defval); +} + +bool PluginManager::GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, int & value, int defval) +{ + return GetConfig(PrivateKey(ID, group, key), value, defval); +} + +bool PluginManager::GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, bool & value, bool defval) +{ + return GetConfig(PrivateKey(ID, group, key), value, defval); +} + +bool PluginManager::GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, float & value, float defval) +{ + return GetConfig(PrivateKey(ID, group, key), value, defval); +} + +bool PluginManager::GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, double & value, double defval) +{ + return GetConfig(PrivateKey(ID, group, key), value, defval); +} + +bool PluginManager::GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, sampleCount & value, sampleCount defval) +{ + return GetConfig(PrivateKey(ID, group, key), value, defval); +} + +bool PluginManager::SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const wxString & value) +{ + return SetConfig(PrivateKey(ID, group, key), value); +} + +bool PluginManager::SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const int & value) +{ + return SetConfig(PrivateKey(ID, group, key), value); +} + +bool PluginManager::SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const bool & value) +{ + return SetConfig(PrivateKey(ID, group, key), value); +} + +bool PluginManager::SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const float & value) +{ + return SetConfig(PrivateKey(ID, group, key), value); +} + +bool PluginManager::SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const double & value) +{ + return SetConfig(PrivateKey(ID, group, key), value); +} + +bool PluginManager::SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const sampleCount & value) +{ + return SetConfig(PrivateKey(ID, group, key), value); +} + +// ============================================================================ +// +// PluginManager +// +// ============================================================================ + +// The one and only PluginManager +PluginManager PluginManager::mInstance; + +// ---------------------------------------------------------------------------- +// Creation/Destruction +// ---------------------------------------------------------------------------- PluginManager::PluginManager() { mConfig = NULL; - mDirty = false; } PluginManager::~PluginManager() { - if (mConfig) { - Close(); + if (mConfig) + { + delete mConfig; } } -PluginManager & PluginManager::Get(bool WXUNUSED(refresh)) +// ---------------------------------------------------------------------------- +// PluginManager implementation +// ---------------------------------------------------------------------------- + +// ============================================================================ +// +// Return reference to singleton +// +// (Thread-safe...no active threading during construction or after destruction) +// ============================================================================ + +PluginManager & PluginManager::Get() { return mInstance; } -void PluginManager::Open() +void PluginManager::Initialize() { - // Writes out any pending changes and - // sets mConfig == NULL. - Close(); + Load(); + ModuleManager::Get().EarlyInit(); - wxFileName name(FileNames::PluginsCache()); + CheckForUpdates(); - if (!::wxFileExists(FileNames::PluginsCache())) { - wxFile file; - file.Create(FileNames::PluginsCache()); - file.Close(); + bool doRescan; + gPrefs->Read(wxT("/VST/Rescan"), &doRescan, true); + if (doRescan) + { + gPrefs->Write(wxT("/VST/Rescan"), false); + PluginRegistrationDialog dlg; + dlg.ShowModal(); } - - wxFileInputStream stream(FileNames::PluginsCache()); - - // mConfig is NULL because of the PlugInManager::Close() earlier. - // create it and fill it from the stream. - mConfig = new wxFileConfig(stream); } -void PluginManager::Close() +void PluginManager::Terminate() +{ + if (mConfig) + { + Save(); + delete mConfig; + mConfig = NULL; + } + + // Get rid of all non-module plugins first + PluginMap::iterator iter = mPlugins.begin(); + while (iter != mPlugins.end()) + { + PluginDescriptor & plug = iter->second; + if (plug.GetPluginType() == PluginTypeEffect) + { + mPlugins.erase(iter++); + continue; + } + + ++iter; + } + + // Now get rid of the modules + iter = mPlugins.begin(); + while (iter != mPlugins.end()) + { + mPlugins.erase(iter++); + } +} + +void PluginManager::Load() +{ + // IF already open THEN nothing to do. + if (mConfig != NULL) + { + return; + } + + // Create the config + // + // TODO: I'd like to switch to XML using the TinyXML2 lib + mConfig = new wxFileConfig(wxEmptyString, wxEmptyString, FileNames::PluginsCache()); + + // If this group doesn't exist then we have the original format and we + // can't use it or even attempt a conversion, so just start with a fresh + // config. + if (!mConfig->HasGroup(CACHEROOT)) + { + // Must start over + mConfig->DeleteAll(); + return; + } + + // Load all provider plugins first + LoadGroup(wxT("modules"), PluginTypeModule); + + // Now the rest + LoadGroup(wxT("effects"), PluginTypeEffect); + LoadGroup(wxT("exporters"), PluginTypeExporter); + LoadGroup(wxT("importers"), PluginTypeImporter); +} + +void PluginManager::LoadGroup(const wxChar * group, PluginType type) +{ + wxString strVal; + bool boolVal; + wxString groupName; + long groupIndex; + wxString cfgPath = CACHEROOT + group + wxCONFIG_PATH_SEPARATOR; + + mConfig->SetPath(cfgPath); + for (bool cont = mConfig->GetFirstGroup(groupName, groupIndex); + cont; + mConfig->SetPath(cfgPath), + cont = mConfig->GetNextGroup(groupName, groupIndex)) + { + PluginDescriptor plug; + + // Bypass group if the ID is already in use + if (mPlugins.find(wxString(groupName)) != mPlugins.end()) + { + continue; + } + + mConfig->SetPath(groupName); + + // Set the ID and type + plug.SetID(wxString(groupName)); + plug.SetPluginType(type); + + // Get the provider ID and bypass group if not found + if (!mConfig->Read(KEY_PROVIDERID, &strVal, wxEmptyString)) + { + // Bypass group if the provider isn't valid + if (!strVal.IsEmpty() && mPlugins.find(wxString(strVal)) == mPlugins.end()) + { + continue; + } + } + plug.SetProviderID(PluginID(strVal)); + + // Get the path (optional) + mConfig->Read(KEY_PATH, &strVal, wxEmptyString); + plug.SetPath(wxString(strVal)); + + // Get the name and bypass group if not found + if (!mConfig->Read(KEY_NAME, &strVal)) + { + continue; + } + plug.SetName(wxString(strVal)); + + // Get the version and bypass group if not found + if (!mConfig->Read(KEY_VERSION, &strVal)) + { + continue; + } + plug.SetVersion(wxString(strVal)); + + // Get the vendor and bypass group if not found + if (!mConfig->Read(KEY_VENDOR, &strVal)) + { + continue; + } + plug.SetVendor(wxString(strVal)); + + // Get the description and bypass group if not found + if (!mConfig->Read(KEY_DESCRIPTION, &strVal)) + { + continue; + } + plug.SetDescription(wxString(strVal)); + + // Get the last update time and bypass group if not found + if (!plug.GetPath().empty()) + { + if (!mConfig->Read(KEY_LASTUPDATED, &strVal)) + { + continue; + } + plug.SetDateTime(wxString(strVal)); + } + + // Is it enabled...default to no if not found + mConfig->Read(KEY_ENABLED, &boolVal, false); + plug.SetEnabled(boolVal); + + switch (type) + { + case PluginTypeModule: + break; + + case PluginTypeEffect: + // Get the effect type and bypass group if not found + if (!mConfig->Read(KEY_EFFECTTYPE, &strVal)) + { + continue; + } + + if (strVal.IsSameAs(KEY_EFFECTTYPE_ANALYZE)) + { + plug.SetEffectType(EffectTypeAnalyze); + } + else if (strVal.IsSameAs(KEY_EFFECTTYPE_GENERATE)) + { + plug.SetEffectType(EffectTypeGenerate); + } + else if (strVal.IsSameAs(KEY_EFFECTTYPE_PROCESS)) + { + plug.SetEffectType(EffectTypeProcess); + } + else + { + continue; + } + + // Get the effect family and bypass group if not found + if (!mConfig->Read(KEY_EFFECTFAMILY, &strVal)) + { + continue; + } + plug.SetEffectFamily(wxString(strVal)); + + // Is it a default (above the line) effect and bypass group if not found + if (!mConfig->Read(KEY_EFFECTDEFAULT, &boolVal)) + { + continue; + } + plug.SetEffectDefault(boolVal); + + // Is it an interactive effect and bypass group if not found + if (!mConfig->Read(KEY_EFFECTINTERACTIVE, &boolVal)) + { + continue; + } + plug.SetEffectInteractive(boolVal); + + // Is it an realtime capable effect and bypass group if not found + if (!mConfig->Read(KEY_EFFECTREALTIMECAPABLE, &boolVal)) + { + continue; + } + plug.SetEffectRealtimeCapable(boolVal); + + break; + + case PluginTypeImporter: + { + // Get the importer identifier and bypass group if not found + if (!mConfig->Read(KEY_IMPORTERIDENT, &strVal)) + { + continue; + } + plug.SetImporterIdentifier(wxString(strVal)); + + // Get the importer filter description and bypass group if not found + if (!mConfig->Read(KEY_IMPORTERFILTER, &strVal)) + { + continue; + } + plug.SetImporterFilterDescription(wxString(strVal)); + + // Get the importer extensions and bypass group if not found + if (!mConfig->Read(KEY_IMPORTEREXTENSIONS, &strVal)) + { + continue; + } + wxArrayString extensions; + wxStringTokenizer tkr(strVal, wxT(":")); + while (tkr.HasMoreTokens()) + { + extensions.push_back(wxString(tkr.GetNextToken())); + } + plug.SetImporterExtensions(extensions); + } + break; + + default: + continue; + } + + // Everything checked out...accept the plugin + mPlugins[groupName] = plug; + } + + return; +} + +void PluginManager::Save() { // IF already closed THEN nothing to do. - if( mConfig == NULL ) - return; - - // JKC: There is no recovery action here if writing the - // config out fails (e.g. due to write protected media). - // I guess we can live with that for now. - // This function will still close the config and - // delete it, without updating the file. - if( IsDirty()) + if (mConfig == NULL) { - wxFile file(FileNames::PluginsCache(), wxFile::write); - if (!file.IsOpened()) - { - // Might fail to open... - wxLogDebug(wxT("Couldn't open plugins cache for write")); - } - else - { - wxFileOutputStream stream(file); - // Save() might return false. - mConfig->Save(stream); - file.Close(); - } - } - - SetDirty( false ); - delete mConfig; - mConfig = NULL; -} - -bool PluginManager::IsDirty() -{ - return mDirty; -} - -void PluginManager::SetDirty(bool dirty) -{ - mDirty = dirty; -} - -wxString PluginManager::Read(const wxString & key, const wxString & def) -{ - if (mConfig) { - return mConfig->Read(key, def); - } - - return def; -} - -long PluginManager::Read(const wxString & key, long def) -{ - if (mConfig) { - return mConfig->Read(key, def); - } - - return def; -} - -void PluginManager::Write(const wxString & key, const wxString & val) -{ - if (mConfig) { - mConfig->Write(key, val); - - SetDirty(); - } - - return; -} - -void PluginManager::Write(const wxString & key, long val) -{ - if (mConfig) { - mConfig->Write(key, val); - - SetDirty(); - } - - return; -} - -bool PluginManager::HasType(const wxString & type) -{ - if (!mConfig) { - return false;; - } - - wxString path; - - path.Printf(wxT("/%s"), type.c_str()); - - return mConfig->HasGroup(path); -} - -void PluginManager::PurgeType(const wxString & type) -{ - if (!mConfig) { return; } - wxString path; + // TODO: This is a bit drastic...only save groups when new plugins are registerd - path.Printf(wxT("/%s"), type.c_str()); + // Save the individual groups + SaveGroup(wxT("effects"), PluginTypeEffect); + SaveGroup(wxT("exporters"), PluginTypeExporter); + SaveGroup(wxT("importers"), PluginTypeImporter); - SetDirty(); - mConfig->DeleteGroup(path); + // And now the providers + SaveGroup(wxT("modules"), PluginTypeModule); + + mConfig->Flush(); } -int PluginManager::GetPluginCount(const wxString & type) +void PluginManager::SaveGroup(const wxChar *group, PluginType type) { - if (!mConfig) { - return 0; - } + for (PluginMap::iterator iter = mPlugins.begin(); iter != mPlugins.end(); iter++) + { + PluginDescriptor & plug = iter->second; - wxString path = mConfig->GetPath(); - - mConfig->SetPath(wxString::Format(wxT("/%s"), type.c_str())); - - int cnt = mConfig->GetNumberOfGroups(); - - mConfig->SetPath(path); - - return cnt; -} - -wxString PluginManager::GetPlugin(const wxString & type, int index) -{ - if (!mConfig) { - return wxEmptyString; - } - - wxString path; - - path.Printf(wxT("/%s/%d"), type.c_str(), index); - if (!mConfig->HasGroup(path)) { - return wxEmptyString; - } - - mConfig->SetPath(path); - - path = mConfig->Read(wxT("PluginPath"), wxEmptyString); - - mConfig->SetPath(wxT("private")); - - return path; -} - -wxString PluginManager::GetFirstPlugin(const wxString & type) -{ - if (!mConfig) { - return wxEmptyString; - } - - wxString path; - - mCurrentIndex = -1; - - do { - path.Printf(wxT("/%s/%d"), type.c_str(), ++mCurrentIndex); - if (!mConfig->HasGroup(path)) { - return wxEmptyString; + if (plug.GetPluginType() != type) + { + continue; } - mConfig->SetPath(path); - } while (!mConfig->Read(wxT("Enabled"), (bool) true)); + mConfig->SetPath(CACHEROOT + group + wxCONFIG_PATH_SEPARATOR + plug.GetID()); - path = mConfig->Read(wxT("PluginPath"), wxEmptyString); + mConfig->Write(KEY_PATH, plug.GetPath()); + mConfig->Write(KEY_NAME, plug.GetName()); + mConfig->Write(KEY_VERSION, plug.GetVersion()); + mConfig->Write(KEY_VENDOR, plug.GetVendor()); + mConfig->Write(KEY_DESCRIPTION, plug.GetDescription()); + mConfig->Write(KEY_PROVIDERID, plug.GetProviderID()); + mConfig->Write(KEY_LASTUPDATED, plug.GetDateTime()); + mConfig->Write(KEY_ENABLED, plug.IsEnabled()); - mConfig->SetPath(wxT("private")); + switch (type) + { + case PluginTypeModule: + break; - return path; -} + case PluginTypeEffect: + { + EffectType etype = plug.GetEffectType(); + wxString stype; + if (etype == EffectTypeAnalyze) + { + stype = KEY_EFFECTTYPE_ANALYZE; + } + else if (etype == EffectTypeGenerate) + { + stype = KEY_EFFECTTYPE_GENERATE; + } + else if (etype == EffectTypeProcess) + { + stype = KEY_EFFECTTYPE_PROCESS; + } + mConfig->Write(KEY_EFFECTTYPE, stype); + mConfig->Write(KEY_EFFECTFAMILY, plug.GetEffectFamily()); + mConfig->Write(KEY_EFFECTDEFAULT, plug.IsEffectDefault()); + mConfig->Write(KEY_EFFECTINTERACTIVE, plug.IsEffectInteractive()); + mConfig->Write(KEY_EFFECTREALTIMECAPABLE, plug.IsEffectRealtimeCapable()); + } + break; -wxString PluginManager::GetNextPlugin(const wxString & type) -{ - if (!mConfig) { - return wxEmptyString; + case PluginTypeImporter: + { + mConfig->Write(KEY_IMPORTERIDENT, plug.GetImporterIdentifier()); + mConfig->Write(KEY_IMPORTERFILTER, plug.GetImporterFilterDescription()); + const wxArrayString & extensions = plug.GetImporterExtensions(); + wxString strExt; + for (size_t i = 0, cnt = extensions.size(); i < cnt; i++) + { + strExt += extensions[i] + wxT(":"); + } + strExt.RemoveLast(1); + mConfig->Write(KEY_IMPORTEREXTENSIONS, strExt); + } + break; + + default: + break; + } } - wxString path; - - do { - path.Printf(wxT("/%s/%d"), type.c_str(), ++mCurrentIndex); - if (!mConfig->HasGroup(path)) { - return wxEmptyString; - } - - mConfig->SetPath(path); - } while (!mConfig->Read(wxT("Enabled"), (bool) true)); - - path = mConfig->Read(wxT("PluginPath"), wxEmptyString); - - mConfig->SetPath(wxT("private")); - - return path; + return; } -bool PluginManager::IsRegistered(const wxString & type, const wxString & path) +void PluginManager::CheckForUpdates() { - int cnt = GetPluginCount(type); + // Always check for and remove missing plugins + RemoveMissing(); - for (int i = 0; i < cnt; i++) { - wxString registered = GetPlugin(type, i); - if (registered == path) { + // Get ModuleManager reference + ModuleManager & mm = ModuleManager::Get(); + + wxArrayString providers; + wxArrayString paths; + + // Always check for new or updated modules + if (mm.DiscoverProviders(paths)) + { + paths = IsNewOrUpdated(paths); + for (size_t i = 0, cnt = paths.size(); i < cnt; i++) + { + mm.DiscoverProvider(paths[i]); + } + } + + bool doCheck; + gPrefs->Read(wxT("/Plugins/CheckForUpdates"), &doCheck, true); + if (doCheck && paths.size() > 0) + { + PluginRegistrationDialog dlg; + dlg.ShowModal(); + } + + return; +} + +void PluginManager::RemoveMissing() +{ + // Check for plugins that no longer exist + PluginMap::iterator iter = mPlugins.begin(); + while (iter != mPlugins.end()) + { + PluginDescriptor & plug = iter->second; + + if (!plug.GetPath().empty()) + { + wxFileName plugPath = plug.GetPath(); + + if (!(plugPath.FileExists() || plugPath.DirExists())) + { + mPlugins.erase(iter++); + continue; + } + } + + ++iter; + } +} + +wxArrayString PluginManager::IsNewOrUpdated(const wxArrayString & paths) +{ + wxArrayString plugsToAddOrUpdate; + + // Create a map of plugins indexed by their path + std::map pathPlugs; + for (PluginMap::iterator iter = mPlugins.begin(); iter != mPlugins.end(); iter++) + { + PluginDescriptor & plug = iter->second; + pathPlugs[plug.GetPath()] = &plug; + } + + // Now check for new or updated paths + for (size_t i = 0, cnt = paths.size(); i < cnt; i++) + { + wxFileName scanPath = paths[i]; + wxString scanFull = scanPath.GetFullPath(); + + if (pathPlugs.find(scanFull) != pathPlugs.end()) + { + if (GetDateTime(scanFull) <= pathPlugs[scanFull]->GetDateTime()) + { + continue; + } + } + + plugsToAddOrUpdate.push_back(scanFull); + } + + return plugsToAddOrUpdate; +} + +bool PluginManager::HasType(PluginType type) +{ + for (PluginMap::iterator iter = mPlugins.begin(); iter != mPlugins.end(); iter++) + { + if (iter->second.GetPluginType() == type) + { return true; } } @@ -292,51 +1746,477 @@ bool PluginManager::IsRegistered(const wxString & type, const wxString & path) return false; } -void PluginManager::RegisterPlugin(const wxString & type, const wxString & path) +void PluginManager::PurgeType(PluginType type) { - if (IsRegistered(type, path)) { - return; +#if 0 + for (PluginMap::iterator iter = mPlugins.begin(); iter != mPlugins.end(); iter++) + { + if (iter->second.GetPluginType() == type) + { + mPlugins.erase(iter->first); + mConfig->DeleteGroup(CACHEROOT + iter->second.GetID() + } } - - mConfig->SetPath(wxString::Format(wxT("/%s/%d"), type.c_str(), GetPluginCount(type))); - - mConfig->Write(wxT("PluginPath"), path); - SetDirty(); - - mConfig->SetPath(wxT("private")); - - return; +#endif } -bool PluginManager::IsPluginEnabled(const wxString & type, const wxString & path) +int PluginManager::GetPluginCount(PluginType type) { - int cnt = GetPluginCount(type); + int num = 0; - for (int i = 0; i < cnt; i++) { - wxString registered = GetPlugin(type, i); - if (registered == path) { - mConfig->SetPath(wxT("..")); - bool enabled = mConfig->Read(wxT("Enabled"), true) != false; - mConfig->SetPath(wxT("private")); - return enabled; + for (PluginMap::iterator iter = mPlugins.begin(); iter != mPlugins.end(); iter++) + { + if (iter->second.GetPluginType() == type) + { + num++; } } + return num; +} + +const PluginDescriptor *PluginManager::GetPlugin(const PluginID & ID) +{ + if (mPlugins.find(ID) == mPlugins.end()) + { + return NULL; + } + + return &mPlugins[ID]; +} + +const PluginDescriptor *PluginManager::GetFirstPlugin(PluginType type) +{ + for (mPluginsIter = mPlugins.begin(); mPluginsIter != mPlugins.end(); mPluginsIter++) + { + if (mPluginsIter->second.GetPluginType() == type) + { + return &mPluginsIter->second; + } + } + + return NULL; +} + +const PluginDescriptor *PluginManager::GetNextPlugin(PluginType type) +{ + while (++mPluginsIter != mPlugins.end()) + { + if (mPluginsIter->second.GetPluginType() == type) + { + return &mPluginsIter->second; + } + } + + return NULL; +} + +const PluginDescriptor *PluginManager::GetFirstPluginForProvider(const PluginID & ID) +{ + for (mPluginsIter = mPlugins.begin(); mPluginsIter != mPlugins.end(); mPluginsIter++) + { + if (mPluginsIter->second.GetProviderID() == ID) + { + return &mPluginsIter->second; + } + } + + return NULL; +} + +const PluginDescriptor *PluginManager::GetNextPluginForProvider(const PluginID & ID) +{ + while (++mPluginsIter != mPlugins.end()) + { + if (mPluginsIter->second.GetProviderID() == ID) + { + return &mPluginsIter->second; + } + } + + return NULL; +} + +const PluginDescriptor *PluginManager::GetFirstPluginForEffectType(EffectType type) +{ + for (mPluginsIter = mPlugins.begin(); mPluginsIter != mPlugins.end(); mPluginsIter++) + { + PluginDescriptor & plug = mPluginsIter->second; + if (plug.IsEnabled() && plug.GetEffectType() == type) + { + return &plug; + } + } + + return NULL; +} + +const PluginDescriptor *PluginManager::GetNextPluginForEffectType(EffectType type) +{ + while (++mPluginsIter != mPlugins.end()) + { + PluginDescriptor & plug = mPluginsIter->second; + if (plug.IsEnabled() && plug.GetEffectType() == type) + { + return &plug; + } + } + + return NULL; +} + + +const PluginDescriptor *PluginManager::GetFirstPluginForEffectFamily(const wxString & family) +{ + for (mPluginsIter = mPlugins.begin(); mPluginsIter != mPlugins.end(); mPluginsIter++) + { + if (mPluginsIter->second.GetEffectFamily() == family) + { + return &mPluginsIter->second; + } + } + + return NULL; +} + +const PluginDescriptor *PluginManager::GetNextPluginForEffectFamily(const wxString & family) +{ + while (++mPluginsIter != mPlugins.end()) + { + if (mPluginsIter->second.GetEffectFamily() == family) + { + return &mPluginsIter->second; + } + } + + return NULL; +} + +bool PluginManager::IsRegistered(const PluginID & ID) +{ + if (mPlugins.find(ID) == mPlugins.end()) + { + return false; + } + return true; } -void PluginManager::EnablePlugin(const wxString & type, const wxString & path, bool enable) +const PluginID & PluginManager::RegisterLegacyEffectPlugin(EffectIdentInterface *effect) { - int cnt = GetPluginCount(type); + PluginDescriptor & plug = CreatePlugin(effect, PluginTypeEffect); - for (int i = 0; i < cnt; i++) { - wxString registered = GetPlugin(type, i); - if (registered == path) { - mConfig->SetPath(wxT("..")); - mConfig->Write(wxT("Enabled"), enable); - SetDirty(true); - mConfig->SetPath(wxT("private")); - break; - } - } + plug.SetEffectType(effect->GetType()); + plug.SetEffectFamily(effect->GetFamily()); + plug.SetEffectInteractive(effect->IsInteractive()); + plug.SetEffectDefault(effect->IsDefault()); + plug.SetEffectRealtimeCapable(effect->IsRealtimeCapable()); + + plug.SetInstance(effect); + plug.SetEffectLegacy(true); + plug.SetEnabled(true); + + return plug.GetID(); } + +bool PluginManager::IsPluginEnabled(const PluginID & ID) +{ + if (mPlugins.find(ID) == mPlugins.end()) + { + return false; + } + + return mPlugins[ID].IsEnabled(); +} + +void PluginManager::EnablePlugin(const PluginID & ID, bool enable) +{ + if (mPlugins.find(ID) == mPlugins.end()) + { + return; + } + + return mPlugins[ID].SetEnabled(enable); +} + +const wxString & PluginManager::GetName(const PluginID & ID) +{ + if (mPlugins.find(ID) == mPlugins.end()) + { + static wxString empty; + return empty; + } + + return mPlugins[ID].GetName(); +} + +void *PluginManager::GetInstance(const PluginID & ID) +{ + if (mPlugins.find(ID) == mPlugins.end()) + { + return NULL; + } + + PluginDescriptor & plug = mPlugins[ID]; + + // If not dealing with legacy effects, make sure the provider is loaded + if (!plug.IsEffectLegacy()) + { + const PluginID & prov = plug.GetProviderID(); + if (mPlugins.find(prov) == mPlugins.end()) + { + return NULL; + } + mPlugins[prov].GetInstance(); + } + + return plug.GetInstance(); +} + +// TODO: This goes away when all effects have been converted +void PluginManager::SetInstance(const PluginID & ID, void *instance) +{ + if (mPlugins.find(ID) == mPlugins.end()) + { + return; + } + + return mPlugins[ID].SetInstance(instance); +} + +PluginDescriptor & PluginManager::CreatePlugin(IdentInterface *ident, PluginType type) +{ + PluginDescriptor plug; + + plug.SetPluginType(type); + + plug.SetID(ident->GetID()); + plug.SetPath(ident->GetPath()); + plug.SetName(ident->GetName()); + plug.SetVendor(ident->GetVendor()); + plug.SetVersion(ident->GetVersion()); + plug.SetDescription(ident->GetDescription()); + plug.SetEnabled(false); + plug.SetDateTime(GetDateTime(ident->GetPath())); + + // This will either create a new entry or replace an existing entry + mPlugins[plug.GetID()] = plug; + PluginDescriptor &p = mPlugins[plug.GetID()]; + return mPlugins[plug.GetID()]; +} + +wxString PluginManager::GetDateTime(const wxString & path) +{ + wxFileName fn(path); + if (fn.FileExists()) + { + wxDateTime mod = fn.GetModificationTime(); + return wxString(mod.FormatISODate() + wxT(' ') + mod.FormatISOTime()); + } + + return L""; +} + +bool PluginManager::GetConfig(const wxString & key, wxString & value, const wxString & defval) +{ + bool result = false; + + if (mConfig && !key.empty()) + { + wxString wxval = wxEmptyString; + + result = mConfig->Read(key, &wxval, defval); + + value = wxval; + } + + return result; +} + +bool PluginManager::GetConfig(const wxString & key, int & value, int defval) +{ + bool result = false; + + if (mConfig && !key.empty()) + { + result = mConfig->Read(key, &value, defval); + } + + return result; +} + +bool PluginManager::GetConfig(const wxString & key, bool & value, bool defval) +{ + bool result = false; + + if (mConfig && !key.empty()) + { + result = mConfig->Read(key, &value, defval); + } + + return result; +} + +bool PluginManager::GetConfig(const wxString & key, float & value, float defval) +{ + bool result = false; + + if (mConfig && !key.empty()) + { + double dval = 0.0; + + result = mConfig->Read(key, &dval, (double) defval); + + value = (float) dval; + } + + return result; +} + +bool PluginManager::GetConfig(const wxString & key, double & value, double defval) +{ + bool result = false; + + if (mConfig && !key.empty()) + { + result = mConfig->Read(key, &value, defval); + } + + return result; +} + +bool PluginManager::GetConfig(const wxString & key, sampleCount & value, sampleCount defval) +{ + bool result = false; + + if (mConfig && !key.empty()) + { + wxString wxval = wxEmptyString; + wxString wxdef; + wchar_t *endptr; + wxdef.Printf(wxT("%Ld"), defval); + + result = mConfig->Read(key, &wxval, wxdef); + value = wxStrtoll(wxval.c_str(), &endptr, 10); + } + + return result; +} + +bool PluginManager::SetConfig(const wxString & key, const wxString & value) +{ + bool result = false; + + if (mConfig && !key.empty()) + { + wxString wxval = value.c_str(); + result = mConfig->Write(key, wxval); + } + + return result; +} + +bool PluginManager::SetConfig(const wxString & key, const int & value) +{ + bool result = false; + + if (mConfig && !key.empty()) + { + result = mConfig->Write(key, value); + } + + return result; +} + +bool PluginManager::SetConfig(const wxString & key, const bool & value) +{ + bool result = false; + + if (mConfig && !key.empty()) + { + result = mConfig->Write(key, value); + } + + return result; +} + +bool PluginManager::SetConfig(const wxString & key, const float & value) +{ + bool result = false; + + if (mConfig && !key.empty()) + { + result = mConfig->Write(key, value); + } + + return result; +} + +bool PluginManager::SetConfig(const wxString & key, const double & value) +{ + bool result = false; + + if (mConfig && !key.empty()) + { + result = mConfig->Write(key, value); + } + + return result; +} + +bool PluginManager::SetConfig(const wxString & key, const sampleCount & value) +{ + bool result = false; + + if (mConfig && !key.empty()) + { + result = mConfig->Write(key, wxString::Format(wxT("%d"), (int) value)); + } + + return result; +} + +wxString PluginManager::SharedKey(const PluginID & ID, const wxString & group, const wxString & key) +{ + if (mPlugins.find(ID) == mPlugins.end()) + { + L""; + } + + wxString path = CACHEROOT + + mPlugins[ID].GetProviderID() + + wxCONFIG_PATH_SEPARATOR + + wxT("private") + + wxCONFIG_PATH_SEPARATOR; + + wxFileName f(group); + if (!f.GetName().IsEmpty()) + { + path += f.GetName() + wxCONFIG_PATH_SEPARATOR; + } + + return path + key; +} + +wxString PluginManager::PrivateKey(const PluginID & ID, const wxString & group, const wxString & key) +{ + if (mPlugins.find(ID) == mPlugins.end()) + { + L""; + } + + wxString path = CACHEROOT + + ID + + wxCONFIG_PATH_SEPARATOR + + wxT("private") + + wxCONFIG_PATH_SEPARATOR; + + wxFileName f(group); + if (!f.GetName().IsEmpty()) + { + path += f.GetName() + wxCONFIG_PATH_SEPARATOR; + } + + return path + key; +} + diff --git a/src/PluginManager.h b/src/PluginManager.h index f6b561414..4f17def10 100644 --- a/src/PluginManager.h +++ b/src/PluginManager.h @@ -16,6 +16,13 @@ #include #include +#include + +#include "audacity/EffectInterface.h" +#include "audacity/ImporterInterface.h" +#include "audacity/ModuleInterface.h" +#include "audacity/PluginInterface.h" + /////////////////////////////////////////////////////////////////////////////// // // PluginManager @@ -24,50 +31,238 @@ typedef enum { - PluginTypeAll, - PluginTypeVST, - PluginTypeLadspa + PluginTypeNone, + PluginTypeEffect, + PluginTypeExporter, + PluginTypeImporter, + PluginTypeModule, } PluginType; -class PluginManager +// TODO: Convert this to multiple derived classes +class PluginDescriptor { - public: +public: + PluginDescriptor(); + virtual ~PluginDescriptor(); + + void *GetInstance(); + void SetInstance(void *instance); + + PluginType GetPluginType() const; + void SetPluginType(PluginType type); + + // All plugins + const wxString & GetID() const; + const wxString & GetPath() const; + const wxString & GetName() const; + const wxString & GetVersion() const; + const wxString & GetVendor() const; + const wxString & GetDescription() const; + const wxString & GetProviderID() const; + const wxString & GetDateTime() const; + bool IsEnabled() const; + + void SetID(const PluginID & ID); + void SetPath(const wxString & path); + void SetName(const wxString & name); + void SetVersion(const wxString & version); + void SetVendor(const wxString & vendor); + void SetDescription(const wxString & description); + void SetProviderID(const PluginID & providerID); + void SetDateTime(const wxString & dateTime); + void SetEnabled(bool enable); + + wxString GetMenuName() const; + + // Effect plugins only + + EffectType GetEffectType() const; + const wxString & GetEffectFamily() const; + bool IsEffectDefault() const; + bool IsEffectInteractive() const; + bool IsEffectLegacy() const; + bool IsEffectRealtimeCapable() const; + + void SetEffectType(EffectType type); + void SetEffectFamily(const wxString & family); + void SetEffectDefault(bool dflt); + void SetEffectInteractive(bool interactive); + void SetEffectLegacy(bool legacy); + void SetEffectRealtimeCapable(bool realtime); + + // Importer plugins only + + const wxString & GetImporterIdentifier() const; + const wxString & GetImporterFilterDescription() const; + const wxArrayString & GetImporterExtensions() const; + + void SetImporterIdentifier(const wxString & identifier); + void SetImporterFilterDescription(const wxString & filterDesc); + void SetImporterExtensions(const wxArrayString & extensions); + +private: + + // Common + + void *mInstance; + + PluginType mPluginType; + + wxString mID; + wxString mPath; + wxString mName; + wxString mVersion; + wxString mVendor; + wxString mDescription; + wxString mProviderID; + wxString mDateTime; + bool mEnabled; + + // Effects + + wxString mEffectFamily; + EffectType mEffectType; + bool mEffectInteractive; + bool mEffectDefault; + bool mEffectLegacy; + bool mEffectRealtimeCapable; + + // Importers + wxString mImporterIdentifier; + wxString mImporterFilterDesc; + wxArrayString mImporterExtensions; +}; + +//WX_DECLARE_STRING_HASH_MAP(PluginDescriptor, PluginMap); +typedef std::map PluginMap; +typedef wxArrayString PluginIDList; + +class PluginManager : public PluginManagerInterface +{ +public: PluginManager(); virtual ~PluginManager(); - void Open(); - void Close(); + // PluginManagerInterface implementation - static PluginManager & Get(bool refresh = false); + void RegisterModulePlugin(IdentInterface *module); + void RegisterEffectPlugin(IdentInterface *provider, EffectIdentInterface *effect); + void RegisterImporterPlugin(IdentInterface *provider, ImporterInterface *importer); - wxString Read(const wxString & key, const wxString & def); - long Read(const wxString & key, long def); + void FindFilesInPathList(const wxString & pattern, + const wxArrayString & pathList, + wxArrayString & files, + bool directories = false); - void Write(const wxString & key, const wxString & val); - void Write(const wxString & key, long val); + virtual bool GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, wxString & value, const wxString & defval = _T("")); + virtual bool GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, int & value, int defval = 0); + virtual bool GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, bool & value, bool defval = false); + virtual bool GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, float & value, float defval = 0.0); + virtual bool GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, double & value, double defval = 0.0); + virtual bool GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, sampleCount & value, sampleCount defval = 0); - bool HasType(const wxString & type); - void PurgeType(const wxString & type); + virtual bool SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const wxString & value); + virtual bool SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const int & value); + virtual bool SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const bool & value); + virtual bool SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const float & value); + virtual bool SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const double & value); + virtual bool SetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, const sampleCount & value); - int GetPluginCount(const wxString & type); - wxString GetPlugin(const wxString & type, int index); + virtual bool GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, wxString & value, const wxString & defval = _T("")); + virtual bool GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, int & value, int defval = 0); + virtual bool GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, bool & value, bool defval = false); + virtual bool GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, float & value, float defval = 0.0); + virtual bool GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, double & value, double defval = 0.0); + virtual bool GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, sampleCount & value, sampleCount defval = 0); - wxString GetFirstPlugin(const wxString & type); - wxString GetNextPlugin(const wxString & type); + virtual bool SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const wxString & value); + virtual bool SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const int & value); + virtual bool SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const bool & value); + virtual bool SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const float & value); + virtual bool SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const double & value); + virtual bool SetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, const sampleCount & value); - bool IsRegistered(const wxString & type, const wxString & path); + // PluginManager implementation + + void Initialize(); + void Terminate(); + + static PluginManager & Get(); + + bool HasType(PluginType type); + void PurgeType(PluginType type); + + int GetPluginCount(PluginType type); + const PluginDescriptor *GetPlugin(const PluginID & ID); + + const PluginDescriptor *GetFirstPlugin(PluginType type); + const PluginDescriptor *GetNextPlugin(PluginType type); + + const PluginDescriptor *GetFirstPluginForProvider(const PluginID & ID); + const PluginDescriptor *GetNextPluginForProvider(const PluginID & ID); + + const PluginDescriptor *GetFirstPluginForEffectType(EffectType type); + const PluginDescriptor *GetNextPluginForEffectType(EffectType type); + + const PluginDescriptor *GetFirstPluginForEffectFamily(const PluginID & ID); + const PluginDescriptor *GetNextPluginForEffectFamily(const PluginID & ID); + + bool IsRegistered(const PluginID & ID); void RegisterPlugin(const wxString & type, const wxString & path); - bool IsPluginEnabled(const wxString & type, const wxString & path); - void EnablePlugin(const wxString & type, const wxString & path, bool enable); + bool IsPluginEnabled(const PluginID & ID); + void EnablePlugin(const PluginID & ID, bool enable); + + const wxString & GetName(const PluginID & ID); + void *GetInstance(const PluginID & ID); + void SetInstance(const PluginID & ID, void *instance); // TODO: Remove after conversion + + // + const PluginID & RegisterLegacyEffectPlugin(EffectIdentInterface *effect); + + void CheckForUpdates(); private: + void Load(); + void LoadGroup(const wxChar *group, PluginType type); + void Save(); + void SaveGroup(const wxChar *group, PluginType type); + + void RemoveMissing(); + wxArrayString IsNewOrUpdated(const wxArrayString & paths); + + PluginDescriptor & CreatePlugin(IdentInterface *ident, PluginType type); + wxString GetDateTime(const wxString & path); + + bool GetConfig(const wxString & key, wxString & value, const wxString & defval = L""); + bool GetConfig(const wxString & key, int & value, int defval = 0); + bool GetConfig(const wxString & key, bool & value, bool defval = false); + bool GetConfig(const wxString & key, float & value, float defval = 0.0); + bool GetConfig(const wxString & key, double & value, double defval = 0.0); + bool GetConfig(const wxString & key, sampleCount & value, sampleCount defval = 0); + + bool SetConfig(const wxString & key, const wxString & value); + bool SetConfig(const wxString & key, const int & value); + bool SetConfig(const wxString & key, const bool & value); + bool SetConfig(const wxString & key, const float & value); + bool SetConfig(const wxString & key, const double & value); + bool SetConfig(const wxString & key, const sampleCount & value); + + wxString SharedKey(const PluginID & ID, const wxString & group, const wxString & key); + wxString PrivateKey(const PluginID & ID, const wxString & group, const wxString & key); + +private: + static PluginManager mInstance; + bool IsDirty(); void SetDirty(bool dirty = true); wxFileConfig *mConfig; bool mDirty; int mCurrentIndex; + + PluginMap mPlugins; + PluginMap::iterator mPluginsIter; }; -#endif /* __AUDACITY_LOADMODULES_H__ */ +#endif /* __AUDACITY_PLUGINMANAGER_H__ */ diff --git a/src/Project.cpp b/src/Project.cpp index 1196bb9f5..6a07597e7 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -134,7 +134,7 @@ scroll information. It also has some status flags. #ifdef EXPERIMENTAL_OD_FLAC #include "ondemand/ODDecodeFlacTask.h" #endif -#include "LoadModules.h" +#include "ModuleManager.h" #include "Theme.h" #include "AllThemeResources.h" @@ -509,7 +509,7 @@ AudacityProject *CreateNewAudacityProject() // and add the shortcut keys to the tooltips. p->GetControlToolBar()->RegenerateToolsTooltips(); - ModuleManager::Dispatch(ProjectInitialized); + ModuleManager::Get().Dispatch(ProjectInitialized); p->Show(true); @@ -765,7 +765,7 @@ AudacityProject::AudacityProject(wxWindow * parent, wxWindowID id, mRecordingRecoveryHandler(NULL), mImportedDependencies(false), mWantSaveCompressed(false), - mLastEffect(NULL), + mLastEffect(wxEmptyString), mLastEffectType(0), mTimerRecordCanceled(false), mMenuClose(false) @@ -1960,7 +1960,7 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event) } } - ModuleManager::Dispatch(ProjectClosing); + ModuleManager::Get().Dispatch(ProjectClosing); // Stop the timer since there's no need to update anything anymore delete mTimer; @@ -2152,7 +2152,7 @@ wxArrayString AudacityProject::ShowOpenDialog(wxString extraformat, wxString ext // Construct the filter l.DeleteContents(true); - wxGetApp().mImporter->GetSupportedImportFormats(&l); + Importer::Get().GetSupportedImportFormats(&l); for (FormatList::compatibility_iterator n = l.GetFirst(); n; n = n->GetNext()) { /* this loop runs once per supported _format_ */ @@ -2160,7 +2160,7 @@ wxArrayString AudacityProject::ShowOpenDialog(wxString extraformat, wxString ext wxString newfilter = f->formatName + wxT("|"); // bung format name into string plus | separator - for (size_t i = 0; i < f->formatExtensions.GetCount(); i++) { + for (size_t i = 0; i < f->formatExtensions.size(); i++) { /* this loop runs once per valid _file extension_ for file containing * the current _format_ */ if (!newfilter.Contains(wxT("*.") + f->formatExtensions[i] + wxT(";"))) @@ -3521,7 +3521,7 @@ bool AudacityProject::Import(wxString fileName, WaveTrackArray* pTrackArray /*= int numTracks; wxString errorMessage=wxT(""); - numTracks = wxGetApp().mImporter->Import(fileName, + numTracks = Importer::Get().Import(fileName, mTrackFactory, &newTracks, mTags, diff --git a/src/Project.h b/src/Project.h index 82e35896d..4d7e47535 100644 --- a/src/Project.h +++ b/src/Project.h @@ -563,7 +563,7 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, wxArrayString mStrOtherNamesArray; // used to make sure compressed file names are unique // Last effect applied to this project - Effect *mLastEffect; + PluginID mLastEffect; int mLastEffectType; // The screenshot class needs to access internals @@ -577,13 +577,13 @@ class AUDACITY_DLL_API AudacityProject: public wxFrame, // Are we currently closing as the result of a menu command? bool mMenuClose; - public: DECLARE_EVENT_TABLE() }; typedef void (AudacityProject::*audCommandFunction)(); typedef void (AudacityProject::*audCommandKeyFunction)(const wxEvent *); typedef void (AudacityProject::*audCommandListFunction)(int); +typedef void (AudacityProject::*audCommandPluginFunction)(const PluginID &); // Previously this was in menus.cpp, and the declaration of the // command functor was not visible anywhere else. @@ -596,16 +596,27 @@ public: audCommandKeyFunction commandFunction); AudacityProjectCommandFunctor(AudacityProject *project, audCommandListFunction commandFunction); + AudacityProjectCommandFunctor(AudacityProject *project, + audCommandPluginFunction commandFunction, + const PluginID & pluginID); +#if defined(EFFECT_CATEGORIES) AudacityProjectCommandFunctor(AudacityProject *project, audCommandListFunction commandFunction, wxArrayInt explicitIndices); +#endif + virtual void operator()(int index = 0, const wxEvent *evt = NULL); + private: AudacityProject *mProject; audCommandFunction mCommandFunction; audCommandKeyFunction mCommandKeyFunction; audCommandListFunction mCommandListFunction; + audCommandPluginFunction mCommandPluginFunction; + PluginID mPluginID; +#if defined(EFFECT_CATEGORIES) wxArrayInt mExplicitIndices; +#endif }; #endif diff --git a/src/SampleFormat.h b/src/SampleFormat.h index 2cbdea830..d2b9e8e04 100644 --- a/src/SampleFormat.h +++ b/src/SampleFormat.h @@ -14,30 +14,34 @@ #include "Audacity.h" #include +#include "audacity/Types.h" + // // Definitions / Meta-Information // +#if 0 +// Moved to audacity/types.h typedef enum { int16Sample = 0x00020001, int24Sample = 0x00040001, floatSample = 0x0004000F } sampleFormat; +/** \brief Return the size (in memory) of one sample (bytes) */ +#define SAMPLE_SIZE(SampleFormat) (SampleFormat >> 16) +#endif + // Used to determine how to fill in empty areas of audio. typedef enum { fillZero = 0, fillTwo = 2 }fillFormat; -/** \brief Return the size (in memory) of one sample (bytes) */ -#define SAMPLE_SIZE(SampleFormat) (SampleFormat >> 16) /** \brief Return the size on disk of one uncompressed sample (bytes) */ #define SAMPLE_SIZE_DISK(SampleFormat) ((SampleFormat == int24Sample) ? \ 3 : SAMPLE_SIZE(SampleFormat) ) -typedef char *samplePtr; - const wxChar *GetSampleFormatStr(sampleFormat format); // diff --git a/src/Sequence.h b/src/Sequence.h index 663de68d3..eca3cb3d9 100644 --- a/src/Sequence.h +++ b/src/Sequence.h @@ -19,8 +19,13 @@ #include "xml/XMLWriter.h" #include "ondemand/ODTaskThread.h" +#include "audacity/Types.h" + +#if 0 +// Moved to "audacity/types.h" typedef wxLongLong_t sampleCount; /** < A native 64-bit integer type, because 32-bit integers may not be enough */ +#endif class BlockFile; class DirManager; diff --git a/src/ShuttleGui.cpp b/src/ShuttleGui.cpp index d9b557493..8a91863fb 100644 --- a/src/ShuttleGui.cpp +++ b/src/ShuttleGui.cpp @@ -2170,6 +2170,12 @@ wxSizer *CreateStdButtonSizer(wxWindow *parent, long buttons, wxButton *extra) bs->AddButton( new wxButton( parent, wxID_NO ) ); } + if( buttons & eApplyButton ) + { + b = new wxButton( parent, wxID_APPLY ); + bs->AddButton( b ); + } + if( buttons & eHelpButton ) { bs->AddButton( new wxButton( parent, wxID_HELP ) ); @@ -2187,7 +2193,7 @@ wxSizer *CreateStdButtonSizer(wxWindow *parent, long buttons, wxButton *extra) if( buttons & eDefaultsButton ) { - bs->Add(new wxButton( parent, eDefaultsID, _("&Defaults") ) ); + bs->Add(new wxButton( parent, eDefaultsID, _("&Defaults") ), 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, margin ); bs->Add( 20, 0 ); } diff --git a/src/ShuttleGui.h b/src/ShuttleGui.h index d48826ae1..5bad91907 100644 --- a/src/ShuttleGui.h +++ b/src/ShuttleGui.h @@ -335,7 +335,8 @@ enum ePreviewButton = 0x0020, eDebugButton = 0x0040, eDefaultsButton= 0x0080, - ePreviewDryButton = 0x0100 + ePreviewDryButton = 0x0100, + eApplyButton = 0x0200, }; enum diff --git a/src/ThemeAsCeeCode.h b/src/ThemeAsCeeCode.h index 3a300bb13..75cd5ffe8 100644 --- a/src/ThemeAsCeeCode.h +++ b/src/ThemeAsCeeCode.h @@ -7,4031 +7,4060 @@ 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,1,184, 0,0,3,68,8,6,0,0,0,194,5,58,248,0,0,0,4,115,66,73, 84,8,8,8,8,124,8,100,136,0,0,32,0,73,68,65,84,120,156,236, - 189,123,120,84,215,121,239,255,221,115,209,204,72,3,72,96,176,176,17,65, - 50,138,13,182,127,70,16,82,99,187,70,184,142,123,30,59,165,38,78,220, - 220,234,250,151,228,180,174,73,73,48,118,220,164,23,68,219,159,83,39,54, - 36,56,56,78,127,245,41,225,224,52,77,142,193,77,124,105,176,99,32,33, - 64,138,65,56,137,133,9,66,82,44,108,129,132,46,72,154,153,61,183,189, - 206,31,163,119,235,157,53,123,207,69,154,25,141,164,245,121,158,253,204,204, - 190,172,181,246,154,153,245,221,239,187,222,181,150,22,8,4,52,167,203,229, - 210,52,77,3,160,1,16,241,120,92,196,99,177,152,16,66,56,157,206,180, - 199,103,206,156,137,43,110,168,94,222,123,182,175,53,60,28,25,68,142,92, - 121,229,149,150,251,175,190,111,241,137,211,187,90,151,179,207,119,158,222,213, - 250,178,124,222,187,239,190,155,107,150,37,79,133,199,227,191,249,154,107,86, - 215,207,159,191,212,229,116,122,187,250,251,187,222,56,123,246,112,219,133,11, - 45,242,185,154,166,137,137,40,163,66,161,80,148,58,46,151,203,85,217,221, - 31,92,216,223,167,207,20,194,112,8,1,67,211,196,224,188,217,174,142,202, - 202,153,195,14,135,211,223,221,31,92,100,117,124,214,172,153,131,0,196,210, - 63,90,178,246,134,123,175,255,204,129,175,253,252,159,143,239,110,126,122,60, - 5,186,250,190,197,143,223,178,126,213,199,14,237,56,82,43,29,250,214,103, - 127,249,167,145,67,59,142,60,125,122,87,235,246,241,228,97,69,195,213,183, - 52,53,159,62,212,100,117,76,211,28,115,133,48,122,210,237,171,156,113,217, - 220,129,161,139,73,231,88,237,35,62,243,71,143,54,253,175,31,63,158,148, - 95,133,215,235,127,100,237,218,191,254,204,237,183,127,222,229,112,204,10,70, - 34,136,198,98,136,197,227,136,25,6,222,104,109,61,242,141,151,94,122,228, - 173,119,222,249,197,24,111,83,161,80,40,166,13,90,203,153,158,15,60,243, - 195,216,39,207,247,198,151,104,48,202,132,208,34,126,79,111,203,167,254,71, - 124,215,77,31,92,218,218,217,53,188,248,91,223,143,221,119,190,55,190,148, - 31,255,228,31,198,118,173,250,224,210,150,138,242,242,232,31,124,165,177,233, - 247,191,112,243,230,200,112,24,221,167,47,190,245,211,199,14,60,212,126,168, - 99,95,54,5,224,22,220,213,247,45,126,251,150,245,171,174,6,128,208,37, - 29,199,119,55,55,159,222,213,186,252,234,251,22,223,121,203,250,85,47,133, - 46,233,0,128,227,187,155,191,118,122,87,235,163,192,168,5,39,122,55,10, - 12,69,128,72,60,125,134,49,3,151,186,131,216,180,245,151,91,158,253,209, - 153,38,218,253,226,147,173,226,195,155,22,107,242,233,245,53,215,61,232,118, - 121,231,181,180,191,209,148,110,223,134,63,105,106,234,120,175,163,251,71,63, - 223,249,116,186,125,118,249,93,57,123,246,130,151,255,246,111,95,189,188,178, - 242,154,222,161,33,12,235,58,162,177,24,12,145,48,208,28,90,226,84,61, - 26,197,183,94,126,249,145,23,254,251,191,159,0,148,5,167,80,40,20,118, - 56,222,235,234,153,213,249,94,255,210,190,224,220,27,251,67,115,87,245,6, - 42,111,124,247,221,238,107,59,59,207,205,140,70,163,206,174,174,238,153,157, - 239,245,95,43,31,63,119,238,221,153,209,104,212,1,0,66,8,24,49,3, - 177,168,129,57,117,179,175,253,248,191,221,243,147,79,61,247,39,251,47,191, - 118,222,242,76,5,32,72,220,66,151,116,132,46,233,232,61,219,219,78,199, - 78,239,106,125,249,208,142,35,95,160,207,43,62,221,240,165,171,239,91,252, - 201,164,4,134,34,136,95,12,33,120,62,128,64,215,176,237,118,233,252,48, - 126,219,49,128,243,189,161,164,203,135,67,67,41,101,186,102,209,117,15,254, - 239,45,63,219,49,28,28,48,247,93,181,224,253,159,149,247,37,234,0,248, - 252,189,143,237,184,233,250,63,252,44,223,183,225,79,254,121,71,227,242,181, - 15,202,105,243,252,42,188,94,255,203,127,251,183,175,206,153,49,227,154,206, - 139,23,113,113,112,16,129,112,24,17,178,222,226,113,68,98,49,68,226,113, - 104,0,238,95,179,230,235,183,46,93,250,185,44,170,85,161,80,40,166,45, - 142,120,44,230,132,136,150,193,208,189,48,116,47,68,212,43,68,180,44,30, - 143,57,13,195,208,226,241,184,229,241,88,60,234,48,12,99,52,37,33,0, - 67,192,136,27,136,199,12,212,172,188,178,241,51,47,220,119,252,143,158,184, - 115,215,140,106,255,130,116,133,24,113,75,94,77,22,154,21,167,119,181,110, - 63,190,187,249,83,108,215,189,73,39,68,226,8,7,163,24,10,70,49,28, - 138,217,110,131,129,24,134,130,81,132,163,70,114,6,72,54,132,174,89,116, - 221,131,63,126,242,87,59,206,188,115,6,209,88,4,0,48,123,230,156,59, - 246,60,126,108,71,107,103,43,34,177,112,210,249,241,56,224,113,123,240,103, - 119,61,178,99,201,162,229,119,0,128,97,0,101,174,50,124,118,237,87,118, - 172,110,144,69,110,52,191,71,214,174,253,235,234,202,202,107,186,250,251,49, - 172,235,136,27,70,162,62,229,18,10,1,104,26,202,220,110,124,116,213,170, - 175,249,189,222,121,182,21,166,80,40,20,211,28,7,18,129,35,99,193,246, - 58,97,8,196,163,6,226,209,56,174,93,187,228,79,31,120,237,115,173,141, - 15,255,254,99,101,254,178,153,54,151,124,44,155,12,79,239,106,253,222,241, - 221,205,95,3,128,21,159,110,248,227,171,239,91,252,66,82,190,35,162,32, - 132,176,221,32,196,136,118,200,2,226,48,223,93,179,232,186,7,95,220,250, - 171,29,191,235,234,70,64,31,130,219,229,65,213,140,57,119,28,124,166,237, - 71,3,67,81,79,255,80,143,153,151,153,247,72,149,204,158,117,185,103,227, - 39,190,254,163,235,175,250,189,59,28,90,98,191,207,235,199,103,215,126,217, - 66,228,18,1,37,159,185,253,246,207,95,28,26,66,32,28,78,73,215,10, - 151,195,129,42,191,191,234,247,234,235,255,60,227,201,10,133,66,49,77,113, - 100,62,101,236,8,33,16,143,198,225,112,57,60,55,254,249,7,191,252,151, - 63,253,92,235,242,79,45,123,208,89,230,244,208,57,87,223,183,184,237,150, - 245,171,106,169,207,237,248,238,230,175,29,223,221,124,186,227,200,59,3,86, - 105,158,222,213,250,232,241,221,205,205,35,31,255,56,95,101,245,151,39,180, - 119,84,220,122,48,24,232,131,191,124,22,174,187,234,131,75,119,53,29,218, - 221,63,20,247,244,13,246,32,110,216,247,243,57,52,7,42,103,204,245,60, - 252,233,111,236,126,223,252,37,75,99,241,40,52,104,166,200,173,89,113,119, - 146,200,221,124,205,53,171,93,14,199,172,161,80,200,236,111,179,131,158,40, - 28,14,7,188,110,55,174,190,242,202,181,227,187,107,133,66,161,152,186,184, - 138,145,137,17,55,160,25,128,119,150,119,238,29,155,255,96,199,202,251,151, - 63,180,255,235,63,255,242,111,247,157,249,33,128,90,30,80,50,114,201,163, - 197,40,23,231,242,217,243,177,120,193,117,15,254,231,215,71,197,205,16,6, - 188,101,62,60,240,145,45,31,243,184,189,200,36,110,0,160,105,26,28,14, - 7,102,85,204,158,59,127,78,205,199,2,161,65,104,154,102,138,220,95,172, - 219,188,99,70,121,37,134,131,137,17,21,245,243,231,47,13,69,34,136,198, - 227,150,110,201,148,244,145,176,10,157,9,43,110,105,30,110,93,161,80,40, - 166,36,69,17,56,96,164,139,46,26,135,17,53,224,246,185,175,106,124,248, - 247,127,48,99,94,69,83,177,242,207,68,60,30,199,55,31,250,241,142,182, - 119,207,33,20,30,6,68,194,2,213,52,13,145,152,142,104,44,12,77,211, - 178,112,33,38,236,172,152,17,197,80,240,82,98,207,72,4,164,16,2,161, - 112,0,247,220,246,23,59,218,222,125,11,0,224,114,58,189,97,22,45,153, - 45,34,145,158,47,167,139,20,10,133,98,26,81,20,129,75,244,201,197,17, - 25,142,32,52,16,66,215,175,207,159,56,190,251,228,166,238,83,61,7,110, - 251,242,234,166,116,215,94,125,223,226,19,35,111,203,1,252,39,128,15,221, - 178,126,85,195,72,64,74,187,237,133,57,210,213,123,14,127,249,248,29,235, - 31,123,240,185,29,126,223,44,56,28,9,239,109,52,22,65,80,31,70,185, - 215,15,183,171,44,163,192,9,97,32,54,114,141,167,204,7,79,153,47,225, - 170,141,199,209,63,212,141,150,182,55,240,243,147,47,173,255,227,91,63,179, - 3,0,222,235,239,239,138,27,70,214,29,161,148,187,30,137,160,103,112,176, - 11,128,245,72,121,133,66,161,152,230,20,182,15,206,0,98,225,24,66,253, - 33,92,58,55,136,142,163,239,188,245,234,63,238,191,247,149,191,121,117,69, - 247,169,158,3,35,167,253,39,0,172,248,116,67,195,213,247,45,126,220,42, - 157,91,214,175,170,188,101,253,170,171,111,89,191,234,75,43,62,221,208,48, - 226,210,108,63,189,171,181,46,95,101,13,71,66,56,223,251,206,211,127,243, - 237,79,175,239,238,59,23,54,12,3,154,166,97,112,184,15,207,60,191,249, - 135,111,181,29,235,137,199,99,166,240,217,220,49,98,241,40,222,237,233,192, - 47,223,250,105,207,47,127,243,218,15,203,92,30,24,134,129,158,254,119,113, - 244,215,175,134,255,243,103,255,182,190,249,183,135,158,94,112,121,162,232,199, - 207,158,61,28,139,199,205,113,110,217,16,139,199,209,63,60,140,223,117,119, - 31,30,231,109,43,20,10,197,148,197,129,212,112,194,108,177,189,78,8,32, - 30,137,67,191,20,194,224,187,36,108,175,223,251,210,151,254,235,186,206,99, - 231,126,200,207,61,189,171,245,238,227,187,155,73,228,82,199,183,141,64,227, - 227,0,160,247,108,47,0,252,208,234,188,177,147,184,157,174,139,191,123,250, - 209,29,31,95,219,211,255,94,56,22,139,34,28,9,161,179,187,181,229,159, - 191,251,249,198,51,239,252,170,39,22,139,217,166,16,141,69,113,174,187,13, - 63,127,243,229,158,239,253,228,27,141,195,161,193,22,143,219,135,11,125,157, - 56,242,235,125,225,31,31,250,238,218,223,157,255,237,211,0,80,238,157,1, - 0,104,187,112,161,229,141,214,214,35,0,0,77,75,184,30,211,148,80,8, - 129,193,80,8,239,246,245,225,55,157,157,207,230,237,246,21,10,133,98,138, - 225,0,16,23,2,145,184,17,215,13,67,232,70,60,174,11,129,8,128,56, - 18,109,170,229,113,13,154,60,144,44,225,138,139,196,161,15,132,112,233,221, - 65,188,123,242,189,206,131,219,14,173,183,18,54,137,31,208,155,21,159,110, - 120,238,234,251,22,111,176,59,177,247,108,47,58,142,188,115,154,102,50,49, - 137,25,136,197,13,68,162,6,162,233,182,120,226,188,116,4,66,131,251,190, - 244,173,143,173,253,221,249,211,131,113,35,14,33,4,98,241,104,75,211,191, - 126,182,177,245,220,175,122,172,130,65,12,195,64,215,197,223,225,208,155,47, - 247,188,122,244,63,26,135,130,151,90,92,78,55,122,6,222,195,161,147,47, - 15,190,114,228,223,215,246,94,186,96,206,238,194,45,182,111,190,244,210,35, - 122,52,10,62,174,144,231,64,162,39,132,192,176,174,163,163,187,27,205,109, - 109,175,190,215,215,247,147,180,55,162,80,40,20,211,24,151,211,17,191,228, - 117,92,108,185,116,233,183,194,128,81,6,129,136,207,31,111,41,115,251,7, - 163,209,104,28,136,13,122,29,189,111,217,28,79,180,200,2,136,199,12,132, - 7,195,8,246,5,209,219,222,215,249,235,61,45,255,220,246,179,246,103,141, - 152,17,206,80,6,156,222,213,250,61,0,55,172,248,116,195,151,0,96,197, - 167,27,190,9,160,149,38,87,14,93,210,107,129,36,113,187,70,78,227,82, - 119,16,191,125,103,16,67,193,104,218,96,196,88,92,224,189,158,16,98,49, - 33,237,79,182,204,2,161,161,125,127,243,237,63,93,245,133,143,63,126,64, - 211,28,35,231,68,91,154,254,255,207,54,126,241,227,95,51,247,153,231,235, - 195,56,242,235,159,244,236,59,250,131,198,128,62,212,2,0,193,240,48,14, - 255,234,191,122,94,60,244,191,27,3,250,96,210,68,201,60,191,223,188,243, - 206,47,190,245,242,203,143,220,191,102,205,215,203,92,46,184,92,46,56,70, - 172,57,96,228,193,193,48,48,24,10,161,163,187,27,199,207,158,61,123,224, - 173,183,238,179,191,75,133,66,161,80,184,230,206,46,59,123,247,173,177,239, - 158,191,48,52,51,30,143,59,52,205,97,204,156,57,99,112,225,149,179,58, - 12,195,208,231,205,246,116,220,125,107,108,151,213,113,97,24,49,0,136,133, - 227,24,58,63,140,238,211,23,7,155,255,253,100,211,153,159,158,125,58,27, - 97,227,140,88,100,239,46,90,181,240,193,142,35,239,148,145,184,141,12,29, - 16,139,86,45,108,239,56,242,206,15,83,44,183,17,30,218,250,203,45,231, - 123,67,136,68,13,100,242,186,70,99,2,237,239,13,29,224,251,46,244,157, - 75,57,47,22,143,182,124,227,251,95,106,172,244,207,105,228,251,182,125,255, - 145,164,125,0,240,187,174,223,118,255,166,237,151,73,66,102,181,207,46,191, - 23,254,251,191,159,232,27,30,30,248,216,170,85,95,171,242,251,171,188,110, - 55,156,14,7,12,0,225,72,4,125,129,0,222,235,237,197,137,182,182,87, - 15,188,245,214,125,122,52,122,62,237,77,42,20,10,197,52,71,235,237,237, - 213,244,112,216,165,235,186,22,143,199,53,77,211,132,203,229,18,62,175,55, - 86,86,86,38,132,16,105,143,207,158,61,27,203,63,121,195,70,1,204,252, - 245,158,183,182,197,244,88,78,75,230,88,45,151,35,47,141,35,47,157,195, - 153,106,203,229,248,189,222,121,191,87,95,255,231,87,95,121,229,218,42,191, - 127,169,16,194,119,113,112,176,171,163,187,251,240,111,58,59,159,149,221,146, - 106,178,101,133,66,161,176,70,123,242,201,39,53,77,211,92,96,235,189,65, - 8,33,132,136,33,97,10,165,61,222,214,214,6,239,76,207,242,72,32,218, - 106,196,141,156,215,131,123,225,133,23,44,247,111,218,182,241,196,147,27,183, - 45,103,159,239,124,114,227,182,148,245,224,62,254,241,143,231,154,101,18,79, - 62,249,228,184,174,95,191,126,253,184,174,183,194,233,112,248,103,251,253,171, - 43,60,158,165,154,166,121,195,209,104,215,64,48,120,56,24,14,167,88,130, - 79,63,253,180,18,56,133,66,161,176,192,165,105,90,101,52,102,44,140,199, - 140,153,34,17,116,98,0,98,208,237,210,58,92,46,215,48,0,127,52,102, - 44,178,57,62,8,64,248,47,247,175,157,57,127,230,103,122,207,246,253,243, - 165,119,47,141,107,61,184,77,219,54,62,142,196,220,148,41,235,193,109,218, - 182,49,2,224,233,39,55,110,203,251,122,112,183,175,249,195,166,215,246,255, - 164,201,234,152,207,231,155,27,10,133,122,210,237,115,187,202,230,70,99,145, - 164,115,172,246,17,53,151,95,213,212,121,225,108,82,126,78,135,195,127,85, - 117,245,95,215,92,118,217,231,53,96,86,92,8,8,195,48,3,76,6,2, - 129,35,237,221,221,143,12,133,66,106,61,56,133,66,161,200,128,75,15,199, - 175,186,56,32,62,25,137,137,37,0,202,0,68,156,142,88,203,156,25,216, - 229,247,187,90,195,145,248,162,158,126,113,95,36,38,150,242,227,179,103,136, - 93,126,191,171,5,64,20,2,112,121,92,53,115,175,158,179,99,214,149,51, - 31,188,216,122,241,161,96,95,40,171,245,224,56,155,182,109,124,27,192,213, - 236,243,137,39,55,110,91,190,105,219,198,59,49,42,120,223,220,180,109,227, - 149,79,110,220,150,212,23,247,225,63,172,19,136,25,128,145,193,160,17,64, - 44,18,71,75,91,255,150,119,206,7,154,104,247,159,126,244,127,110,182,18, - 184,223,91,185,234,193,138,10,255,188,215,15,188,218,148,110,223,130,121,139, - 214,7,245,80,247,133,190,206,167,211,237,35,230,207,89,184,153,11,156,215, - 237,94,240,193,250,250,87,61,110,247,53,145,88,12,113,195,72,204,110,66, - 17,51,154,6,191,207,183,234,218,154,154,67,29,221,221,143,156,31,24,120, - 34,253,141,42,20,10,197,244,198,17,141,69,103,233,209,216,210,136,225,190, - 49,98,184,87,133,227,174,27,245,112,236,218,104,52,58,83,8,225,140,70, - 163,51,245,104,236,90,249,120,44,26,155,41,12,195,12,37,20,66,64,24, - 128,187,220,125,237,21,55,204,255,201,149,13,87,236,247,204,40,203,122,61, - 56,89,220,192,102,41,25,113,77,126,129,29,251,210,166,109,27,147,199,203, - 197,12,136,136,129,120,56,158,118,139,133,99,8,4,163,8,71,146,135,10, - 196,226,169,115,76,174,250,224,170,7,191,248,63,191,188,35,22,143,154,251, - 62,176,124,229,103,229,125,64,194,151,187,232,138,171,119,84,205,152,251,89, - 190,175,246,138,107,118,204,153,117,121,202,42,2,60,63,167,195,225,255,96, - 125,253,171,101,46,215,53,161,72,4,36,112,194,48,70,87,66,24,121,15, - 0,11,230,204,249,250,108,191,95,173,7,167,80,40,20,105,112,64,192,9, - 33,202,32,12,47,132,225,5,132,87,64,148,9,8,167,16,66,3,108,143, - 91,79,233,49,178,28,141,175,210,219,88,243,129,5,199,47,95,58,111,151, - 203,227,76,187,30,220,136,91,242,234,116,231,140,184,37,237,215,131,27,89, - 139,46,22,23,89,108,6,140,20,75,47,249,243,170,15,174,122,112,211,3, - 127,191,99,56,20,128,24,57,247,170,218,171,238,120,232,129,191,217,17,8, - 5,32,140,100,129,20,2,112,104,78,212,92,126,213,14,191,111,214,29,148, - 164,67,115,160,230,242,122,11,145,27,205,239,170,234,234,191,246,184,221,215, - 232,209,232,232,90,112,118,235,193,33,177,154,192,252,170,170,175,57,29,14, - 181,30,156,66,161,80,216,80,144,245,224,32,4,132,145,16,186,25,151,251, - 255,244,125,55,46,108,157,83,55,251,49,135,211,49,174,245,224,158,220,184, - 237,123,0,190,54,242,241,143,55,109,219,104,29,161,50,58,52,58,117,19, - 118,131,8,70,111,103,213,7,87,61,184,233,47,255,126,71,40,28,70,220, - 136,65,115,56,80,87,123,213,29,255,244,229,39,127,100,24,154,39,26,139, - 216,14,68,112,187,60,158,186,43,151,252,104,70,121,229,29,84,18,167,195, - 137,154,203,23,91,90,114,78,135,195,95,115,217,101,159,39,171,45,219,21, - 5,220,46,87,85,85,69,133,90,15,78,161,80,40,108,40,232,92,148,36, - 116,208,52,79,213,251,42,191,252,190,85,53,173,179,174,156,249,160,230,208, - 204,245,224,54,109,219,216,134,209,254,181,102,36,4,236,52,0,203,245,224, - 70,250,222,242,190,30,156,203,153,152,119,218,20,55,61,140,88,60,10,151, - 211,133,247,45,168,93,250,200,250,205,187,13,225,24,17,183,244,34,228,118, - 149,121,174,90,112,237,238,114,175,127,169,16,9,75,207,233,112,141,136,92, - 117,146,200,205,246,251,87,107,192,172,184,133,139,84,134,36,88,211,52,56, - 53,13,21,94,175,90,15,78,161,80,40,108,40,206,114,57,34,33,9,14, - 151,115,238,220,247,95,182,163,178,102,214,67,23,207,246,125,57,208,19,248, - 33,152,184,177,97,1,69,95,15,174,172,204,139,223,91,153,112,75,146,184, - 9,33,224,208,156,248,131,91,238,252,152,67,115,34,18,141,100,92,77,32, - 177,164,14,224,114,150,205,245,184,125,31,139,27,49,115,153,29,167,195,133, - 247,85,191,127,135,203,233,54,103,50,169,240,120,150,26,66,192,0,114,90, - 15,78,211,52,148,185,92,106,61,56,133,66,161,176,161,104,235,193,37,92, - 131,2,34,46,160,57,28,87,205,169,155,253,3,87,153,179,169,104,249,103, - 66,8,60,120,255,195,59,2,122,8,134,17,79,242,99,26,134,1,3,134, - 185,174,91,118,201,141,206,121,57,122,157,64,220,136,97,254,101,11,119,4, - 245,33,58,230,53,88,0,73,214,233,39,54,181,30,156,66,161,80,216,80, - 156,245,224,0,51,8,36,30,53,16,30,210,79,12,156,27,220,20,25,142, - 28,184,108,241,156,166,116,215,110,218,182,49,101,61,56,0,13,35,251,242, - 182,30,156,30,9,97,199,255,250,218,250,63,191,239,139,59,18,238,74,90, - 164,212,64,220,136,195,233,112,34,155,197,23,18,81,143,137,107,28,14,7, - 28,154,51,177,15,2,209,88,4,195,193,1,244,93,234,94,127,249,156,154, - 29,0,160,71,163,93,2,163,150,89,38,232,28,195,48,16,137,70,213,122, - 112,10,133,66,97,67,97,215,131,67,98,177,83,35,26,71,84,143,33,216, - 31,122,235,226,153,139,247,118,191,125,113,69,100,56,114,96,228,180,255,28, - 121,109,24,137,166,180,162,18,137,40,203,47,129,137,219,147,27,183,229,109, - 61,56,195,48,240,198,137,99,79,255,203,174,111,174,15,134,130,97,146,146, - 88,60,138,159,254,252,229,31,118,247,157,239,73,56,90,211,91,113,2,2, - 122,36,132,129,161,139,61,3,67,23,127,152,88,63,78,32,18,209,49,48, - 216,19,62,223,219,185,254,82,160,239,105,175,167,28,0,112,41,24,60,44, - 132,0,114,178,14,5,162,241,56,66,145,136,90,15,78,161,80,40,108,40, - 204,122,112,72,52,194,70,212,72,22,182,83,61,215,133,6,244,164,101,115, - 158,220,184,237,110,140,138,92,234,248,54,123,10,178,30,220,27,39,254,251, - 233,39,159,254,135,181,33,61,24,78,204,226,31,199,123,231,59,91,158,216, - 254,143,141,189,189,221,61,233,92,137,66,24,208,195,65,244,13,118,247,188, - 219,211,214,24,139,199,90,28,154,19,225,136,142,254,161,158,240,133,190,115, - 107,67,225,192,211,64,34,232,4,0,130,225,112,203,64,32,144,245,122,112, - 64,98,12,157,30,137,96,40,20,82,235,193,41,20,10,133,13,14,36,214, - 125,139,8,64,7,160,67,8,29,210,122,112,54,199,83,23,85,27,25,148, - 76,194,166,15,234,157,125,237,125,235,173,132,77,226,7,236,253,115,155,182, - 109,180,93,15,110,132,211,242,76,38,16,228,30,76,12,56,183,219,140,145, - 113,122,233,104,239,104,223,247,196,142,127,88,123,105,168,111,144,2,100,122, - 251,122,91,30,127,170,169,177,183,191,219,114,234,45,136,132,229,214,55,216, - 221,211,211,255,94,99,44,30,107,209,52,13,145,168,142,190,193,238,193,238, - 254,247,214,70,98,97,115,118,23,110,175,181,119,119,63,34,247,195,89,173, - 7,7,0,49,195,64,48,18,193,165,96,240,85,61,26,85,235,193,41,20, - 10,133,13,14,64,92,114,104,177,22,196,134,142,138,216,224,17,196,134,142, - 58,29,198,91,154,166,13,10,33,226,128,24,116,104,177,183,108,142,179,21, - 58,5,140,152,129,24,9,91,91,223,250,243,111,93,168,15,92,12,102,156, - 155,82,26,223,6,36,166,227,186,147,125,230,243,82,158,126,114,227,182,148, - 245,224,98,145,56,2,161,24,2,161,40,134,117,251,45,160,199,160,71,226, - 137,105,176,24,178,101,214,222,209,190,239,255,123,242,111,87,245,93,234,237, - 33,49,234,237,237,109,121,124,123,83,99,223,192,197,30,217,161,24,51,226, - 232,31,234,233,233,233,127,175,49,110,196,90,0,32,110,196,209,55,212,211, - 115,161,239,220,170,40,19,55,57,191,161,80,232,23,29,221,221,143,196,226, - 137,114,153,235,192,97,84,216,132,16,136,198,98,8,232,58,46,5,2,103, - 123,135,134,212,122,112,10,133,66,145,6,151,203,165,157,157,237,199,119,163, - 177,248,76,8,56,160,193,112,58,28,131,110,151,163,3,128,238,114,106,29, - 179,253,216,101,117,124,100,69,1,24,134,64,44,28,67,56,16,25,28,124, - 119,176,105,248,98,224,105,8,228,180,30,220,147,27,183,61,186,105,219,198, - 119,1,60,8,160,140,86,14,24,153,139,82,32,17,80,242,195,20,203,109, - 132,150,182,254,45,122,196,48,103,29,73,135,33,4,130,122,252,0,223,23, - 142,234,41,231,245,246,245,182,108,219,241,213,198,247,189,175,182,209,220,215, - 155,186,15,0,66,122,160,123,40,216,111,138,155,221,62,187,252,206,15,12, - 60,17,137,197,6,174,168,170,250,154,219,229,170,114,104,90,98,120,1,18, - 253,131,209,17,183,228,165,96,240,213,222,161,161,251,12,33,212,122,112,10, - 133,66,145,6,87,153,219,61,224,118,185,134,13,195,163,9,33,52,104,154, - 208,52,77,56,52,45,166,105,154,112,187,221,131,46,151,171,197,234,184,195, - 225,16,0,16,15,199,46,245,181,247,55,13,118,13,109,19,134,200,121,201, - 28,98,100,58,174,237,146,245,6,36,143,145,179,132,79,156,60,22,214,63, - 252,255,90,70,121,244,246,245,182,244,246,245,182,100,218,215,55,120,33,197, - 82,181,218,71,180,180,191,145,146,95,223,240,240,191,94,10,6,127,84,85, - 81,241,231,21,94,239,218,50,151,107,169,0,124,145,104,180,43,20,137,28, - 30,10,133,158,85,110,73,133,66,161,200,14,237,141,55,222,200,104,242,144, - 59,141,198,115,37,34,3,19,175,46,87,98,169,56,135,195,97,190,202,238, - 62,33,4,12,195,64,60,30,135,166,105,136,199,227,48,216,68,194,134,52, - 175,99,46,227,205,172,160,89,65,156,78,167,101,57,248,107,60,30,79,42, - 143,92,22,42,143,195,225,128,211,233,52,223,211,198,239,93,8,97,214,141, - 156,239,120,238,171,148,235,255,134,27,110,128,54,98,109,2,35,99,6,13, - 195,172,15,158,30,47,103,182,80,89,191,250,213,175,226,213,87,95,69,121, - 121,57,226,241,184,249,221,166,123,79,247,30,139,37,6,213,59,157,137,33, - 27,154,166,193,237,118,39,93,227,116,58,225,247,251,113,243,205,55,99,253, - 250,245,230,61,21,250,190,52,77,195,111,126,253,102,214,215,41,10,143,166, - 105,88,214,176,34,237,57,39,155,143,99,249,242,15,104,64,154,217,255,0, - 104,212,221,174,22,38,158,16,178,30,7,199,27,118,167,211,9,151,203,101, - 190,242,198,159,99,6,125,176,6,150,26,28,18,23,106,56,198,50,216,89, - 134,242,161,178,114,120,62,177,88,204,220,34,145,8,226,241,56,98,177,152, - 41,118,116,191,118,247,237,118,187,147,234,192,233,116,154,231,80,254,188,46, - 168,81,164,198,117,44,148,106,253,135,195,97,188,253,246,219,99,186,167,92, - 89,179,102,13,238,190,251,238,130,231,35,132,64,36,18,193,233,211,167,147, - 30,38,56,242,195,19,144,252,155,161,239,139,30,30,120,61,211,103,33,4, - 222,121,231,29,44,172,81,67,25,75,137,108,196,237,216,177,99,0,40,182, - 205,254,127,163,105,154,208,50,141,45,82,20,140,172,4,142,26,80,167,211, - 9,183,219,13,183,219,157,212,208,203,79,175,220,42,160,70,149,26,126,249, - 149,172,10,122,207,127,44,86,98,97,7,53,24,114,89,100,97,139,68,34, - 136,70,163,8,135,195,8,135,195,136,70,163,136,70,163,102,99,15,88,139, - 27,175,3,151,203,5,151,203,133,178,178,178,148,186,224,86,20,47,59,189, - 142,197,154,43,229,250,39,75,104,170,225,118,187,205,122,181,18,46,194,225, - 112,160,172,172,204,124,136,161,58,35,156,78,39,12,195,48,95,185,229,102, - 24,6,142,30,61,138,133,53,247,20,253,254,20,217,113,178,249,120,210,231, - 185,243,170,83,196,237,224,193,211,182,215,63,249,228,143,176,105,211,90,161, - 20,110,98,176,21,56,106,160,201,13,70,13,58,109,86,13,0,255,243,82, - 26,114,122,114,99,73,98,64,141,134,108,77,240,52,236,26,90,178,82,228, - 167,106,89,216,34,145,8,116,93,71,40,20,66,40,20,74,18,54,186,158, - 238,201,78,56,72,4,104,139,199,227,112,187,221,48,12,195,20,30,186,47, - 126,223,153,238,97,178,214,191,149,75,182,80,100,51,33,117,62,224,238,73, - 126,207,244,93,240,135,30,250,204,221,151,84,78,122,200,112,185,92,48,12, - 195,188,134,60,5,154,166,161,187,187,187,40,247,52,93,161,255,189,97,8, - 132,195,97,68,162,17,24,134,145,120,31,14,99,254,252,43,48,107,214,76, - 203,223,177,44,110,0,208,211,173,98,187,38,19,41,2,199,45,12,114,131, - 149,149,149,193,227,241,192,227,241,152,141,43,253,249,185,171,139,247,103,113, - 203,1,24,253,179,115,113,176,202,151,224,233,83,227,108,231,226,163,198,67, - 222,71,110,72,178,214,2,129,0,130,193,32,66,161,80,146,24,200,150,145, - 220,136,81,121,228,50,114,177,227,125,90,101,101,101,230,123,110,205,101,195, - 100,171,127,171,62,203,66,97,229,22,44,4,178,59,153,190,11,222,223,201, - 221,195,64,178,208,187,92,174,36,87,48,61,60,201,191,83,171,223,173,34, - 123,50,137,23,183,152,169,255,85,126,239,245,122,224,243,249,16,14,231,20, - 244,109,201,234,213,163,75,90,166,179,234,20,197,35,73,224,228,198,213,229, - 114,193,227,241,192,235,245,194,235,245,162,172,172,204,180,108,168,97,37,17, - 137,70,163,73,253,88,188,191,193,10,202,139,91,12,242,53,188,33,182,19, - 9,238,98,35,184,184,233,186,142,64,32,128,225,225,97,4,131,65,232,186, - 110,230,225,118,187,77,225,224,226,65,238,64,106,80,121,25,228,178,242,39, - 247,88,44,6,135,195,129,72,36,98,166,195,239,69,182,6,173,250,204,38, - 91,253,143,55,32,168,84,225,226,70,15,62,36,110,86,214,179,124,13,144, - 16,100,250,78,184,101,205,3,129,42,42,42,138,121,91,147,134,132,135,37, - 17,28,20,12,6,17,141,69,205,247,177,104,52,233,193,206,78,188,232,63, - 92,54,242,31,162,255,148,215,227,29,57,230,192,226,197,139,225,112,56,208, - 217,217,57,238,50,111,221,250,99,243,253,138,21,239,31,119,122,138,241,147, - 98,193,241,198,149,26,86,159,207,7,143,199,99,254,169,169,97,141,68,34, - 102,63,22,5,107,100,106,92,201,98,162,247,178,120,112,75,8,72,126,50, - 182,235,191,146,159,138,169,193,15,133,66,8,4,2,24,26,26,194,240,240, - 48,162,35,127,12,186,183,242,242,114,148,151,151,155,2,71,22,147,236,154, - 228,238,59,94,78,186,95,238,230,228,17,156,178,245,38,91,5,86,162,49, - 222,250,151,131,25,56,148,95,190,235,191,88,20,211,69,73,175,220,82,227, - 253,109,118,129,68,242,62,250,77,69,34,145,36,107,223,202,162,155,14,144, - 71,37,62,178,210,134,157,120,69,163,137,125,110,183,219,246,125,38,241,242, - 122,189,25,173,254,124,214,191,18,181,210,35,73,224,184,251,133,26,86,222, - 184,146,149,18,14,135,161,235,58,116,93,71,36,18,49,5,69,14,63,151, - 211,37,87,13,53,84,92,72,248,159,159,7,123,240,247,86,141,8,255,1, - 147,232,144,229,54,60,60,140,193,193,65,12,15,15,35,22,75,172,203,230, - 241,120,80,81,81,1,191,223,143,138,138,138,36,203,141,238,157,242,227,200, - 209,111,114,20,34,119,71,1,201,150,165,44,18,242,147,254,120,235,159,238, - 217,170,238,121,221,81,131,202,93,112,227,173,127,57,175,66,82,76,23,37, - 128,36,55,53,89,207,0,82,4,78,22,59,217,234,37,43,144,26,103,234, - 179,227,94,130,169,0,23,175,120,60,14,61,172,39,121,82,226,35,191,209, - 120,60,110,254,206,237,196,171,172,172,12,46,183,27,229,229,137,73,201,221, - 46,246,222,237,130,207,87,122,43,69,41,23,101,233,145,36,112,244,71,246, - 120,18,126,105,178,110,232,15,25,139,197,204,0,13,93,215,77,235,129,55, - 174,86,145,119,178,171,139,242,178,122,130,165,235,72,144,168,209,231,125,97, - 118,24,134,97,90,110,67,67,67,184,116,233,18,2,129,0,162,209,40,28, - 14,7,124,62,31,102,204,152,129,153,51,103,194,231,243,153,110,63,171,190, - 20,185,225,150,173,49,254,20,46,71,201,241,123,165,58,201,166,252,185,214, - 63,183,154,229,7,138,116,1,33,188,63,78,238,91,28,79,253,79,53,168, - 255,147,30,126,128,244,226,38,255,230,249,195,4,53,232,244,93,209,185,126, - 191,191,200,119,53,54,178,233,239,226,226,69,158,6,249,61,89,196,101,35, - 94,19,96,114,136,87,54,40,23,101,233,225,146,251,125,220,110,119,82,159, - 15,61,197,71,34,17,179,113,13,6,131,166,184,113,171,141,176,122,170,167, - 232,66,222,168,242,188,173,68,145,26,98,30,38,79,141,133,12,89,49,20, - 76,50,52,52,132,64,32,128,88,44,6,167,211,137,242,242,114,204,156,57, - 19,51,103,206,76,178,220,172,26,111,187,96,10,110,197,240,232,67,222,231, - 66,66,103,135,44,40,99,169,255,80,40,100,138,155,157,176,217,185,113,101, - 241,229,101,26,75,253,23,83,240,138,229,162,228,222,6,122,248,145,173,113, - 121,64,125,186,190,56,170,95,30,77,201,163,42,39,154,124,4,107,144,75, - 158,139,151,195,225,128,215,227,29,121,64,208,204,8,224,169,130,6,104,154, - 166,9,33,18,67,5,100,81,59,126,252,183,216,180,105,45,13,246,86,3, - 189,39,0,23,144,220,184,242,160,11,250,243,81,227,26,8,4,16,8,4, - 76,113,227,65,23,68,58,203,129,31,167,6,213,202,226,163,134,36,26,141, - 38,141,25,162,70,71,110,140,233,15,72,195,0,130,193,160,41,110,154,166, - 161,188,188,28,179,102,205,194,172,89,179,80,81,81,1,159,207,151,210,112, - 17,114,163,207,177,18,110,46,206,212,248,203,117,194,207,179,10,218,200,165, - 254,131,193,160,249,96,33,91,17,86,247,67,245,207,243,230,174,76,46,116, - 220,29,153,109,253,23,83,224,104,70,146,66,67,150,22,31,196,47,215,175, - 213,111,150,195,31,26,232,149,2,84,200,157,109,103,105,231,19,187,96,141, - 92,197,43,31,253,93,83,17,18,185,193,193,65,156,56,241,158,185,95,18, - 55,197,4,97,10,156,28,142,78,79,168,60,88,35,16,8,64,215,117,179, - 225,3,146,27,69,59,184,123,207,42,80,193,202,10,225,141,50,239,23,162, - 113,68,100,17,82,25,200,122,35,113,35,183,164,215,235,69,101,101,37,102, - 206,156,9,191,223,159,36,110,148,158,85,25,56,188,145,167,227,86,193,35, - 178,117,39,91,73,252,254,228,99,217,212,63,23,55,158,22,93,111,215,248, - 114,107,67,182,30,101,177,163,116,179,173,255,98,10,92,127,127,127,209,242, - 162,58,229,22,186,213,189,202,86,26,255,77,88,65,214,48,213,247,88,45, - 154,241,6,107,112,81,83,226,53,62,52,64,155,57,115,166,41,114,74,220, - 74,7,23,253,145,105,28,24,159,145,67,22,13,26,28,109,213,112,19,242, - 126,121,192,179,93,99,97,101,193,81,39,52,127,114,215,180,68,135,61,183, - 0,169,239,141,202,26,14,135,33,132,128,199,227,193,140,25,51,224,247,251, - 77,113,227,99,200,120,121,229,114,240,126,42,126,204,106,63,125,150,93,174, - 92,36,120,158,220,133,153,109,253,7,131,65,211,45,201,45,10,218,172,44, - 12,94,22,30,166,206,69,141,223,19,63,150,109,253,23,83,224,186,186,186, - 138,146,15,221,23,127,136,146,93,137,178,23,129,234,95,246,0,200,22,187, - 252,255,176,18,142,98,5,107,40,241,202,31,92,228,26,27,175,81,226,86, - 34,184,184,123,140,119,168,203,226,22,14,135,83,34,5,1,235,208,113,43, - 11,40,93,95,131,149,216,113,145,163,63,55,29,227,13,59,183,222,40,248, - 34,30,143,163,172,172,12,229,229,229,166,192,209,48,0,158,190,149,21,102, - 231,114,149,239,91,118,55,90,221,147,188,201,195,25,40,207,76,245,79,150, - 27,213,35,183,46,248,103,57,31,126,159,220,106,224,150,153,124,47,252,123, - 205,166,254,139,41,112,161,80,168,40,249,112,151,34,145,238,62,229,135,10, - 187,223,3,63,151,231,101,69,44,150,28,161,75,86,123,124,228,253,84,14, - 214,152,172,144,200,41,113,43,29,163,201,249,178,0,0,32,0,73,68,65, - 84,92,212,80,145,107,130,71,3,82,56,58,31,99,101,247,231,181,18,11, - 32,209,144,211,204,14,86,214,27,255,195,147,96,241,70,148,26,110,33,70, - 103,133,231,141,43,31,247,70,125,131,154,150,232,208,246,251,253,40,47,47, - 55,159,82,229,6,89,46,175,236,106,180,123,250,230,200,65,27,84,38,57, - 48,193,202,122,229,129,6,233,234,159,172,102,186,150,238,133,234,134,207,129, - 105,213,15,71,245,202,203,41,7,205,240,1,235,124,95,166,250,47,166,192, - 21,115,152,64,186,7,178,116,125,144,86,191,41,249,56,191,198,106,46,79, - 135,195,129,138,138,209,241,153,241,120,220,12,138,138,197,98,230,131,16,141, - 173,3,96,122,45,232,119,147,46,208,73,145,39,44,86,8,24,249,102,85, - 64,73,137,224,162,198,149,207,188,65,81,123,52,214,138,34,20,51,61,153, - 90,33,91,19,242,181,114,31,6,111,88,184,200,209,159,151,4,147,139,1, - 159,142,75,8,1,247,136,75,134,54,122,218,149,243,74,247,36,45,91,103, - 86,86,107,186,243,100,107,143,143,161,226,110,192,76,245,79,247,100,37,252, - 252,53,147,155,82,238,23,228,110,75,222,159,202,39,7,230,46,48,187,250, - 183,179,64,38,51,178,181,158,233,92,217,245,104,247,48,100,117,109,101,101, - 101,202,126,30,181,42,91,203,252,119,66,191,105,218,47,187,163,157,78,167, - 41,118,154,166,37,9,31,77,87,167,80,76,101,92,124,90,42,110,17,145, - 96,208,64,238,76,79,132,242,31,156,224,22,141,140,157,219,134,239,227,127, - 112,18,217,72,36,98,54,178,188,255,141,34,11,201,61,73,125,110,212,80, - 200,101,181,42,139,236,198,227,247,96,39,130,118,159,229,8,81,122,207,35, - 17,51,213,63,175,123,94,23,178,184,201,27,207,143,139,46,191,15,46,110, - 178,216,91,165,105,85,255,197,164,88,13,50,213,79,58,215,186,92,95,86, - 191,95,187,242,242,223,9,185,20,173,206,161,240,125,59,72,216,40,80,133, - 30,148,232,61,48,58,116,133,127,95,46,151,11,51,102,204,48,223,219,137, - 32,173,188,49,21,31,98,20,211,3,23,128,164,168,66,106,96,185,176,145, - 112,240,198,95,198,238,15,207,221,92,116,158,108,97,216,65,141,56,159,177, - 157,250,147,168,108,36,112,52,38,140,102,1,241,122,189,150,226,150,238,233, - 90,14,16,160,247,92,220,101,215,37,127,149,211,226,238,64,121,214,10,238, - 46,181,171,127,62,153,179,28,174,158,78,232,172,250,143,100,225,150,235,129, - 207,114,66,175,188,113,180,171,255,98,90,1,197,116,81,202,3,246,237,196, - 78,118,81,203,81,185,86,15,65,114,80,207,120,202,153,73,4,129,68,189, - 81,127,156,195,225,128,199,227,49,203,202,215,52,148,69,144,234,128,34,103, - 233,187,230,129,71,74,4,21,165,140,139,143,7,3,70,103,3,161,77,142, - 26,148,69,201,78,240,8,171,70,201,170,31,204,238,184,220,112,83,227,79, - 51,246,243,197,74,133,16,102,168,61,13,42,181,138,126,203,182,236,252,28, - 185,33,146,133,206,234,15,206,35,23,185,69,202,211,77,87,255,124,188,148, - 92,23,217,136,156,220,159,104,231,146,148,239,85,22,184,116,245,63,21,251, - 122,248,195,137,188,79,182,138,185,229,15,32,229,97,144,31,163,126,204,76, - 115,134,230,155,120,60,142,225,225,225,180,231,216,137,32,121,68,248,131,19, - 69,209,114,183,55,253,174,85,191,160,162,148,48,199,193,1,201,115,57,242, - 126,55,171,62,39,171,126,44,14,23,134,116,253,112,50,86,174,30,46,0, - 212,128,240,160,23,106,40,120,127,22,23,14,89,228,100,43,70,238,155,147, - 207,149,3,52,172,26,62,187,58,224,240,9,152,101,87,34,144,90,255,220, - 58,178,10,84,33,23,167,149,200,201,117,109,39,212,220,141,74,117,197,7, - 145,203,209,146,114,253,23,147,98,247,25,113,203,141,91,226,217,94,103,245, - 191,177,90,79,176,20,200,70,4,73,248,200,35,67,209,155,36,130,64,230, - 126,65,77,211,148,8,42,138,134,139,63,129,82,3,43,139,27,63,39,147, - 245,37,239,151,197,77,118,79,166,75,143,159,195,163,249,184,91,82,30,132, - 44,11,28,149,155,167,105,231,98,148,239,211,202,74,203,198,114,227,200,79, - 233,148,135,28,213,41,215,191,157,184,201,150,91,58,151,37,191,95,187,134, - 131,63,137,243,250,226,34,156,174,254,51,61,176,228,147,98,185,40,185,152, - 203,15,71,86,86,47,189,242,239,210,234,119,145,152,14,107,212,114,35,23, - 227,100,193,48,140,164,161,26,67,67,67,41,231,100,234,23,36,175,69,182, - 34,40,247,11,170,224,24,69,46,184,228,70,157,55,176,86,22,154,236,146, - 177,130,174,147,103,230,183,235,127,147,223,203,2,35,55,50,124,92,16,135, - 4,142,139,27,47,143,149,107,73,46,55,47,3,119,237,241,115,50,89,109, - 178,101,200,211,149,251,198,50,213,191,108,229,89,185,32,185,200,201,67,8, - 128,100,87,169,85,89,185,91,146,231,195,31,28,236,234,127,170,246,189,144, - 59,145,238,157,71,140,198,98,49,219,0,27,43,171,141,210,146,127,83,197, - 114,81,22,19,18,237,241,4,199,112,17,164,190,65,58,166,130,99,20,185, - 224,226,127,48,190,26,52,33,91,63,86,239,173,206,145,45,55,43,151,156, - 44,124,114,26,244,84,199,27,94,190,82,53,205,53,201,251,142,248,154,110, - 60,109,249,73,219,238,190,100,171,78,118,131,202,247,75,231,80,58,220,234, - 149,133,144,187,91,73,188,210,213,63,63,143,215,41,191,47,43,161,227,174, - 74,185,30,121,249,173,174,229,229,226,101,181,171,255,98,82,236,40,74,46, - 112,242,67,0,89,175,178,213,43,63,212,80,61,201,150,27,109,52,235,200, - 116,98,44,34,88,168,224,24,197,212,198,5,32,169,81,149,173,21,59,23, - 148,220,119,197,145,45,12,222,216,202,110,38,222,32,200,1,24,178,69,97, - 247,68,198,27,26,238,246,147,133,140,55,240,178,184,200,105,91,61,109,219, - 185,54,9,171,229,65,236,92,88,188,124,233,234,223,42,114,207,206,34,230, - 251,73,232,120,195,155,110,227,105,203,105,165,171,255,98,186,40,139,53,51, - 7,15,158,224,227,63,169,97,149,221,212,28,249,123,230,226,198,69,143,182, - 112,56,92,148,123,154,108,100,35,130,192,248,131,99,252,254,10,4,131,193, - 98,220,146,98,2,48,253,44,217,244,39,241,31,6,185,15,248,194,158,4, - 125,230,253,76,178,203,82,182,164,100,113,227,105,1,214,171,105,91,149,47, - 91,184,101,104,39,110,220,90,225,174,74,249,41,158,246,17,242,50,54,114, - 157,164,203,51,29,233,92,187,86,216,53,196,114,58,60,45,171,114,3,246, - 245,95,76,55,208,85,87,93,85,148,124,120,148,41,144,252,64,18,143,199, - 147,214,135,179,114,49,242,135,22,217,98,227,245,103,245,59,81,228,198,120, - 131,99,18,115,215,78,158,126,80,69,110,184,128,228,177,57,118,253,2,244, - 20,36,15,12,182,179,32,248,198,231,73,228,233,241,87,121,191,140,236,38, - 228,215,103,51,235,59,165,97,117,76,182,242,120,99,206,95,169,126,236,44, - 43,126,92,70,118,3,90,221,27,93,111,87,255,114,217,237,26,71,234,151, - 72,103,101,240,116,173,176,43,163,92,255,197,100,205,154,53,69,201,39,26, - 141,154,79,251,116,191,209,104,52,105,9,25,57,200,135,224,214,154,149,184, - 201,30,1,37,112,133,39,155,224,24,43,230,206,171,70,79,247,249,164,125, - 199,142,29,203,107,217,20,133,197,69,79,146,86,13,47,239,139,225,226,38, - 207,196,1,164,10,150,221,152,172,76,88,137,144,252,52,204,251,183,120,159, - 147,149,0,200,46,66,185,81,225,13,16,125,166,60,173,172,56,94,38,126, - 62,79,79,126,79,101,228,117,69,27,5,108,88,213,191,236,114,228,81,102, - 86,245,70,229,164,62,55,110,149,201,141,173,157,248,241,188,101,23,170,85, - 253,127,245,171,95,181,188,190,16,220,117,215,93,73,223,121,182,200,223,159, - 236,34,230,46,116,94,63,135,14,29,194,175,126,245,43,0,163,129,16,52, - 67,14,173,182,78,139,210,2,201,174,71,234,123,163,48,120,90,211,143,230, - 118,165,89,130,6,6,6,176,166,241,214,124,86,147,34,15,156,108,62,174, - 196,108,10,224,146,27,116,171,144,118,238,82,148,133,204,174,255,70,126,186, - 229,13,38,191,198,174,81,151,159,122,249,248,48,121,230,124,18,90,222,248, - 90,89,82,86,226,99,231,42,148,69,33,147,229,194,243,150,133,137,94,121, - 191,24,207,203,170,254,229,114,81,120,186,108,153,201,194,38,151,135,127,150, - 173,67,171,114,88,157,159,174,254,183,108,217,98,89,31,133,160,152,121,21, - 147,166,205,127,55,209,69,80,48,178,17,183,149,43,87,22,169,52,138,241, - 224,18,66,36,69,195,241,167,91,59,107,193,170,33,231,215,200,1,37,118, - 253,107,252,90,249,169,90,182,30,248,204,30,148,54,239,60,166,232,41,178, - 94,120,195,207,163,223,172,68,142,191,183,18,55,187,107,120,122,118,194,71, - 226,203,231,155,148,45,41,187,250,183,66,190,47,110,213,113,17,182,18,188, - 116,46,50,59,171,142,44,124,187,250,87,140,159,21,31,248,224,68,23,65, - 161,152,146,184,228,193,210,188,193,228,110,73,89,156,172,250,220,128,228,225, - 1,244,74,110,32,190,159,210,180,219,71,101,33,87,15,133,245,90,245,127, - 80,152,176,85,95,7,119,253,201,125,83,60,79,217,26,146,143,217,93,39, - 127,150,173,55,30,202,76,174,84,110,93,102,170,127,43,107,205,106,227,226, - 198,3,127,236,44,62,59,119,37,23,62,62,232,223,174,254,21,10,133,162, - 84,113,81,163,70,99,202,128,212,240,116,43,87,37,63,102,103,201,89,185, - 49,173,44,63,158,54,143,212,228,226,70,171,5,0,72,18,12,77,27,93, - 48,148,247,63,201,17,108,178,165,104,231,158,75,231,182,179,67,190,94,22, - 57,171,153,85,168,140,233,234,159,238,129,139,20,23,109,126,191,28,222,239, - 41,151,211,170,47,142,111,188,12,92,220,236,234,95,161,80,40,74,21,23, - 53,100,64,242,88,39,217,138,176,106,236,51,9,159,108,249,164,115,187,241, - 107,184,27,45,26,141,154,235,162,197,98,177,164,129,157,188,95,203,229,114, - 153,174,62,121,92,153,28,241,104,229,138,163,207,178,11,82,190,223,116,245, - 32,239,115,58,157,230,164,207,20,90,206,195,196,185,165,4,164,214,63,127, - 181,114,75,90,185,39,233,92,59,129,147,173,62,94,215,84,95,60,140,61, - 83,253,43,20,10,69,169,226,162,6,141,55,134,60,20,158,250,136,236,172, - 51,194,42,152,196,202,45,105,39,6,4,119,221,81,228,89,48,24,52,167, - 222,113,185,92,40,43,43,75,114,249,145,5,199,87,21,224,86,145,28,161, - 104,231,106,148,45,161,116,235,121,89,221,7,23,22,42,39,173,202,204,199, - 77,145,120,240,136,59,187,250,167,243,105,33,82,185,15,143,71,182,202,67, - 24,228,233,202,228,244,101,139,142,247,205,81,4,96,166,250,87,40,20,138, - 82,197,37,55,116,128,189,37,99,231,178,179,106,236,229,192,14,171,52,210, - 89,24,180,136,41,133,86,71,163,81,56,28,142,164,229,112,228,126,184,178, - 178,50,68,34,17,179,31,202,202,69,73,249,90,185,38,229,254,42,26,200, - 206,207,177,187,95,218,79,86,37,77,51,228,241,120,146,22,103,37,225,165, - 25,46,50,213,191,188,207,106,168,0,239,119,227,211,109,89,9,180,44,140, - 242,184,45,18,95,90,112,53,83,253,43,20,10,69,169,226,2,70,3,29, - 248,212,78,220,154,225,98,37,91,27,118,253,113,28,46,110,118,253,113,244, - 153,139,91,48,24,196,208,208,16,66,161,16,12,195,176,20,55,32,97,189, - 208,192,92,94,118,62,198,143,91,147,178,128,88,137,137,124,140,95,107,135, - 44,182,30,143,7,94,175,215,156,56,150,196,141,175,132,144,77,253,243,178, - 112,55,37,47,139,221,20,101,86,214,177,85,95,28,183,38,169,207,45,219, - 250,87,40,20,138,82,196,156,201,68,126,181,106,248,129,204,19,36,211,123, - 238,42,147,177,234,179,227,214,141,174,235,8,6,131,24,28,28,52,221,99, - 46,151,11,94,175,23,62,159,15,30,143,199,92,173,155,202,65,125,67,36, - 144,60,77,171,0,10,249,190,172,132,75,22,25,94,118,126,29,239,175,228, - 43,138,151,151,151,39,13,97,224,209,136,92,224,178,169,127,122,47,15,184, - 151,199,45,90,185,134,101,203,148,223,155,60,206,141,187,133,179,169,127,133, - 66,161,40,85,146,230,162,228,227,200,184,133,96,101,165,165,123,122,39,247, - 158,44,26,86,110,74,46,64,36,110,129,64,0,131,131,131,24,30,30,70, - 56,28,134,166,105,102,227,234,245,122,45,87,11,208,52,45,201,138,227,125, - 121,60,250,79,30,255,37,151,135,210,228,66,33,187,41,185,21,200,199,252, - 113,17,160,153,46,168,76,20,176,17,137,68,44,151,251,201,166,254,249,80, - 0,114,75,202,243,131,146,0,202,226,39,231,37,215,15,89,110,161,80,40, - 167,250,87,40,20,138,82,197,92,77,192,42,16,67,110,100,185,176,113,139, - 130,160,99,86,209,152,60,93,222,96,83,62,20,212,16,8,4,48,52,52, - 132,193,193,65,232,186,14,33,68,138,104,240,33,2,148,7,53,236,228,14, - 228,19,217,202,22,168,28,118,47,91,56,252,124,43,113,147,211,162,62,55, - 143,199,99,150,211,231,243,153,75,120,80,192,12,77,207,36,175,134,157,75, - 253,243,114,146,229,42,187,95,29,14,71,74,96,144,149,149,200,35,38,35, - 145,136,249,112,145,107,253,43,20,10,69,41,226,2,146,93,134,114,184,57, - 95,91,137,26,115,254,106,135,157,139,82,182,222,40,224,130,250,124,46,93, - 186,132,161,161,33,4,2,1,115,230,246,242,242,114,84,84,84,192,235,245, - 154,46,63,43,247,168,92,54,46,94,124,128,50,47,139,236,114,148,197,143, - 195,243,228,67,20,40,160,132,220,146,228,198,35,161,165,62,69,18,55,121, - 29,181,92,235,159,44,100,217,34,229,227,236,168,140,114,221,115,129,227,86, - 229,120,234,95,161,80,40,74,17,203,101,137,121,191,18,48,26,218,206,251, - 153,172,26,93,222,72,203,179,112,0,72,18,27,74,51,22,139,153,125,62, - 67,67,67,24,30,30,54,131,26,220,110,55,102,204,152,1,191,223,143,242, - 242,114,51,96,195,74,56,185,72,144,117,33,175,74,46,7,101,240,241,100, - 242,49,217,61,200,3,109,0,36,205,80,66,150,27,245,189,209,234,196,20, - 141,200,39,217,205,102,165,225,108,235,159,234,153,62,147,203,146,7,162,88, - 165,205,235,62,26,141,230,165,254,21,10,133,162,212,72,18,56,30,130,110, - 213,200,210,113,110,189,216,173,26,96,23,160,65,238,57,222,184,6,2,1, - 132,66,33,179,207,7,0,220,110,55,252,126,191,217,192,250,124,190,164,117, - 184,200,117,72,110,64,74,63,157,245,66,175,116,13,31,155,38,247,205,145, - 187,83,46,63,191,111,62,206,141,222,115,113,35,183,31,13,148,206,36,110, - 227,169,127,190,162,130,157,229,172,105,163,171,23,228,171,254,21,10,133,162, - 84,113,201,33,252,114,3,204,173,5,62,67,8,159,103,81,22,56,187,39, - 124,238,146,228,203,135,36,22,29,76,184,240,72,56,202,203,203,225,247,251, - 225,247,251,147,66,237,173,34,34,121,95,147,85,217,9,94,54,121,152,1, - 165,37,91,115,242,181,124,238,75,42,23,13,124,166,40,78,114,253,209,253, - 233,186,158,52,238,141,167,73,76,214,250,87,40,20,138,82,197,52,81,184, - 213,32,135,164,243,70,150,91,96,116,29,53,174,242,10,222,4,119,137,241, - 185,13,233,149,26,127,30,133,88,81,81,129,138,138,10,211,42,34,241,160, - 114,201,46,80,171,128,10,171,192,24,190,79,182,58,229,32,15,158,38,221, - 27,185,37,41,76,158,7,92,112,203,136,92,147,60,106,210,78,220,38,123, - 253,43,20,10,69,41,146,228,131,147,45,10,218,199,27,118,33,18,139,55, - 2,48,151,79,145,251,171,228,168,61,185,207,135,94,185,219,141,6,69,83, - 180,158,215,235,77,26,111,37,151,135,231,103,23,230,47,151,201,202,149,42, - 71,34,202,3,166,101,1,225,211,131,241,254,71,62,142,140,111,86,226,38, - 215,241,100,175,127,133,66,161,40,69,44,131,76,172,44,30,218,79,141,45, - 13,166,230,125,58,212,216,202,211,63,145,0,200,179,103,208,100,196,212,143, - 69,13,44,77,80,44,47,240,201,203,38,151,215,42,132,223,202,157,70,243, - 58,242,243,184,208,1,201,171,145,243,113,110,178,117,196,45,170,104,52,106, - 90,110,36,34,178,0,201,101,179,99,178,213,191,66,161,80,148,34,150,2, - 7,36,143,95,163,134,150,44,23,126,78,52,26,53,27,127,185,159,73,110, - 24,233,90,106,56,41,188,94,222,168,17,231,141,169,149,235,45,19,86,194, - 199,225,141,61,23,67,57,31,74,71,30,51,199,215,75,227,214,17,237,183, - 19,183,108,203,62,217,235,95,161,80,40,38,18,91,129,227,200,141,62,245, - 201,196,98,49,115,22,127,154,126,138,187,190,248,84,84,116,45,15,212,32, - 43,129,247,103,201,227,235,184,139,48,83,25,9,187,62,57,218,111,53,247, - 35,189,39,43,142,207,185,41,7,109,144,136,112,49,227,86,148,85,160,138, - 157,59,53,27,38,67,253,43,20,10,69,169,145,149,192,1,169,211,87,209, - 123,43,151,152,220,192,242,52,120,191,150,28,222,110,231,126,204,181,113,77, - 103,185,113,171,74,182,216,184,171,50,93,190,178,235,143,127,182,139,192,164, - 235,198,202,100,170,127,133,66,161,40,5,52,33,132,56,113,226,4,218,219, - 219,17,137,68,80,81,81,145,178,222,151,93,240,131,29,153,206,225,209,124, - 129,64,0,101,101,101,168,173,173,197,242,229,203,209,213,213,133,174,174,46, - 188,244,210,75,136,197,98,230,192,105,121,74,170,124,150,71,94,220,211,229, - 114,225,174,187,238,194,252,249,243,1,0,93,93,93,37,81,63,243,231,207, - 199,145,35,71,108,211,205,55,93,93,93,184,230,154,107,146,230,182,148,197, - 154,132,150,187,111,101,215,42,192,39,137,22,16,34,121,162,232,214,214,86, - 204,155,55,175,104,247,245,145,143,124,164,104,121,41,138,131,154,124,64,97, - 133,235,205,55,223,196,219,111,191,141,235,174,187,14,151,95,126,57,202,203, - 203,1,36,71,228,113,178,25,3,149,233,28,106,28,13,195,64,40,20,194, - 249,243,231,241,214,91,111,153,130,241,194,11,47,160,182,182,22,179,103,207, - 134,199,227,41,106,121,34,145,8,122,123,123,241,194,11,47,224,158,123,238, - 1,128,146,171,159,91,111,189,21,85,85,85,41,66,146,205,43,97,103,221, - 2,192,240,240,48,126,250,211,159,34,16,8,160,191,191,31,64,114,3,194, - 7,156,243,235,132,16,73,43,171,115,43,19,160,49,125,49,196,227,72,186, - 86,215,245,162,222,215,192,192,128,109,221,43,20,138,169,131,107,120,120,24, - 62,159,15,243,231,207,71,121,121,185,109,128,133,85,163,67,199,101,50,157, - 67,174,60,135,195,1,191,223,143,43,174,184,2,109,109,109,24,30,30,198, - 201,147,39,225,241,120,48,103,206,28,120,189,222,148,235,11,89,30,167,211, - 9,159,207,135,203,46,187,12,93,93,93,56,116,232,16,150,45,91,86,82, - 245,3,0,67,67,67,150,195,25,172,210,147,203,198,143,203,193,40,212,63, - 25,8,4,0,0,125,125,125,73,147,87,211,2,176,242,189,198,227,113,115, - 8,3,159,182,13,128,25,252,50,58,8,94,131,203,53,26,205,106,24,6, - 186,187,187,177,112,225,194,162,221,23,9,170,162,116,9,133,66,0,146,191, - 43,106,15,124,62,223,132,148,73,49,249,112,69,163,81,84,87,87,195,231, - 243,165,4,51,0,169,99,171,248,113,171,190,174,76,231,240,227,212,0,249, - 124,62,84,87,87,35,28,14,35,30,143,167,88,110,197,44,143,16,2,30, - 143,7,179,103,207,70,52,26,197,111,127,251,91,92,115,205,53,37,81,63, - 111,191,253,54,102,205,154,133,222,222,94,132,195,225,164,254,51,186,78,158, - 172,153,206,161,62,58,106,236,71,221,189,134,105,81,105,154,134,112,56,108, - 54,42,124,128,55,31,66,33,91,77,20,157,105,37,212,116,156,86,52,119, - 185,180,164,244,52,77,51,173,226,98,221,23,53,148,138,210,67,215,117,180, - 183,183,227,249,231,79,224,240,225,46,156,58,117,30,3,3,64,101,37,176, - 100,73,53,110,186,105,62,238,185,103,57,106,107,107,213,247,168,200,136,235, - 194,133,11,184,250,234,171,83,102,173,39,228,198,204,106,223,88,206,225,110, - 56,195,48,224,243,249,240,246,219,111,163,171,171,11,245,245,245,73,110,176, - 241,230,149,237,57,84,30,18,185,119,222,121,7,51,102,204,128,207,231,43, - 137,250,33,72,120,40,10,50,22,139,165,76,192,204,69,129,187,19,53,77, - 51,231,203,4,128,88,76,192,227,129,153,78,89,89,153,41,4,30,143,199, - 114,81,83,94,86,62,169,179,108,109,201,253,116,86,253,36,20,232,82,204, - 251,170,172,172,76,41,135,98,226,209,117,29,47,191,124,2,223,250,214,17, - 0,149,88,190,252,38,220,117,79,21,42,43,189,24,24,208,209,222,222,143, - 215,95,111,199,225,195,175,227,243,159,95,133,143,124,228,38,37,114,138,180, - 184,130,193,32,220,110,55,6,7,7,147,166,157,146,45,149,124,66,150,82, - 194,101,21,55,195,221,9,167,211,137,64,32,144,18,225,87,140,242,208,224, - 109,222,176,151,90,253,144,219,144,26,120,154,97,133,11,9,183,146,172,92, - 135,180,223,227,25,181,116,200,101,72,22,25,89,94,64,122,87,171,60,41, - 53,63,46,231,203,243,39,151,39,89,235,197,186,47,213,7,87,122,232,186, - 142,231,158,123,29,207,62,215,142,218,37,75,112,231,93,75,80,85,233,133, - 215,11,232,0,170,116,160,118,73,53,26,26,230,99,207,158,83,248,167,39, - 142,160,171,235,60,62,245,169,219,148,200,41,108,113,1,201,46,27,222,63, - 196,159,148,249,113,121,159,76,54,231,240,243,228,50,80,131,39,159,91,232, - 242,112,120,25,74,173,126,0,160,172,172,204,20,61,171,37,108,228,6,223, - 202,26,38,28,142,81,107,76,78,215,202,130,147,211,149,145,221,173,148,182, - 92,46,42,19,47,123,49,238,75,245,193,149,22,161,80,8,167,78,181,227, - 217,231,91,224,157,191,20,243,151,206,135,183,210,11,120,1,221,7,0,62, - 192,23,2,66,128,119,126,37,170,27,170,209,165,135,240,236,243,45,88,178, - 164,26,75,150,212,78,244,45,40,74,148,180,227,224,210,53,94,185,94,151, - 15,84,121,146,175,151,27,127,187,116,51,133,80,147,96,59,28,142,164,126, - 44,62,255,165,44,32,116,126,166,52,233,61,207,131,167,97,53,252,163,208, - 247,165,158,248,75,139,80,40,132,151,95,62,133,126,95,45,124,94,160,11, - 192,121,93,71,37,188,72,124,83,20,112,50,242,112,82,229,67,127,165,15, - 8,213,226,229,151,79,41,129,83,216,146,179,192,229,3,171,167,237,108,80, - 229,73,32,15,204,182,178,32,121,227,111,213,55,102,101,101,241,201,151,1, - 36,5,150,240,180,173,242,227,121,201,159,169,223,204,206,226,227,235,243,21, - 227,190,168,15,238,229,151,95,198,225,195,135,209,220,220,172,68,175,72,232, - 186,142,134,134,6,220,116,211,77,184,243,206,59,1,0,247,220,115,15,14, - 183,215,2,75,110,3,188,94,116,245,135,112,162,29,152,95,233,133,215,151, - 16,57,29,128,30,210,209,175,3,237,93,33,192,235,197,64,21,240,236,203, - 71,112,234,212,158,9,189,39,69,233,226,2,96,206,103,40,7,79,20,170, - 1,183,130,55,148,177,88,44,41,152,99,34,102,175,231,229,41,181,250,225, - 211,109,1,201,11,165,242,247,252,90,222,111,40,175,184,14,192,180,112,120, - 208,72,58,193,177,130,167,201,175,161,60,185,187,147,187,122,249,74,14,197, - 184,175,129,129,1,188,254,250,235,120,238,185,231,80,85,85,165,34,242,138, - 136,174,235,56,127,254,60,158,125,246,89,232,186,142,219,110,187,13,213,213, - 213,208,251,107,81,89,233,69,85,85,162,223,45,113,238,200,69,62,64,15, - 141,90,112,62,47,80,85,229,133,14,96,160,178,22,213,213,161,137,186,29, - 69,137,227,2,70,27,178,66,4,116,100,107,29,89,137,71,46,141,107,33, - 203,83,106,245,67,159,121,100,33,97,37,34,233,44,48,122,79,97,252,242, - 125,167,155,173,197,202,77,105,247,125,201,125,121,116,29,221,67,49,239,75, - 215,117,156,58,117,10,181,181,181,168,170,170,2,160,34,43,139,197,192,192, - 0,66,161,16,42,43,43,113,234,212,41,220,116,211,77,168,170,170,66,101, - 109,45,230,87,121,49,191,178,10,149,85,94,84,121,19,66,231,245,141,10, - 30,0,84,121,189,128,105,211,245,3,181,181,168,170,234,154,160,187,81,148, - 58,73,2,7,20,215,74,178,67,110,240,38,154,82,171,31,77,27,93,155, - 14,176,182,156,236,220,129,116,142,149,53,36,91,80,252,123,144,243,224,214, - 147,156,31,63,70,253,119,118,253,101,242,67,76,49,238,203,235,245,162,171, - 171,11,243,231,207,71,117,117,53,0,152,66,167,40,44,85,85,85,232,239, - 239,135,174,235,232,234,106,135,215,235,69,101,101,37,170,250,67,152,95,89, - 139,234,249,9,113,171,244,121,225,171,244,193,139,196,247,165,235,58,244,74, - 31,66,3,161,145,125,0,80,5,189,191,75,61,156,40,108,73,90,209,187, - 16,141,183,85,154,217,88,45,170,60,217,93,103,37,188,233,4,128,191,183, - 27,135,39,187,23,173,210,148,247,243,129,216,114,93,113,177,227,239,1,164, - 88,106,197,184,175,202,202,74,220,116,211,77,8,133,66,240,249,124,170,129, - 44,34,94,175,23,94,175,23,253,253,253,168,173,189,9,149,149,149,137,239, - 0,3,35,150,91,37,42,171,124,168,170,4,188,72,244,193,1,9,75,78, - 15,233,240,86,3,24,240,1,253,33,232,85,3,168,108,31,80,51,155,40, - 108,73,187,224,105,161,144,199,156,209,130,161,118,20,163,60,192,104,48,130, - 16,194,156,79,113,162,202,147,174,126,210,185,5,121,223,22,237,227,34,36, - 175,70,192,243,52,140,212,107,121,223,35,239,11,149,87,42,224,214,22,31, - 144,77,174,68,185,15,141,191,231,125,112,197,184,175,129,129,1,212,214,214, - 162,165,165,197,108,112,85,35,89,28,104,10,46,159,207,135,218,218,90,12, - 12,12,160,186,186,26,243,219,219,81,85,73,226,54,98,193,121,19,67,5, - 200,33,233,243,122,17,210,245,145,79,35,129,39,190,126,84,87,171,40,74, - 133,53,46,192,190,193,150,199,121,229,171,97,231,233,201,33,220,19,85,30, - 217,229,150,141,229,48,81,245,195,207,203,212,7,102,101,221,88,89,163,163, - 121,141,238,147,151,13,202,84,39,178,120,113,65,180,203,147,242,41,230,125, - 233,186,110,6,150,232,186,142,254,254,126,229,162,44,18,161,80,200,12,236, - 169,170,170,130,174,235,137,207,149,237,232,63,223,140,170,218,219,76,113,243, - 86,38,196,205,75,65,38,94,0,3,163,29,114,237,167,14,163,182,82,185, - 151,21,246,76,200,48,1,57,125,171,6,109,34,203,3,100,183,252,198,68, - 213,143,149,21,148,41,13,122,47,175,74,206,207,113,56,82,163,53,101,129, - 179,114,99,2,153,135,11,208,140,36,252,56,125,150,3,89,10,125,95,20, - 49,89,91,171,158,252,139,141,85,157,55,52,52,0,0,94,63,124,10,93, - 167,230,99,254,109,171,224,245,2,149,62,192,55,18,83,226,243,2,33,29, - 24,0,0,221,139,83,39,154,81,213,127,10,183,221,180,220,188,94,161,144, - 153,80,129,163,60,178,205,71,149,39,121,159,85,192,69,166,253,124,234,43, - 25,218,207,131,76,248,20,97,36,36,116,30,23,22,171,8,76,121,214,17, - 110,101,209,176,129,228,9,146,139,115,95,170,207,173,180,160,7,14,93,215, - 113,184,229,48,218,155,67,88,117,219,109,240,85,38,130,73,188,24,177,222, - 70,134,13,28,57,242,58,244,174,102,220,180,188,22,13,13,13,230,186,141, - 10,133,204,132,141,131,147,159,182,57,19,49,14,46,93,121,74,173,126,198, - 155,191,221,117,114,158,114,0,8,237,227,125,94,220,253,152,206,141,40,151, - 155,187,49,101,235,180,208,247,165,230,162,44,61,168,79,174,191,191,31,167, - 78,188,140,61,45,71,80,187,124,9,150,52,52,96,73,109,45,218,219,219, - 113,170,185,25,237,39,78,1,122,63,150,212,214,162,182,182,22,62,159,79, - 77,189,166,176,69,141,131,203,162,60,165,86,63,84,38,43,215,30,183,98, - 228,192,12,59,235,70,206,35,62,210,97,69,115,65,202,150,19,79,135,198, - 153,241,7,0,121,200,128,213,92,145,92,224,248,100,205,197,184,47,213,32, - 150,38,213,213,213,88,190,124,57,170,170,170,208,222,222,142,246,215,95,199, - 225,231,158,131,174,235,240,122,189,152,63,127,62,230,207,159,143,218,165,137, - 229,114,104,136,135,250,62,21,118,168,113,112,89,80,106,245,67,17,150,0, - 82,44,203,108,175,151,175,33,23,34,159,224,152,150,175,145,207,225,2,111, - 24,134,233,198,148,135,1,144,43,146,142,17,252,122,202,179,152,247,165,102, - 45,41,77,40,154,181,186,186,26,181,181,181,8,133,66,24,24,24,48,5, - 142,134,20,208,250,149,234,123,84,100,66,141,131,155,164,229,33,215,30,23, - 95,185,129,151,45,29,126,45,229,205,69,139,92,195,4,159,8,25,72,158, - 58,203,202,162,227,249,91,173,2,96,101,117,201,22,94,49,238,75,245,193, - 149,62,212,175,102,181,162,183,18,54,69,182,168,113,112,152,124,227,224,120, - 223,149,188,54,26,189,231,231,202,1,26,178,112,240,115,248,125,211,106,2, - 86,229,147,5,199,14,18,42,187,115,52,77,67,52,26,69,44,22,43,218, - 125,169,62,184,201,9,137,157,114,73,42,178,37,167,113,112,86,200,97,227, - 50,118,129,6,244,58,158,113,112,249,44,79,62,198,193,229,179,60,244,106, - 87,63,114,3,110,55,78,206,206,10,178,58,87,30,247,38,91,112,153,172, - 168,76,159,101,40,13,90,117,187,88,247,165,26,72,133,98,122,48,238,97, - 2,227,177,102,228,134,60,31,121,229,163,60,64,254,198,193,21,162,126,52, - 45,177,138,182,219,237,30,183,53,201,5,152,2,62,200,106,227,43,170,243, - 188,185,59,49,30,143,91,246,123,113,145,178,18,121,218,47,7,149,20,227, - 190,148,139,75,161,152,30,168,113,112,22,121,76,134,242,144,59,53,83,95, - 23,183,116,120,154,60,29,32,185,79,140,162,13,105,26,43,158,182,108,49, - 145,24,241,129,214,86,130,70,253,108,66,0,180,155,167,21,12,6,139,118, - 95,170,15,78,161,152,30,164,184,40,173,250,54,228,247,242,53,252,156,116, - 13,16,39,147,251,202,234,220,137,42,79,169,213,79,60,30,71,32,16,72, - 9,158,144,243,74,135,28,229,72,233,132,195,97,68,34,17,0,9,129,163, - 232,67,126,30,23,49,74,75,30,38,192,243,144,203,194,243,229,231,23,235, - 190,84,31,156,66,49,61,176,141,162,164,206,126,171,134,217,28,236,171,105, - 0,107,236,233,149,31,55,88,122,230,62,230,158,226,253,48,28,171,242,200, - 194,194,207,75,148,79,131,166,37,55,132,86,199,105,255,232,190,100,171,195, - 202,101,58,150,250,209,52,71,82,121,228,250,209,52,7,128,209,134,152,246, - 9,97,164,173,159,147,39,79,102,249,245,142,143,178,178,50,184,221,110,219, - 240,123,42,159,60,48,95,22,113,94,63,178,232,241,126,182,98,221,151,234, - 131,83,40,166,7,73,2,199,195,179,249,160,102,171,206,126,222,224,90,157, - 67,199,157,22,215,56,88,212,162,93,200,55,23,26,171,224,3,43,171,64, - 46,143,188,111,228,93,202,190,132,219,44,57,180,220,170,60,133,168,31,94, - 67,163,145,131,163,139,129,202,229,249,232,71,63,10,197,248,232,235,235,155, - 232,34,40,20,138,34,96,186,40,169,179,159,55,224,118,51,80,228,26,57, - 103,181,143,63,209,91,5,50,144,213,194,133,173,208,229,161,190,31,121,94, - 197,82,171,31,197,248,152,61,123,246,68,23,65,161,80,20,129,36,129,211, - 52,13,110,183,219,20,22,110,117,112,119,19,89,22,66,211,0,139,121,9, - 249,113,167,197,62,109,196,82,114,58,157,136,68,34,150,97,240,244,153,250, - 128,236,44,165,100,203,75,192,48,82,103,66,225,199,1,71,202,62,33,70, - 63,71,163,81,203,249,17,199,82,63,114,121,228,250,209,52,1,77,115,166, - 236,163,242,216,213,143,66,161,80,40,50,99,78,213,229,114,185,224,243,249, - 82,166,103,34,172,130,35,236,2,41,248,123,187,96,12,32,49,169,178,211, - 233,180,180,152,156,78,39,60,30,15,92,46,87,74,255,92,161,202,67,66, - 34,91,83,165,86,63,10,133,66,161,200,140,3,0,186,187,187,225,241,120, - 224,243,249,44,27,111,32,53,200,194,170,193,181,58,158,238,26,151,203,5, - 143,199,131,178,178,50,92,184,112,193,220,63,48,48,0,183,219,13,143,199, - 99,41,110,133,42,143,211,233,52,5,172,191,191,31,0,48,111,222,188,146, - 171,31,133,66,161,80,100,198,113,217,101,151,161,165,165,101,194,44,4,114, - 255,157,58,117,10,151,93,118,25,102,205,154,133,142,142,142,9,47,207,239, - 126,247,59,204,154,53,11,134,97,148,76,253,40,20,10,133,34,123,28,21, - 21,21,232,234,234,194,238,221,187,113,230,204,153,162,23,224,204,153,51,216, - 189,123,55,186,186,186,80,81,81,1,175,215,139,222,222,94,236,219,183,15, - 231,206,157,43,122,121,206,157,59,135,125,251,246,161,183,183,23,94,175,23, - 165,84,63,239,123,223,251,138,158,191,66,161,80,76,86,180,83,167,78,137, - 51,103,206,224,215,191,254,53,218,218,218,208,223,223,143,112,56,156,245,32, - 236,49,103,172,105,240,120,60,168,170,170,66,93,93,29,174,191,254,122,212, - 215,215,3,0,94,120,225,5,180,181,181,225,189,247,222,195,208,208,16,162, - 209,104,81,202,227,118,187,49,99,198,12,92,113,197,21,168,171,171,195,221, - 119,223,13,32,33,50,165,82,63,75,151,46,45,104,190,10,133,66,49,85, - 208,132,16,226,252,249,243,232,233,233,65,111,111,175,57,147,68,49,26,112, - 151,203,133,138,138,10,204,153,51,7,115,231,206,69,117,117,53,116,93,199, - 192,192,0,122,122,122,176,127,255,126,132,66,33,196,227,241,162,148,199,233, - 116,194,231,243,97,205,154,53,152,59,119,174,57,165,19,149,103,162,235,167, - 178,178,18,229,229,229,5,205,87,161,80,40,166,10,154,0,10,219,82,43, - 20,10,133,13,14,21,29,172,40,32,106,112,149,66,161,80,40,166,36,74, - 224,20,10,133,66,49,37,81,2,167,80,40,20,138,41,137,18,56,133,66, - 161,80,76,73,148,192,41,20,10,133,98,74,146,118,69,111,69,42,217,196, - 124,169,176,84,133,66,161,152,120,166,134,192,241,49,105,69,8,59,78,55, - 6,78,77,138,172,80,40,20,165,193,152,4,78,110,194,133,180,175,168,22, - 140,52,3,191,72,172,94,90,184,236,96,189,126,27,104,127,193,114,46,81, - 228,122,40,182,192,79,116,254,211,16,187,26,158,118,191,125,69,201,51,238, - 129,222,244,99,159,144,31,183,197,146,51,137,221,133,21,57,32,113,223,41, - 11,153,22,52,199,18,196,102,73,160,162,137,76,17,243,159,208,223,121,14, - 20,178,156,102,218,54,30,12,115,217,167,28,210,84,3,189,21,133,100,242, - 6,153,216,136,91,209,178,71,242,146,55,165,222,240,229,29,190,142,29,219, - 52,77,75,181,170,166,72,254,66,136,172,250,96,15,71,127,161,0,0,32, - 0,73,68,65,84,39,10,249,161,171,16,105,167,75,223,92,68,184,32,37, - 80,40,114,103,242,10,220,8,19,105,65,152,238,202,162,228,86,66,208,195, - 5,70,221,211,220,114,40,184,200,73,249,39,29,42,112,254,165,218,128,23, - 67,220,146,246,141,172,127,40,175,131,8,148,110,29,41,166,31,147,83,224, - 152,245,86,232,73,143,51,22,165,168,153,137,204,13,119,54,231,140,179,12, - 217,88,204,5,19,153,34,231,207,197,123,50,81,200,114,243,135,139,105,247, - 112,167,152,84,76,78,129,99,20,187,239,109,194,16,2,142,44,125,177,142, - 132,250,23,182,56,72,109,68,233,115,49,26,61,158,191,188,229,43,127,222, - 231,196,93,225,165,102,161,112,11,75,126,240,27,111,57,51,245,53,219,89, - 142,165,86,71,138,233,201,228,19,56,102,189,77,27,114,16,55,162,24,34, - 55,29,224,191,179,82,20,57,43,113,35,242,253,31,201,36,110,86,238,74, - 133,98,34,153,212,227,224,166,133,245,102,37,110,89,54,92,14,77,211,140, - 68,171,156,247,98,113,75,73,142,220,43,198,183,144,206,82,155,130,191,130, - 146,195,206,178,83,117,175,40,37,38,151,192,77,55,235,205,66,220,198,98, - 201,229,85,228,178,140,92,45,216,3,199,68,231,175,80,67,100,20,147,134, - 201,37,112,140,105,97,189,105,26,12,33,4,23,53,35,11,117,79,57,63, - 159,117,195,196,197,206,114,43,232,247,49,209,249,79,115,148,184,41,38,19, - 147,175,15,14,211,108,58,172,17,145,147,247,217,110,140,66,138,91,226,227, - 104,32,67,177,197,173,88,249,243,252,184,247,160,84,26,118,62,30,83,182, - 108,243,253,63,145,163,150,179,13,56,81,40,38,138,73,107,193,17,211,226, - 105,221,194,146,203,68,81,196,205,202,93,92,76,113,43,112,254,102,164,38, - 19,16,160,116,196,141,224,211,199,165,204,234,147,199,180,57,217,4,156,148, - 82,29,41,166,39,147,90,224,74,65,220,138,21,22,111,105,201,217,80,44, - 113,163,114,21,156,9,204,191,152,129,51,249,164,24,191,73,94,39,202,114, - 83,148,34,147,86,224,74,70,220,216,172,26,133,207,48,139,251,205,119,157, - 76,192,60,159,37,149,191,68,169,90,38,118,150,86,161,210,206,180,162,70, - 41,214,145,98,250,49,41,251,224,38,186,145,3,146,93,50,165,50,38,42, - 239,76,180,184,76,116,254,18,165,222,112,243,254,184,66,165,157,46,125,58, - 94,202,117,164,152,94,140,105,53,1,249,39,46,143,127,41,232,15,188,196, - 196,45,105,255,84,252,115,243,161,25,19,81,239,19,157,191,34,5,187,111, - 97,44,191,125,181,154,128,162,144,140,123,185,156,233,70,166,72,177,169,42, - 114,19,42,46,19,157,191,162,96,40,129,83,20,146,73,219,7,55,145,76, - 171,97,10,192,196,139,203,68,231,175,80,40,38,37,74,224,114,100,202,89, - 103,10,133,66,49,69,153,148,65,38,10,133,66,161,80,100,66,9,156,66, - 161,80,40,166,36,74,224,20,10,133,66,49,37,81,2,167,80,40,20,138, - 41,137,18,56,133,66,161,80,76,73,138,26,128,109,20,113,190,58,53,190, - 70,49,33,104,154,10,180,85,40,74,4,101,193,41,20,10,133,98,74,162, - 4,78,161,80,40,20,83,146,105,59,208,251,202,5,11,50,186,146,222,61, - 119,78,249,57,21,10,133,98,146,50,109,5,14,0,58,59,59,109,143,213, - 212,212,20,177,36,138,241,32,207,167,170,77,190,229,219,20,10,69,1,200, - 218,69,41,18,83,222,10,1,136,91,87,175,22,242,231,66,22,178,16,188, - 123,238,156,102,39,98,53,53,53,202,122,155,36,8,64,180,182,182,226,165, - 151,94,66,107,107,43,158,120,226,137,20,193,203,23,7,14,30,156,116,191, - 115,133,98,58,51,166,88,67,1,136,213,171,87,227,103,7,15,230,116,249, - 88,163,40,107,106,106,146,46,236,236,236,204,152,111,182,81,148,87,46,88, - 32,184,37,55,21,197,109,170,90,56,116,95,45,45,45,40,43,43,195,129, - 3,7,208,216,216,136,109,219,182,97,199,142,29,121,191,207,255,231,134,27, - 196,175,222,124,51,125,154,42,138,82,161,40,25,74,58,200,100,239,222,189, - 77,53,53,53,226,204,153,51,232,236,236,68,103,103,39,126,252,163,23,80, - 83,83,35,246,238,221,219,148,143,60,184,37,55,21,197,141,56,115,230,140, - 185,21,202,194,33,139,254,239,55,111,46,120,35,79,150,91,127,127,63,150, - 46,93,138,238,238,110,52,54,54,226,219,223,254,54,54,110,220,136,59,239, - 188,115,92,247,249,133,47,126,49,229,218,5,11,22,88,238,87,40,20,37, - 138,54,134,13,9,11,78,228,122,157,16,34,167,109,193,130,5,130,216,179, - 103,143,216,179,103,143,249,121,193,130,5,98,207,158,61,77,118,215,230,90, - 182,5,11,22,228,116,63,15,254,85,91,206,247,63,17,27,0,113,230,204, - 153,164,13,64,65,202,142,132,160,136,205,155,55,23,188,110,0,136,182,182, - 54,209,218,218,42,250,251,251,5,0,241,175,255,250,175,162,181,181,85,220, - 118,219,109,162,181,181,117,92,247,105,119,173,207,231,75,159,166,166,9,181, - 169,77,109,165,177,149,172,5,71,150,27,0,236,221,187,23,235,214,173,195, - 186,117,235,204,227,103,206,156,193,134,13,27,54,231,43,191,108,44,183,191, - 252,171,54,65,91,190,242,45,6,245,245,245,73,239,183,111,223,62,129,165, - 201,31,134,97,160,187,187,27,189,189,189,56,124,248,48,62,247,185,207,225, - 67,31,250,16,254,229,95,254,5,31,250,208,135,198,156,238,239,221,120,163, - 176,251,252,149,175,124,37,229,184,66,161,40,77,74,86,224,0,192,235,245, - 154,226,102,117,12,72,184,49,243,145,151,157,112,229,67,212,178,113,219,21, - 194,181,39,0,65,22,109,125,125,125,146,208,229,37,237,44,239,171,80,110, - 203,197,139,23,99,222,188,121,120,243,205,55,49,111,222,60,220,121,231,157, - 104,111,111,199,226,197,139,209,222,222,158,83,90,95,254,202,87,4,109,71, - 143,30,77,58,230,243,249,240,229,175,124,69,0,192,223,255,221,223,105,242, - 113,133,66,81,154,148,252,48,1,43,113,203,55,127,249,87,109,98,199,246, - 218,145,79,153,133,236,219,79,213,101,180,246,136,92,250,129,182,108,217,130, - 205,155,55,139,127,216,178,37,235,244,179,161,181,181,21,103,206,156,201,171, - 245,166,1,154,0,68,186,50,211,189,111,222,188,25,249,190,39,130,2,75, - 190,253,237,111,99,251,246,237,56,117,234,148,41,110,154,233,109,204,204,99, - 143,61,102,159,199,254,253,218,254,253,251,69,65,110,64,161,80,20,140,146, - 22,56,93,215,77,75,205,234,88,38,242,237,74,204,69,216,128,220,196,141, - 200,151,200,145,245,102,197,23,54,108,200,75,91,45,139,220,150,45,91,146, - 242,7,10,35,110,20,96,178,120,241,98,124,238,115,159,195,63,253,211,63, - 97,96,96,0,27,54,108,24,147,184,41,20,138,169,73,73,15,19,168,169, - 169,17,118,131,177,107,106,106,176,125,251,246,45,0,176,110,221,186,38,249, - 184,67,211,242,34,112,185,138,26,49,222,72,197,241,10,3,9,92,107,107, - 43,128,228,190,183,124,9,28,207,203,106,127,161,197,205,142,177,136,27,239, - 87,35,23,36,165,243,15,255,248,143,226,165,151,94,194,47,143,30,213,168, - 12,182,121,104,106,152,128,66,81,42,148,172,5,71,99,223,106,106,106,112, - 230,204,25,211,146,211,117,157,26,107,91,113,203,7,99,21,54,130,172,27, - 250,156,169,177,207,229,220,76,20,195,122,155,8,172,196,45,95,150,26,137, - 215,104,86,163,60,246,216,99,208,67,161,73,91,111,10,197,180,101,172,33, - 212,133,28,38,176,96,193,2,65,219,158,61,123,154,248,103,218,151,110,136, - 192,88,134,9,20,50,156,29,89,132,206,103,123,94,182,121,10,33,146,134, - 5,108,223,190,93,108,223,190,61,239,225,251,188,220,244,158,111,249,26,50, - 128,132,184,37,165,93,168,239,236,139,137,177,110,130,127,166,247,119,221,117, - 151,224,159,83,182,18,8,141,86,155,218,212,150,216,198,220,216,20,74,224, - 236,132,140,222,103,35,110,165,36,112,84,95,217,8,92,62,197,0,108,252, - 27,70,4,174,16,247,197,203,157,233,243,120,242,41,150,184,209,118,195,13, - 55,164,228,241,196,19,79,8,171,253,73,91,9,252,169,213,166,54,181,37, - 182,49,55,56,133,16,184,92,173,180,124,10,92,174,3,189,75,121,131,100, - 69,21,194,122,131,133,120,101,187,47,215,124,138,45,110,26,128,131,7,15, - 166,228,51,103,206,28,97,181,63,105,43,129,63,181,218,212,166,182,196,86, - 50,227,224,248,124,147,133,238,95,147,161,249,40,179,89,66,103,178,81,168, - 192,18,13,208,52,64,203,212,87,152,237,121,233,40,68,159,91,38,26,87, - 175,78,201,231,163,31,253,168,229,126,133,66,81,154,148,132,192,149,130,184, - 1,137,229,115,166,146,200,21,74,220,138,69,169,77,18,253,47,223,249,206, - 164,172,71,133,98,186,50,166,229,114,86,175,94,141,131,7,15,154,251,198, - 187,92,14,137,218,68,138,27,49,85,68,110,178,139,27,135,172,192,137,46, - 135,66,161,152,92,140,105,28,220,88,73,55,14,142,166,220,202,151,184,101, - 90,46,199,74,220,56,147,125,101,129,111,110,223,46,38,179,184,165,29,107, - 86,202,104,106,28,156,66,81,42,148,140,192,229,155,108,4,46,83,26,147, - 89,224,38,51,147,86,220,0,37,112,10,69,9,49,109,5,78,161,40,8, - 74,224,20,138,146,161,36,130,76,20,10,133,66,161,200,55,37,59,85,151, - 98,154,161,44,31,133,66,145,103,148,5,167,80,40,20,138,41,137,102,55, - 41,175,66,161,250,49,21,83,145,98,198,2,140,5,135,195,81,218,5,156, - 68,40,23,165,66,161,80,48,52,201,93,190,104,209,162,53,237,237,237,7, - 198,154,222,195,15,63,156,148,222,243,207,63,63,174,244,20,217,163,92,148, - 10,133,66,193,16,98,116,241,246,241,138,27,0,60,241,196,19,102,122,74, - 220,138,139,18,56,133,66,161,72,67,109,109,237,162,82,78,79,97,79,206, - 125,112,124,222,72,0,232,236,236,84,29,53,57,82,204,58,28,79,94,211, - 181,15,174,182,174,46,169,206,218,219,218,166,103,69,76,81,236,250,224,214, - 172,89,179,232,192,129,3,59,1,172,150,14,29,92,180,104,81,83,174,150, - 215,238,221,187,23,157,60,121,210,50,189,231,159,127,222,54,61,213,7,151, - 63,178,182,224,246,238,221,219,84,83,83,35,206,156,57,131,206,206,78,116, - 118,118,226,199,63,122,1,53,53,53,130,166,217,82,164,167,152,117,40,231, - 181,125,251,246,45,249,204,107,115,83,147,237,159,80,158,36,57,87,106,235, - 234,68,109,93,157,112,151,149,153,27,237,147,197,39,31,240,180,41,253,179, - 103,219,112,246,108,155,237,241,241,144,109,253,140,183,30,51,165,145,143,244, - 167,2,107,214,172,89,164,105,218,129,3,7,14,180,223,122,107,211,234,19, - 39,78,96,104,104,8,66,8,156,56,113,2,247,223,127,255,234,142,142,142, - 253,154,166,29,168,173,173,109,204,148,222,238,221,187,23,61,252,240,195,7, - 78,158,60,217,110,24,198,234,21,43,86,224,246,219,111,199,237,183,223,142, - 21,43,86,96,217,178,101,171,239,185,231,158,253,15,63,252,112,86,233,41, - 198,65,46,171,108,19,123,246,236,17,123,246,236,49,63,211,250,109,99,93, - 187,45,151,117,226,70,202,81,144,124,10,157,87,49,235,144,242,74,172,136, - 190,83,44,88,176,51,231,188,210,173,123,214,212,212,36,248,43,109,117,9, - 1,176,60,150,237,86,87,87,39,222,120,227,13,203,173,174,174,78,212,213, - 213,229,109,77,184,186,186,58,241,179,159,93,43,126,115,242,168,216,191,63, - 177,222,156,16,163,107,207,209,251,253,251,33,126,115,242,168,248,217,207,174, - 29,119,254,84,63,203,151,31,77,74,71,254,140,113,174,125,183,124,249,209, - 180,235,231,141,55,253,201,186,201,191,115,0,7,26,27,27,197,137,19,39, - 196,130,5,59,197,208,208,144,56,113,226,132,56,113,226,132,16,66,152,159, - 27,27,27,5,128,3,153,254,55,155,54,109,58,240,212,83,79,137,239,125, - 239,123,162,177,177,81,188,242,202,43,41,219,247,190,247,61,241,212,83,79, - 137,77,155,54,165,164,55,209,107,168,77,165,45,43,11,142,44,1,0,216, - 187,119,47,214,173,91,135,117,235,214,153,199,207,156,57,131,13,27,54,108, - 206,38,173,92,176,176,66,138,102,241,228,219,186,42,102,29,82,94,123,247, - 238,221,178,110,221,186,148,52,11,241,125,165,179,232,242,73,91,91,27,126, - 240,131,31,164,184,17,199,195,236,153,207,226,255,188,240,95,88,179,6,248, - 205,201,163,120,235,205,163,248,205,201,163,73,239,215,172,1,254,207,11,255, - 133,217,51,159,205,75,158,13,9,241,201,248,58,150,52,199,114,253,88,242, - 155,10,172,89,179,102,17,128,213,91,183,110,69,67,67,3,0,96,201,146, - 231,209,209,209,129,142,142,14,52,55,55,195,239,247,163,190,190,30,91,183, - 110,5,128,213,181,105,172,174,221,187,119,47,2,176,122,206,156,57,168,170, - 170,2,0,60,254,248,227,41,231,85,85,85,97,206,156,57,25,211,83,140, - 143,172,135,9,120,189,94,179,97,182,58,6,36,68,34,159,75,221,108,216, - 176,97,115,103,103,39,246,238,221,139,13,27,6,1,0,157,157,43,208,217, - 217,137,154,154,154,205,64,254,86,31,160,188,128,132,0,141,164,157,215,188, - 138,89,135,175,188,242,202,150,13,27,6,55,111,216,240,93,115,95,77,77, - 226,125,103,231,159,229,156,151,44,96,91,154,154,180,205,77,77,130,191,146, - 203,171,169,169,9,91,154,154,210,94,155,235,253,188,248,226,139,248,240,135, - 63,12,0,248,192,7,134,80,87,247,111,168,173,131,56,119,206,48,207,89, - 176,32,241,188,214,222,150,219,162,164,61,253,55,2,72,148,247,186,101,55, - 230,90,180,49,211,124,226,70,141,11,139,252,57,23,184,48,54,159,184,81, - 163,244,144,133,27,82,190,150,167,49,22,248,195,199,29,119,220,129,239,60, - 243,204,152,211,146,249,139,7,30,16,251,246,237,51,63,143,183,127,244,192, - 129,3,59,239,191,255,126,52,52,52,160,185,185,25,91,182,44,196,209,163, - 23,176,110,221,58,12,15,15,195,239,247,99,235,214,147,88,181,170,26,215, - 95,95,143,251,239,191,31,59,119,238,108,170,173,173,181,236,67,59,121,242, - 228,206,101,203,150,153,226,118,243,205,55,227,23,191,248,69,210,57,135,14, - 29,194,194,133,11,177,112,225,66,44,91,182,12,0,108,211,83,140,143,156, - 162,40,173,26,230,66,193,172,16,203,124,11,97,241,0,133,183,174,138,85, - 135,86,150,155,21,217,90,168,91,154,154,52,190,89,157,83,87,87,135,161, - 161,33,75,241,203,116,173,29,47,190,248,98,210,231,55,222,120,3,0,112, - 246,236,173,56,123,246,86,132,195,141,230,118,246,236,173,185,36,109,50,183, - 234,40,86,175,110,194,111,78,30,197,254,253,176,125,253,232,221,255,99,68, - 12,75,147,241,136,210,120,174,37,168,143,242,142,59,238,64,123,91,155,214, - 222,214,166,237,219,183,15,181,117,117,226,47,30,120,96,92,22,226,95,60, - 240,128,168,173,171,19,251,246,237,51,211,190,227,142,59,144,135,126,209,213, - 27,54,108,192,240,240,48,58,58,58,112,239,189,43,241,202,43,97,212,212, - 124,23,126,191,31,53,53,223,197,182,109,111,226,250,235,253,240,251,253,216, - 176,97,3,144,26,52,146,148,158,211,233,52,63,220,114,203,45,0,70,173, - 184,199,31,127,28,191,248,197,47,176,112,225,66,0,192,200,185,233,210,83, - 140,131,172,5,78,215,245,49,29,27,15,175,188,242,10,54,108,24,52,45, - 15,32,97,133,212,212,124,55,201,226,201,87,94,53,53,223,53,243,227,91, - 190,242,42,102,29,234,186,142,206,206,63,51,173,53,0,230,103,158,87,103, - 103,39,54,108,216,176,121,60,247,198,173,183,158,158,158,113,148,58,97,237, - 13,13,13,165,8,27,97,183,159,104,107,51,210,30,183,162,167,255,70,204, - 173,58,154,244,186,102,205,126,92,183,44,100,249,122,238,92,126,220,148,147, - 29,46,44,92,216,184,197,198,133,110,172,34,71,86,27,165,69,251,191,243, - 204,51,73,66,103,85,174,108,168,175,175,7,61,224,250,253,126,108,220,120, - 3,128,81,143,199,169,83,247,192,239,247,99,120,120,216,116,99,2,246,225, - 254,100,189,17,55,223,124,51,128,81,145,123,244,209,71,45,207,181,75,79, - 49,118,178,18,184,206,206,78,173,190,190,222,246,120,125,125,189,185,26,119, - 62,41,166,197,88,232,188,138,89,135,185,230,53,86,11,213,202,26,211,70, - 226,23,198,226,134,164,235,102,204,152,129,15,127,248,195,166,91,82,126,181, - 188,110,203,104,213,9,236,23,181,117,7,69,109,221,193,172,26,58,89,220, - 230,86,29,77,164,35,26,45,55,0,112,151,237,159,150,125,86,50,220,106, - 75,231,138,36,145,27,11,36,110,118,199,191,243,204,51,227,178,230,168,143, - 109,209,162,69,24,30,30,198,67,15,45,51,143,145,184,209,121,195,195,195, - 57,151,159,172,56,32,89,220,20,133,39,171,62,56,26,75,85,83,83,131, - 51,103,206,152,22,141,174,235,73,141,101,62,251,223,40,125,178,64,228,254, - 163,66,89,60,118,199,198,75,49,235,80,206,139,215,25,207,139,250,232,198, - 210,39,199,33,235,173,173,173,13,114,43,52,86,161,3,96,43,102,73,233, - 111,217,130,205,155,71,181,153,4,8,0,174,186,234,103,89,229,99,101,193, - 1,251,109,207,143,68,128,83,167,170,113,195,13,251,69,52,178,38,237,253, - 89,245,169,157,56,145,189,155,83,190,126,44,174,68,187,126,189,92,202,97, - 71,91,91,27,234,234,234,242,218,207,54,22,190,243,204,51,90,109,93,157, - 160,242,228,66,115,115,51,26,26,26,80,95,95,111,138,88,103,231,159,153, - 125,112,196,240,240,176,105,233,165,163,191,191,63,197,138,179,19,182,254,254, - 254,156,202,170,200,141,140,2,199,7,10,111,223,190,125,75,125,125,125,210, - 147,126,161,196,173,179,179,83,171,169,169,17,20,248,33,147,111,139,167,144, - 121,21,179,14,179,205,107,195,134,193,113,245,41,202,214,81,91,219,106,212, - 213,29,68,123,91,254,187,19,172,132,78,22,54,190,127,148,53,89,165,111, - 109,193,133,210,230,185,100,201,121,148,149,37,234,33,93,80,139,141,32,101, - 109,101,228,163,111,44,77,26,227,182,66,73,76,106,235,234,196,68,14,136, - 39,203,45,87,113,3,112,112,251,246,237,171,159,122,234,41,83,220,248,43, - 199,239,247,99,251,246,237,0,112,48,93,122,241,120,60,235,63,65,60,30, - 207,148,158,98,28,164,21,56,185,177,4,18,98,32,247,215,228,91,220,120, - 222,153,172,144,66,88,60,249,180,174,138,89,135,57,228,181,153,123,100,115, - 181,80,121,163,78,239,105,92,213,216,74,158,29,92,232,54,111,222,108,10, - 142,252,74,236,218,149,31,11,46,31,86,226,84,164,148,102,120,25,107,89, - 22,45,90,212,180,115,231,206,253,27,54,108,72,178,224,100,113,3,18,150, - 222,206,157,59,177,104,209,162,38,0,3,86,233,61,255,252,243,77,0,246, - 175,88,177,34,197,138,147,233,239,239,199,201,147,39,233,26,203,244,20,227, - 195,86,224,172,26,75,106,132,11,33,104,233,242,46,5,139,39,95,226,86, - 168,58,204,148,87,161,173,97,178,232,50,89,52,217,114,239,189,247,226,220, - 185,115,230,231,5,11,22,152,239,235,234,254,13,0,44,45,184,177,48,99, - 198,27,232,233,255,64,138,5,151,79,43,177,152,140,103,76,91,161,198,195, - 177,126,186,156,175,189,227,142,59,176,111,223,190,130,88,136,237,237,237,7, - 52,77,59,248,208,67,15,173,222,186,117,107,138,200,209,107,115,115,51,30, - 122,232,33,96,212,218,26,128,133,40,181,183,183,31,120,248,225,135,15,246, - 246,246,174,6,82,3,78,136,254,254,126,244,246,246,102,76,79,49,62,44, - 5,46,93,99,89,104,74,212,226,201,57,175,98,214,97,166,188,138,213,255, - 39,91,117,99,79,39,181,33,107,111,107,51,223,215,214,37,91,138,227,17, - 186,246,182,54,237,222,123,239,21,64,29,128,79,98,244,245,217,188,90,137, - 233,144,69,101,44,34,195,199,190,229,50,142,205,106,28,94,62,220,162,4, - 185,14,199,51,30,238,59,207,60,163,141,68,82,10,32,255,150,227,162,69, - 139,154,14,28,56,208,180,124,249,242,213,247,223,127,63,54,108,216,128,134, - 134,6,179,207,109,251,246,237,216,185,115,39,48,50,39,37,70,132,168,189, - 189,221,214,138,187,231,158,123,154,58,58,58,86,47,91,182,12,78,167,211, - 20,186,254,254,126,196,227,113,156,60,121,18,24,153,147,50,83,122,138,177, - 147,50,217,114,169,137,219,68,137,66,169,166,157,107,94,242,113,57,90,50, - 93,249,210,77,182,76,22,155,149,168,229,203,138,75,151,119,54,99,222,174, - 186,234,103,57,15,250,182,203,195,78,224,198,146,135,72,76,145,101,94,35, - 139,10,125,150,207,27,11,233,210,16,128,88,190,252,104,94,250,249,38,19, - 118,147,45,215,214,214,54,118,116,116,52,193,102,178,229,145,247,100,105,13, - 100,18,164,218,218,218,198,123,238,185,199,50,189,17,97,179,76,79,77,182, - 156,63,82,44,56,106,4,229,134,175,166,230,187,162,179,243,207,178,254,35, - 228,126,126,233,136,194,120,177,171,195,212,114,36,215,81,174,117,150,41,175, - 66,90,168,133,20,176,108,242,190,234,170,132,192,242,153,76,56,52,171,73, - 190,200,151,59,212,10,89,96,138,41,56,211,77,220,210,49,50,147,72,163, - 205,212,89,220,133,152,81,220,10,145,158,34,119,44,151,203,161,6,48,185, - 177,252,174,0,128,108,26,224,92,206,77,156,63,117,196,141,176,170,195,228, - 114,164,214,81,174,245,150,46,175,124,220,103,174,203,229,200,86,221,100,166, - 24,86,162,98,98,176,179,224,56,54,131,174,199,44,68,185,164,167,44,184, - 252,145,245,122,112,212,248,230,66,182,13,245,222,189,123,155,178,177,120,242, - 65,49,243,146,41,100,29,38,231,147,31,17,159,174,235,193,1,201,195,32, - 50,89,137,74,224,38,25,154,166,4,100,154,144,179,192,21,194,130,3,50, - 91,60,249,164,152,121,217,145,79,11,46,57,221,252,89,168,211,89,224,20, - 83,24,37,112,211,135,236,215,23,219,153,211,218,104,185,158,63,29,55,185, - 142,242,81,103,137,245,223,18,235,189,141,119,125,57,13,19,191,118,151,218, - 212,150,247,173,4,214,41,83,91,145,54,145,165,5,167,152,60,228,203,66, - 85,22,156,98,74,162,44,184,105,131,18,56,133,45,170,179,91,161,80,76, - 102,242,27,75,173,80,40,20,10,69,137,160,4,78,161,80,40,20,83,18, - 215,127,252,199,127,76,116,25,20,165,138,16,170,19,78,49,229,200,102,28, - 92,46,40,87,126,233,162,44,56,133,66,161,96,200,145,120,181,214,51,145, - 40,38,1,74,224,20,10,133,130,33,152,231,98,209,162,69,107,70,166,220, - 82,76,66,148,192,41,20,10,69,26,106,107,107,23,77,112,17,20,99,36, - 227,138,222,50,199,142,29,75,242,55,175,92,185,82,245,211,228,72,49,235, - 80,125,95,185,243,240,35,143,36,213,217,19,95,255,186,170,179,105,192,154, - 53,107,22,29,56,112,96,39,216,236,255,29,29,29,251,1,28,172,173,173, - 109,82,150,220,228,67,251,254,247,191,159,213,137,199,142,29,107,2,176,249, - 246,219,111,55,247,85,95,62,23,187,159,251,119,0,216,178,114,229,202,166, - 2,148,111,74,81,204,58,164,188,0,96,229,202,149,56,118,236,216,22,250, - 156,109,94,159,248,248,199,109,143,125,227,155,223,20,95,252,194,23,44,27, - 254,7,215,175,23,79,239,216,49,102,81,32,129,225,43,141,211,26,118,64, - 254,5,71,22,52,0,184,237,182,32,0,224,245,215,203,83,206,31,111,254, - 217,214,207,120,235,49,83,26,249,72,127,50,34,7,153,112,97,187,245,214, - 38,124,227,27,107,205,133,79,155,155,155,83,214,131,147,133,78,5,153,148, - 46,185,184,40,205,134,249,181,215,94,195,107,175,189,134,243,23,122,48,178, - 111,243,72,131,90,16,142,29,59,38,248,86,168,124,138,144,87,49,235,112, - 243,202,149,43,1,96,203,51,207,60,131,227,199,143,111,94,185,114,37,70, - 246,229,45,175,111,124,243,155,73,117,196,197,66,62,150,11,43,86,172,192, - 205,55,223,108,110,43,86,172,192,138,21,43,82,242,24,47,15,63,242,136, - 88,182,204,137,149,31,88,142,27,110,8,34,24,12,226,182,219,130,120,241, - 69,224,197,23,19,66,23,12,6,113,195,13,65,172,252,192,114,44,91,230, - 204,91,254,95,254,202,191,139,116,159,243,157,190,194,154,3,7,14,236,108, - 108,108,92,125,226,196,9,180,181,45,66,125,125,61,206,156,57,131,230,230, - 102,52,52,52,224,169,167,158,194,137,19,39,208,216,216,184,122,100,189,56, - 197,36,33,43,129,59,118,236,152,224,13,243,237,183,223,14,110,133,80,3, - 157,239,194,29,59,118,172,137,242,166,237,211,159,250,4,137,80,211,100,202, - 171,152,117,72,194,124,236,216,177,45,43,87,174,180,75,51,175,223,215,120, - 196,44,23,130,193,32,86,172,88,145,87,145,115,187,110,64,215,249,110,28, - 57,2,172,190,245,22,12,13,222,130,213,183,222,146,244,254,200,17,160,235, - 124,55,220,174,27,242,146,39,137,79,166,215,177,164,57,150,235,167,171,24, - 174,89,179,102,17,128,213,91,183,110,69,67,67,3,0,96,201,146,231,209, - 209,209,129,142,142,14,52,55,55,195,239,247,163,190,190,30,91,183,110,5, - 128,213,42,170,114,242,144,83,31,28,53,204,118,28,59,118,172,41,207,174, - 74,211,226,121,252,241,199,1,0,143,62,250,40,110,191,253,118,188,246,218, - 107,155,143,29,59,134,60,230,151,100,93,1,48,69,40,159,121,21,177,14, - 183,28,63,126,124,243,241,227,199,205,29,207,60,243,12,0,224,129,7,30, - 192,177,99,199,114,202,75,22,176,47,126,225,11,26,185,41,233,245,193,245, - 235,5,0,188,255,253,239,207,120,109,174,55,115,225,194,5,92,126,249,229, - 0,128,159,255,60,134,242,242,27,240,240,35,187,5,243,98,130,188,152,79, - 124,253,211,57,165,31,137,30,2,144,40,243,193,159,29,202,181,104,99,230, - 171,143,125,66,227,194,34,127,206,5,46,140,95,125,236,19,26,165,71,223, - 73,46,215,242,52,198,2,127,248,88,177,98,5,62,241,241,143,231,205,13, - 250,239,223,255,190,224,191,233,241,186,139,15,28,56,176,243,254,251,239,71, - 67,67,3,154,155,155,177,101,203,66,28,61,122,1,235,214,173,195,240,240, - 48,252,126,63,182,110,61,137,85,171,170,113,253,245,245,184,255,254,251,177, - 115,231,206,38,213,39,55,57,200,73,224,210,53,204,249,70,182,120,172,202, - 242,218,107,175,109,6,208,148,239,188,228,251,204,103,94,197,170,195,149,43, - 87,254,95,246,206,59,78,170,242,222,255,239,51,125,27,91,168,174,32,213, - 46,88,49,168,4,17,77,98,47,55,196,144,68,163,215,18,11,94,19,115, - 99,162,185,94,90,188,154,246,139,87,13,177,144,228,146,196,24,107,44,160, - 24,11,77,108,116,68,1,145,182,44,44,44,44,219,152,157,157,254,252,254, - 56,115,102,207,204,78,159,217,5,118,191,239,215,107,94,179,115,206,121,202, - 57,51,251,124,206,183,60,231,137,17,183,100,68,172,189,180,49,185,76,68, - 169,184,184,152,96,48,152,80,252,50,238,120,28,102,97,3,248,234,87,191, - 202,251,239,7,153,52,169,111,194,227,23,46,60,144,117,27,14,251,120,250, - 246,93,198,249,19,198,227,15,44,195,97,79,246,62,32,34,134,157,227,114, - 135,3,249,8,100,62,101,13,12,97,51,139,218,79,238,189,87,253,228,222, - 123,85,190,66,103,8,219,170,85,171,162,162,246,143,231,158,83,70,155,121, - 8,221,249,119,223,125,55,110,183,155,29,59,118,112,237,181,95,99,250,244, - 151,25,50,228,47,212,214,222,192,144,33,127,1,224,7,63,24,69,105,105, - 41,119,223,125,55,115,231,206,61,63,77,157,194,97,66,214,89,148,221,141, - 97,185,197,127,254,217,207,126,6,20,214,106,52,234,142,23,134,174,104,171, - 171,89,177,98,5,183,223,126,59,16,107,185,25,251,12,34,9,40,121,89, - 168,102,235,205,239,247,231,213,239,255,125,244,81,181,99,199,142,78,194,102, - 80,95,95,15,36,22,55,0,143,39,251,54,19,137,217,71,31,157,3,132, - 128,206,239,22,153,92,3,232,226,101,8,75,50,17,51,239,255,199,115,207, - 169,92,68,206,16,183,120,17,51,234,50,132,206,220,86,54,130,103,196,220, - 0,74,75,75,185,231,158,83,121,228,145,117,81,113,219,184,241,155,148,150, - 150,226,118,187,163,110,76,208,167,15,108,223,190,125,71,182,231,35,116,31, - 25,253,171,142,29,59,86,75,100,69,25,68,246,205,44,80,159,122,36,221, - 121,13,51,156,10,16,223,86,214,49,185,68,150,153,145,149,151,171,213,246, - 163,31,254,80,179,217,108,12,28,56,48,42,114,241,239,137,216,188,121,115, - 244,239,59,167,62,163,126,114,175,254,202,164,205,68,22,27,192,229,151,247, - 77,248,2,184,235,63,50,171,187,167,147,169,133,246,219,223,252,70,203,196, - 163,144,136,68,226,102,230,59,83,166,104,70,92,54,151,216,172,17,99,27, - 54,108,24,110,183,155,31,255,248,180,232,62,67,220,140,227,220,110,119,46, - 167,32,28,34,50,178,224,140,164,133,68,238,59,243,192,220,21,214,141,97, - 61,197,91,110,93,65,87,214,221,157,215,208,148,100,2,36,180,220,102,2, - 24,49,186,92,98,114,102,12,235,205,147,192,124,202,199,61,153,76,204,204, - 108,222,188,57,38,230,103,8,16,100,238,174,76,100,193,233,22,91,98,194, - 97,152,56,209,9,60,163,126,255,120,234,120,95,34,183,95,75,75,230,113, - 190,248,242,185,196,198,146,185,30,179,233,71,50,60,30,15,197,197,197,5, - 141,179,229,194,119,166,76,209,126,114,239,189,202,232,79,54,24,217,146,198, - 212,0,183,219,77,109,237,13,209,24,156,129,219,237,142,90,122,194,145,65, - 90,129,139,75,149,159,25,137,69,153,233,18,113,139,88,60,42,89,204,170, - 208,22,79,87,182,213,157,215,48,190,45,244,41,1,157,218,90,181,106,85, - 94,89,148,241,214,145,199,243,17,197,197,231,0,179,243,169,54,33,137,132, - 46,94,216,204,219,59,72,238,202,52,147,216,130,11,165,108,115,241,98,31, - 22,139,126,29,82,37,181,36,18,164,76,18,63,82,149,207,150,100,117,100, - 211,143,100,24,98,146,173,91,176,208,24,150,91,182,226,6,44,121,236,177, - 199,206,127,252,241,199,163,226,102,126,55,83,90,90,202,99,143,61,6,176, - 164,32,157,22,186,156,148,2,151,96,176,100,236,216,177,90,124,218,124,87, - 88,110,241,22,143,217,186,234,42,139,167,43,172,171,238,188,134,89,180,101, - 204,145,51,202,101,213,142,121,80,143,253,251,156,46,117,219,153,133,238,184, - 227,142,139,10,78,252,187,193,174,93,133,177,224,10,97,37,246,68,14,167, - 39,188,228,218,151,97,195,134,205,152,59,119,238,162,187,239,190,59,198,130, - 139,23,55,208,45,189,185,115,231,50,108,216,176,25,64,115,158,93,22,186, - 129,164,2,151,100,176,156,97,126,239,42,14,165,197,83,200,182,186,243,26, - 166,107,107,197,138,21,202,44,106,9,200,203,26,54,44,186,116,22,77,166, - 172,90,181,42,233,147,76,138,139,245,185,104,137,44,184,92,176,217,190,138, - 63,240,126,39,11,174,144,86,98,119,146,79,54,100,87,205,135,51,226,116, - 185,96,196,215,186,66,80,183,111,223,190,88,211,180,37,63,254,241,143,207, - 255,221,239,126,215,73,228,140,247,53,107,214,240,227,31,255,24,58,172,183, - 102,68,228,14,123,18,10,92,170,193,178,171,57,76,45,158,172,219,234,206, - 107,152,174,173,248,152,156,33,116,241,49,185,124,251,151,200,170,203,173,158, - 212,3,89,188,123,52,31,161,251,237,111,126,163,233,238,173,98,96,53,29, - 239,167,22,212,74,76,69,33,158,104,98,158,251,150,205,60,182,68,243,240, - 10,225,22,53,72,52,117,32,91,190,51,101,138,86,160,41,1,9,25,54, - 108,216,140,197,139,23,207,56,227,140,51,206,191,241,198,27,185,251,238,187, - 57,253,244,211,163,49,183,248,71,117,17,17,182,237,219,183,139,192,29,230, - 116,18,184,195,80,220,102,116,69,31,186,178,173,195,81,220,76,251,19,198, - 228,178,233,223,111,127,115,157,102,136,76,33,172,181,66,145,171,208,37,26, - 48,141,243,43,148,149,24,79,50,65,50,127,206,53,70,150,173,64,153,143, - 47,164,184,65,225,196,168,43,147,88,34,19,182,39,14,31,62,124,226,220, - 185,115,103,36,152,231,102,8,27,116,88,110,34,110,71,0,137,44,56,227, - 161,188,49,3,95,196,197,149,241,143,44,151,227,227,250,112,200,68,161,0, - 36,188,134,137,250,97,190,70,217,94,179,116,109,117,165,133,122,40,133,77, - 111,251,153,200,3,153,19,31,99,242,104,22,132,174,18,58,232,44,42,133, - 22,153,108,218,238,205,152,133,46,193,110,179,168,53,139,245,118,100,144,112, - 53,1,99,0,76,52,88,102,50,0,103,115,172,249,248,8,71,186,184,25, - 237,204,72,85,119,162,107,148,237,117,75,213,86,33,206,51,213,106,2,137, - 56,28,173,186,92,249,201,189,207,168,100,79,75,49,179,112,225,129,30,113, - 190,189,137,248,213,4,18,145,100,13,184,132,194,38,171,9,28,190,100,179, - 92,78,214,95,98,22,2,55,131,12,44,158,66,208,157,109,37,104,187,203, - 174,97,138,118,114,62,207,108,5,174,39,97,142,243,165,179,18,69,224,142, - 48,52,77,4,169,151,144,245,163,186,178,177,224,178,168,115,134,41,1,98, - 70,182,125,58,92,219,74,208,118,74,107,45,87,11,206,204,161,140,161,246, - 36,68,180,4,225,200,39,43,129,203,116,224,141,196,121,178,22,185,108,142, - 207,135,195,97,192,79,118,141,10,176,226,118,70,241,63,65,16,132,158,78, - 198,46,74,225,200,33,93,252,47,83,122,179,139,82,232,193,136,139,178,215, - 112,216,175,38,32,100,79,193,172,54,25,8,4,65,56,130,145,133,63,4, - 65,16,132,30,137,8,156,32,8,130,208,35,209,36,85,76,16,142,48,196, - 117,44,8,25,33,22,156,32,8,130,208,35,145,36,19,161,215,162,160,160, - 150,144,6,49,14,145,174,174,95,16,132,212,196,184,40,187,243,31,82,218, - 202,191,173,238,162,208,231,100,166,16,231,151,174,127,249,180,241,135,199,230, - 42,128,59,239,190,177,75,190,135,156,234,23,23,165,32,100,68,140,5,151, - 233,64,96,252,83,166,227,206,187,111,76,186,175,59,219,122,226,177,185,153, - 84,81,144,65,172,59,219,202,132,203,47,191,66,1,204,159,63,47,231,246, - 52,208,20,40,243,185,221,113,247,141,49,223,97,190,251,243,69,37,121,190, - 160,38,81,102,65,232,181,228,21,131,123,244,207,103,38,124,207,150,227,79, - 91,175,18,189,119,5,133,234,115,161,232,234,115,159,55,127,30,243,230,207, - 43,100,149,135,4,5,202,120,117,69,253,153,124,15,217,124,87,93,241,27, - 238,202,255,11,65,232,137,228,20,131,51,139,66,34,193,248,225,77,171,50, - 174,43,217,160,209,241,207,156,121,93,233,72,38,110,135,66,228,204,131,85, - 162,115,255,98,237,232,130,186,238,20,168,195,193,221,153,15,239,45,108,7, - 224,194,73,69,5,61,151,212,191,193,85,105,143,137,255,174,10,253,61,198, - 255,86,190,88,55,38,223,42,5,161,87,144,115,146,201,121,99,211,250,156, - 107,0,0,32,0,73,68,65,84,75,18,110,255,96,69,219,33,173,235,112, - 106,43,29,93,217,23,67,220,12,33,48,172,159,124,133,33,221,13,76,190, - 251,187,27,67,60,226,191,139,63,205,25,193,205,183,110,139,126,62,111,108, - 73,167,109,160,127,87,241,66,102,212,149,234,123,76,244,93,164,250,126,204, - 253,251,98,93,186,179,18,4,1,210,184,40,147,185,132,146,13,204,198,190, - 149,235,39,100,212,248,77,183,110,83,70,93,127,154,51,130,63,205,25,145, - 113,59,217,178,114,253,132,180,253,142,167,43,93,98,137,6,84,227,252,207, - 27,91,194,77,183,110,203,171,221,68,3,101,33,196,237,188,177,37,73,45, - 222,124,247,103,202,123,11,219,11,150,248,114,222,216,146,132,223,69,50,18, - 253,70,147,253,174,146,125,143,169,250,158,237,255,155,32,8,201,73,41,112, - 230,187,255,174,238,136,113,103,156,106,112,233,78,226,45,160,174,196,56,231, - 120,235,32,95,170,171,171,163,34,93,93,93,157,119,125,198,64,155,106,64, - 207,103,127,60,241,113,183,11,39,21,101,215,225,28,72,245,93,20,226,55, - 154,234,119,213,157,255,111,130,208,27,72,155,100,210,27,69,174,39,136,27, - 192,158,186,58,45,209,223,71,2,10,212,123,11,219,137,127,25,34,87,72, - 43,206,32,147,239,34,159,223,104,38,191,43,17,57,65,40,28,25,197,224, - 140,52,241,238,72,84,184,249,214,109,81,119,93,87,12,250,233,232,41,226, - 6,112,219,127,220,174,158,124,252,201,232,223,79,61,254,228,17,33,114,134, - 184,37,194,16,185,100,251,51,37,222,117,104,22,172,152,191,83,212,97,254, - 141,26,245,253,121,206,136,78,215,248,166,91,183,41,115,157,102,241,50,220, - 249,137,4,45,95,55,181,32,244,118,162,2,151,234,31,222,76,166,119,150, - 233,226,112,230,246,146,181,245,167,57,35,32,195,193,255,166,91,183,169,68, - 131,75,38,125,49,136,207,58,52,239,139,23,161,100,3,217,202,245,25,53, - 149,116,64,53,183,149,234,156,50,193,16,55,227,239,35,66,221,178,32,34, - 118,57,137,128,113,93,141,223,161,113,99,101,252,109,112,214,232,165,64,236, - 111,40,209,113,169,190,167,63,207,25,161,105,36,190,121,58,107,244,82,93, - 24,227,230,12,38,234,163,32,8,217,17,21,184,248,127,208,248,255,214,184, - 127,206,180,255,112,103,141,94,202,159,83,236,255,243,156,17,154,121,112,49, - 99,30,64,140,1,38,29,169,38,78,159,53,122,105,70,34,103,88,170,198, - 223,113,253,77,91,254,207,115,70,104,153,78,76,39,201,128,26,95,95,70, - 117,37,224,242,203,175,80,243,230,207,139,113,121,93,126,249,21,42,219,9, - 223,233,68,54,213,126,99,95,188,5,147,77,253,221,73,38,222,131,124,172, - 238,76,60,33,221,233,65,16,132,158,78,70,19,189,123,146,219,46,29,61, - 37,230,104,22,55,208,207,43,151,9,223,230,27,145,120,204,2,150,170,108, - 58,1,204,186,83,93,72,170,239,164,16,191,205,84,191,47,17,55,65,40, - 44,105,5,174,55,137,155,193,145,46,114,103,158,121,86,210,126,167,218,151, - 140,100,34,100,108,79,231,158,203,101,95,38,92,56,169,40,239,223,229,7, - 43,218,58,205,87,203,36,201,36,85,249,248,253,241,100,146,100,98,230,207, - 115,70,104,135,98,158,166,32,28,233,164,76,50,233,141,226,102,112,36,39, - 214,172,92,181,50,105,26,250,202,85,43,213,225,110,30,104,160,93,56,169, - 40,97,162,73,33,18,76,204,124,177,118,180,118,252,105,235,85,188,128,156, - 112,218,122,62,88,209,198,89,163,245,207,31,172,104,139,110,75,84,135,249, - 115,38,98,148,203,60,69,17,57,65,200,142,180,243,224,18,253,211,165,187, - 99,205,52,110,102,190,51,189,249,214,109,9,239,142,11,197,89,163,151,230, - 116,167,221,85,226,150,200,106,48,206,255,131,21,109,57,91,55,103,158,115, - 86,74,65,214,64,59,243,156,236,173,184,238,38,34,114,196,191,76,143,235, - 42,216,141,151,33,80,201,222,51,61,38,209,177,133,120,84,87,186,246,4, - 65,72,76,206,143,234,42,164,248,116,231,157,233,225,116,23,220,21,125,89, - 249,209,202,180,163,126,38,199,36,226,131,21,109,156,55,182,36,105,191,243, - 221,31,143,89,192,82,77,29,40,4,217,10,87,178,99,226,143,237,138,62, - 10,130,144,25,57,173,38,96,60,75,48,209,123,182,207,25,52,223,229,102, - 51,128,228,130,185,127,201,222,187,139,84,231,156,235,121,159,121,102,106,235, - 205,64,3,45,151,88,220,15,111,90,197,7,43,218,146,94,171,124,247,103, - 74,33,173,55,65,16,122,46,57,91,112,133,22,136,174,22,55,51,135,90, - 220,12,10,125,206,171,86,173,204,184,124,54,199,154,73,119,173,242,221,223, - 157,100,146,68,116,71,199,58,131,105,143,141,23,221,174,174,95,16,132,212, - 196,8,92,166,89,131,166,127,202,148,164,250,111,236,206,182,50,173,131,12, - 251,148,106,160,233,206,182,122,27,198,99,186,10,117,77,186,250,218,202,119, - 39,8,135,150,156,86,244,46,4,210,150,144,13,114,93,5,65,200,22,77, - 70,13,33,29,93,57,31,176,16,194,149,174,127,61,78,28,53,237,176,207, - 130,21,132,195,1,17,56,161,247,33,2,33,8,189,130,156,178,40,5,65, - 16,4,225,112,71,4,78,16,4,65,232,145,136,139,82,16,142,52,196,197, - 42,8,25,33,22,156,32,8,130,208,35,201,121,162,183,32,28,233,252,244, - 103,63,43,168,37,244,235,95,253,42,198,33,50,115,214,172,130,214,63,125, - 218,52,113,184,8,66,22,196,184,40,167,77,159,94,208,127,200,89,51,103, - 38,253,135,148,182,242,111,171,187,40,244,57,153,41,196,249,165,235,95,62, - 109,124,184,108,165,2,56,119,252,89,93,242,61,172,248,100,173,2,24,251, - 149,211,50,175,95,92,148,130,144,17,57,197,224,62,249,120,77,70,255,96, - 95,25,119,122,222,131,66,33,218,58,210,250,91,72,158,249,251,223,21,192, - 117,223,251,94,94,237,77,155,62,93,93,118,201,213,209,207,111,44,120,53, - 70,56,242,221,159,111,223,102,204,152,145,112,223,140,25,51,68,224,4,161, - 151,146,87,12,238,147,53,71,37,124,207,150,199,158,216,171,18,189,119,5, - 133,234,115,161,232,234,115,223,188,121,51,155,55,111,46,100,149,135,132,105, - 211,167,43,227,213,21,245,255,230,127,247,168,68,239,217,30,99,240,251,167, - 234,11,222,207,174,168,83,16,122,50,57,9,220,39,107,142,74,42,20,217, - 10,70,178,1,254,177,39,246,170,66,15,246,169,250,220,221,66,103,62,191, - 174,18,57,179,24,116,165,155,177,187,248,254,13,255,197,247,111,248,175,130, - 159,75,50,225,50,11,88,38,199,24,24,66,84,40,65,250,253,83,245,170, - 208,117,10,66,111,32,103,11,110,72,181,35,225,235,80,215,117,56,181,117, - 40,251,98,136,192,172,153,51,53,195,69,87,8,97,72,119,35,144,239,254, - 238,198,16,168,161,131,29,49,175,253,123,254,151,161,131,59,190,11,243,54, - 243,203,92,135,193,144,106,59,67,170,237,41,219,77,148,128,146,42,41,197, - 168,51,93,189,130,32,116,144,82,224,146,185,132,82,13,194,67,170,29,212, - 213,15,205,168,241,87,94,107,84,70,93,107,86,63,202,154,213,143,102,220, - 78,182,212,213,15,77,219,239,120,186,210,37,22,223,158,249,252,135,84,59, - 120,229,181,198,188,218,77,20,119,202,55,230,245,201,154,163,24,82,237,72, - 42,82,249,238,207,148,66,90,113,102,161,50,88,185,226,215,73,143,143,223, - 151,168,188,193,144,106,59,175,205,235,252,61,166,18,178,68,251,68,212,4, - 33,55,82,10,92,33,239,252,211,113,250,25,63,4,232,36,114,135,10,179, - 5,212,213,109,25,231,108,92,131,66,81,86,86,22,21,233,178,178,178,188, - 235,51,68,57,217,141,66,190,251,227,137,143,187,253,245,47,255,147,93,135, - 115,192,16,176,179,198,254,180,211,62,99,91,42,1,76,135,33,96,137,82, - 254,141,109,133,158,94,32,8,189,149,180,46,202,222,40,114,61,65,220,0, - 238,253,201,79,180,68,127,31,9,76,155,62,93,25,49,55,243,203,16,185, - 174,136,197,165,18,55,131,124,68,46,149,184,25,136,200,9,66,225,200,104, - 162,247,172,153,51,53,227,78,186,171,7,253,211,207,248,97,212,93,215,21, - 131,126,58,122,138,184,1,188,254,198,60,181,114,249,202,232,223,87,94,118, - 197,17,33,114,134,184,37,194,16,185,100,251,51,229,133,151,14,196,8,136, - 89,176,98,254,78,81,199,202,21,191,142,10,158,81,223,181,147,251,118,186, - 198,175,205,107,84,107,215,252,62,250,217,44,94,117,251,142,233,180,205,92, - 46,221,121,8,130,144,156,168,192,197,199,124,146,89,81,153,222,53,167,139, - 195,153,219,75,214,214,154,213,143,66,134,131,255,43,175,53,170,107,174,170, - 74,56,128,103,26,19,76,149,117,24,47,66,137,218,122,229,181,70,85,87, - 159,81,83,49,231,28,127,254,70,91,169,206,41,19,12,113,139,255,187,167, - 16,17,185,156,68,192,16,34,67,152,206,26,251,211,132,22,220,224,65,219, - 1,216,181,119,120,116,91,162,227,18,9,155,193,85,87,84,197,88,101,102, - 11,110,197,39,87,42,128,171,76,219,140,227,140,114,34,116,130,144,27,81, - 129,75,55,144,154,45,155,87,94,251,97,218,127,184,234,129,53,41,247,95, - 115,85,149,102,136,92,188,120,152,45,155,116,245,24,164,154,56,93,61,176, - 38,35,145,51,44,85,227,239,216,189,51,211,150,191,230,170,42,45,211,137, - 222,68,44,85,72,110,193,229,35,110,207,252,253,239,106,243,230,205,49,46, - 230,103,254,254,119,149,237,132,239,116,34,155,106,191,177,239,149,215,26,85, - 178,155,152,124,69,188,144,24,34,103,182,204,226,201,196,141,153,140,233,211, - 166,105,51,103,205,82,51,103,205,82,201,220,148,153,184,49,5,65,200,140, - 140,166,9,244,36,183,93,58,122,74,204,209,44,110,160,159,87,46,19,190, - 205,55,34,241,152,5,44,85,217,116,2,152,117,167,186,144,84,49,182,124, - 196,205,32,85,140,77,196,77,16,10,75,90,129,235,77,226,102,112,164,139, - 220,147,79,62,149,180,223,169,246,37,35,153,8,25,219,83,137,84,174,251, - 50,225,175,127,249,159,188,127,151,53,187,252,212,236,242,199,108,203,36,201, - 36,85,121,51,181,117,129,78,219,50,73,50,49,115,213,21,85,90,162,122, - 4,65,72,77,218,121,112,208,187,196,205,224,72,22,185,186,61,117,73,231, - 193,213,237,169,43,72,27,93,201,172,153,51,181,100,83,2,10,145,96,98, - 230,222,31,29,165,65,135,80,25,175,254,71,253,40,70,184,204,219,204,47, - 115,29,6,181,117,129,232,43,25,169,166,9,36,35,93,157,130,32,196,146, - 118,30,92,162,129,178,182,46,213,29,171,63,227,184,217,53,87,85,105,70, - 93,167,159,241,195,78,226,150,170,157,108,169,30,88,147,182,223,241,36,59, - 255,66,16,223,158,249,252,107,235,252,57,91,55,79,206,121,42,101,166,235, - 172,153,51,181,39,231,100,111,197,117,55,134,200,197,191,12,113,43,132,245, - 102,96,8,84,178,247,76,143,49,184,235,182,129,154,241,110,252,157,47,230, - 58,11,81,159,32,244,6,114,94,15,174,144,226,83,200,186,14,167,182,210, - 209,21,125,169,219,149,222,66,203,228,152,68,212,214,249,25,82,237,72,218, - 239,124,247,199,19,191,26,65,33,45,183,120,50,17,174,76,142,49,232,10, - 33,18,113,19,132,236,200,233,89,148,95,57,125,79,210,119,227,239,76,185, - 251,142,65,218,221,119,12,210,140,191,19,189,23,10,115,255,146,189,119,23, - 169,206,57,215,243,126,242,201,212,214,155,193,172,153,51,181,92,98,113,95, - 57,125,15,181,117,254,164,215,42,223,253,153,82,72,235,77,16,132,158,75, - 206,22,92,161,5,162,171,197,205,204,161,22,55,131,66,159,243,237,183,223, - 150,113,249,108,142,53,147,238,90,229,187,191,59,201,100,69,239,87,231,189, - 152,241,177,185,172,232,253,230,191,94,207,248,88,201,174,20,132,236,136,17, - 184,76,19,42,222,88,240,106,222,13,119,103,91,153,214,145,105,159,82,89, - 15,221,217,86,111,195,72,60,41,212,53,137,23,164,66,35,130,36,8,135, - 150,24,129,235,206,193,84,218,18,178,65,174,171,32,8,217,162,201,168,33, - 164,163,43,167,74,20,66,184,210,245,175,199,137,163,166,29,246,89,176,130, - 112,56,32,2,39,244,62,68,32,4,161,87,144,243,138,222,130,32,8,130, - 112,56,35,2,39,8,130,32,244,72,114,158,38,32,8,135,37,226,126,20, - 4,33,130,88,112,130,32,8,66,143,68,4,78,16,4,65,232,145,164,117, - 81,42,211,138,201,26,164,76,186,204,230,216,116,101,11,89,87,161,142,77, - 87,86,250,92,152,99,211,149,205,167,46,65,16,122,15,25,89,112,11,23, - 54,179,112,97,115,204,64,19,143,2,101,28,151,45,201,202,102,210,46,64, - 88,41,21,86,42,230,152,76,251,172,148,34,174,104,198,125,78,84,54,211, - 62,39,226,112,191,206,9,235,140,92,131,92,250,156,232,123,203,180,108,38, - 237,10,130,208,187,17,23,165,32,8,130,208,35,201,74,224,146,221,229,27, - 119,217,185,144,73,217,84,214,69,58,11,32,85,159,115,177,220,50,45,155, - 171,69,148,170,236,161,188,206,105,235,79,98,77,101,210,110,178,239,48,147, - 178,98,197,9,130,144,140,132,2,167,64,25,47,128,73,147,42,50,174,208, - 56,54,190,142,108,203,102,219,174,166,105,228,218,103,45,242,60,151,92,250, - 108,46,155,109,187,71,226,117,142,111,79,203,226,89,56,241,125,206,181,108, - 182,237,10,130,208,59,233,52,76,36,187,107,158,52,169,34,26,7,153,52, - 169,34,26,220,55,31,111,62,38,190,108,162,100,128,76,203,38,106,23,58, - 238,252,53,77,203,170,172,217,2,75,85,54,89,159,51,41,155,172,207,137, - 234,49,99,174,51,213,117,78,86,54,147,235,156,77,187,201,234,137,63,95, - 243,53,201,246,183,97,148,181,152,84,43,219,178,209,118,101,30,156,32,8, - 17,98,44,184,84,46,161,133,11,155,83,222,233,39,27,132,140,178,169,44, - 140,116,101,83,181,155,76,100,10,81,54,85,159,243,105,55,149,139,83,41, - 149,246,58,167,42,155,238,58,231,218,110,186,223,70,42,139,42,221,247,219, - 85,101,5,65,232,221,228,148,100,98,12,254,93,29,19,74,214,46,164,143, - 189,37,43,219,213,177,183,100,237,230,210,222,225,112,157,179,110,47,34,178, - 185,180,107,124,167,185,148,149,88,156,32,8,241,72,22,165,32,8,130,208, - 35,17,129,19,4,65,16,122,36,57,9,156,145,132,160,129,150,77,6,158, - 153,92,202,154,147,31,44,89,6,95,204,125,206,53,110,147,75,217,100,9, - 27,217,148,61,148,215,57,235,246,34,201,30,185,180,107,124,167,185,148,77, - 150,96,35,8,66,239,37,70,224,82,13,44,169,130,253,144,58,177,34,221, - 128,153,174,108,170,118,83,37,71,228,91,54,85,159,243,105,55,149,80,166, - 74,94,129,212,137,21,233,6,249,116,101,211,245,57,213,249,166,138,77,166, - 251,126,187,170,172,32,8,189,155,132,195,93,162,96,125,170,20,242,248,148, - 238,78,141,164,18,138,52,101,211,165,174,155,167,10,100,219,103,115,138,121, - 182,125,78,85,54,93,159,205,245,100,219,231,67,117,157,83,245,57,209,20, - 129,76,219,77,52,69,32,219,178,49,237,202,52,1,65,16,34,36,116,81, - 70,93,121,145,65,35,155,140,54,227,216,248,58,178,45,155,109,187,74,41, - 114,237,115,116,160,204,161,207,230,178,217,182,123,36,94,231,248,246,178,177, - 160,226,251,156,107,217,108,219,21,4,161,119,146,85,12,46,217,221,125,87, - 199,136,82,89,21,233,98,113,169,250,220,149,177,184,66,196,222,18,181,123, - 168,174,115,218,250,147,184,71,51,105,55,217,119,152,73,89,137,189,9,130, - 144,12,201,162,20,4,65,16,122,36,105,109,24,115,204,37,221,157,114,54, - 199,166,43,91,200,186,10,117,108,186,178,210,231,194,28,155,174,108,202,186, - 36,6,39,8,66,4,121,208,145,208,179,16,129,19,4,33,130,184,40,5, - 65,16,132,30,137,8,156,32,8,130,208,35,177,1,220,58,107,181,242,123, - 15,2,224,112,149,49,103,218,25,49,158,75,99,127,252,190,100,219,19,81, - 136,58,210,213,29,223,127,243,118,155,173,136,63,205,58,187,203,61,178,133, - 106,211,168,39,190,142,100,219,11,85,71,186,223,66,244,184,105,203,149,223, - 239,193,225,40,166,180,114,48,143,220,83,93,216,107,43,174,70,65,16,242, - 68,251,193,172,213,106,237,178,185,52,236,218,0,64,191,193,39,113,218,248, - 27,163,3,219,228,59,95,84,95,172,157,135,199,221,64,213,160,81,140,25, - 119,29,127,154,117,182,22,191,221,92,38,158,66,212,145,136,155,167,45,87, - 251,235,54,176,125,195,66,220,205,117,49,253,7,48,159,87,105,69,53,195, - 79,154,68,255,234,147,50,22,134,112,48,148,182,15,22,155,53,42,4,183, - 198,93,203,108,218,140,111,127,237,178,185,52,238,221,66,113,105,63,142,63, - 237,10,94,250,195,183,180,155,167,45,87,159,126,252,76,167,237,133,170,35, - 190,255,241,191,5,131,27,238,91,172,54,127,250,38,141,251,182,80,82,210, - 151,163,71,142,165,106,192,113,84,13,60,174,147,208,25,66,24,246,251,211, - 95,75,135,3,135,163,152,57,179,206,150,117,221,4,65,200,27,155,223,123, - 144,134,93,27,88,252,214,159,217,187,119,47,83,110,252,57,94,183,62,169, - 118,242,157,47,170,207,62,254,7,53,91,62,96,249,135,239,113,229,181,63, - 162,165,161,134,43,111,153,219,105,187,81,38,158,66,212,17,143,33,108,203, - 223,253,61,77,251,183,113,160,254,75,54,125,182,34,166,255,22,155,53,122, - 94,173,173,173,156,125,238,133,52,237,223,70,101,255,17,92,121,203,92,149, - 76,116,204,131,124,32,224,77,219,23,187,221,69,191,193,39,69,69,49,151, - 54,227,49,215,115,194,41,99,9,120,221,92,121,203,92,213,210,80,211,105, - 251,228,59,95,84,137,68,46,151,58,188,238,230,164,191,5,128,123,30,169, - 83,141,245,155,169,219,182,156,93,91,62,224,131,247,158,227,228,83,207,97, - 255,158,13,244,63,234,36,142,30,57,150,27,238,91,172,12,161,187,117,218, - 114,245,197,186,215,169,223,189,1,191,191,45,237,181,116,56,74,24,120,244, - 73,220,58,109,185,154,243,139,175,164,61,94,16,4,33,21,182,112,48,68, - 32,224,165,181,181,149,230,230,102,2,1,47,237,238,3,49,2,100,136,135, - 187,121,15,53,91,222,167,113,239,22,234,118,172,98,211,103,43,216,185,115, - 103,82,33,48,139,91,174,117,152,73,38,108,173,173,173,236,221,187,55,218, - 127,0,227,188,12,22,191,59,143,226,226,226,180,162,99,22,134,84,180,182, - 182,2,224,241,120,98,132,32,151,54,227,49,247,125,241,187,243,152,120,209, - 21,4,130,94,170,6,141,194,221,188,39,102,187,113,157,227,69,46,219,58, - 174,188,101,174,106,119,31,232,244,91,48,184,231,145,58,85,251,229,251,108, - 251,252,93,246,238,92,71,203,129,26,252,126,63,31,47,123,155,96,48,200, - 248,137,151,118,18,186,166,134,237,212,110,95,193,146,55,254,168,95,219,20, - 86,156,207,231,163,173,173,141,235,239,120,152,225,39,94,148,242,218,11,130, - 32,100,130,205,252,33,24,12,226,107,107,234,36,64,134,120,28,108,174,227, - 139,213,243,240,123,154,249,98,211,58,246,238,221,27,29,232,227,73,36,110, - 217,214,97,144,76,216,128,232,96,220,216,216,136,219,237,198,110,119,117,42, - 239,241,120,104,110,110,198,239,247,167,21,29,179,48,180,182,182,226,241,120, - 146,14,204,30,143,135,96,48,24,61,222,98,179,98,183,187,162,125,50,202, - 230,42,116,198,117,121,251,205,151,249,218,215,175,96,127,221,70,252,158,230, - 152,237,95,191,244,155,209,235,157,200,146,203,180,14,67,252,124,109,77,128, - 254,91,48,83,251,229,251,172,95,254,60,117,219,150,243,249,186,143,240,251, - 253,248,124,62,154,155,117,97,127,107,254,11,216,237,118,46,252,198,53,81, - 161,43,173,24,72,208,235,6,160,169,169,9,159,207,71,32,16,72,120,174, - 134,192,249,253,109,25,185,51,5,65,16,210,97,139,223,16,47,64,198,96, - 237,245,122,241,121,91,240,121,91,216,177,99,7,173,173,173,52,52,52,36, - 20,149,120,113,203,165,14,200,76,216,90,91,91,113,187,221,4,131,65,110, - 185,253,30,70,157,242,13,28,174,82,252,145,129,21,58,44,7,143,199,147, - 86,116,246,238,88,73,208,231,137,30,111,12,224,137,8,6,131,184,221,29, - 237,56,92,101,84,12,24,201,217,231,94,200,171,47,253,141,96,48,72,107, - 107,43,54,155,45,43,161,51,132,210,232,187,199,227,225,157,183,231,49,97, - 194,132,152,115,242,120,60,73,69,46,219,58,204,226,23,207,173,211,150,171, - 85,75,230,80,183,109,57,107,86,44,225,224,193,131,180,181,181,225,118,187, - 9,4,2,49,55,0,207,254,245,73,74,74,74,184,238,166,159,81,214,54, - 152,182,150,125,81,49,52,95,43,51,70,29,30,143,39,233,181,22,4,65, - 200,150,24,129,179,217,108,157,4,168,174,174,14,183,219,205,228,201,147,1, - 248,244,211,79,163,214,88,115,115,115,140,168,64,98,113,203,182,142,108,133, - 237,230,91,166,82,209,111,56,163,78,249,6,199,159,118,5,127,154,117,182, - 118,253,79,23,38,77,82,72,38,116,251,119,125,70,40,232,227,96,36,97, - 37,149,75,13,116,129,51,91,58,115,166,157,161,77,190,243,69,21,244,183, - 115,195,45,247,209,220,176,157,151,95,250,123,214,66,103,22,202,183,223,124, - 57,218,231,165,75,151,50,97,194,4,198,140,25,195,210,165,75,163,219,19, - 137,92,182,117,196,139,159,25,191,223,67,83,211,78,214,172,88,18,181,148, - 205,194,102,8,83,48,24,228,223,111,185,3,167,171,12,0,175,167,9,247, - 193,125,0,81,203,45,153,5,103,148,23,4,65,40,20,49,2,87,92,92, - 12,232,2,148,76,152,128,168,48,221,124,203,84,142,30,117,78,84,84,110, - 157,181,90,173,92,248,84,90,113,75,87,199,218,101,115,217,179,125,117,39, - 97,51,44,42,183,219,141,215,235,229,230,91,166,82,86,81,205,176,19,46, - 224,184,51,174,204,58,91,209,44,116,111,191,249,50,14,135,131,113,227,198, - 69,219,203,5,35,83,113,127,221,6,54,175,126,157,27,111,185,151,131,205, - 117,188,246,234,243,73,219,156,120,209,21,52,237,223,70,255,163,79,230,214, - 89,171,149,33,148,173,141,181,124,237,235,87,240,206,219,243,162,229,222,122, - 235,45,46,190,248,98,38,76,152,192,210,165,75,163,219,95,125,233,111,92, - 61,249,122,236,174,82,110,158,182,60,167,58,12,241,139,199,112,25,54,54, - 54,82,95,95,207,149,87,94,5,192,235,175,191,134,223,239,199,102,179,49, - 121,242,183,0,40,173,56,138,178,242,106,14,182,212,241,254,162,215,56,229, - 148,209,57,93,71,65,16,132,124,137,153,232,109,12,126,134,144,4,131,193, - 168,48,125,252,241,199,0,209,237,83,166,76,193,81,92,65,245,224,211,162, - 105,230,126,239,65,90,27,107,163,226,102,196,168,178,173,163,113,239,22,22, - 188,242,36,203,63,124,47,38,129,196,220,167,235,174,187,14,71,113,5,131, - 143,27,207,113,103,92,201,235,127,188,81,203,101,206,153,97,93,53,54,54, - 210,208,208,192,91,111,189,21,21,225,92,249,211,172,179,181,215,255,120,163, - 118,220,25,87,50,248,184,241,56,138,43,184,248,226,139,185,248,226,139,163, - 55,17,70,155,123,247,238,229,165,231,254,143,63,205,158,70,107,99,45,198, - 28,180,151,254,240,45,173,122,216,105,56,138,43,152,48,97,2,197,197,197, - 81,151,232,91,111,189,5,208,105,251,115,207,204,193,221,92,71,48,216,158, - 83,29,173,173,173,44,93,186,52,122,157,227,9,4,2,124,243,218,239,81, - 90,113,20,118,87,41,85,85,85,76,158,252,173,168,184,45,91,246,62,62, - 239,65,14,182,212,225,139,156,7,232,241,53,65,16,132,238,38,70,224,130, - 193,32,23,95,124,113,52,65,194,102,179,49,127,254,124,0,198,141,27,23, - 189,211,55,182,251,61,205,212,237,90,203,228,59,95,84,160,199,160,250,84, - 13,225,132,83,198,70,173,148,92,234,168,26,52,138,75,174,185,157,179,207, - 189,144,186,186,186,168,75,50,24,12,98,179,217,120,235,173,183,88,186,116, - 41,126,79,51,187,54,47,99,243,234,215,185,242,150,185,234,230,105,203,51, - 158,59,21,12,6,241,122,189,120,189,94,220,110,55,110,183,155,230,230,102, - 46,190,248,98,198,140,25,147,87,60,232,230,105,203,213,149,183,204,85,155, - 87,191,206,174,205,203,240,123,154,217,177,99,71,84,56,13,145,49,94,223, - 156,252,61,110,158,58,139,62,85,67,112,68,220,123,147,239,124,81,213,237, - 88,27,45,107,148,3,184,248,226,139,129,14,107,216,56,143,41,215,221,74, - 105,69,53,54,91,81,78,117,184,221,110,38,76,152,16,189,49,49,176,56, - 28,209,191,157,174,50,202,202,171,113,186,202,24,63,254,171,0,172,93,187, - 134,181,107,215,96,183,219,9,120,221,184,155,247,176,97,253,106,218,218,218, - 98,218,20,4,65,232,78,18,62,170,203,24,252,128,168,160,128,46,80,134, - 5,98,179,217,120,237,213,231,169,219,177,138,47,214,206,139,186,197,70,158, - 116,17,67,71,157,23,77,63,207,165,142,49,227,174,227,140,243,111,97,212, - 41,223,224,134,91,238,227,170,171,191,13,116,142,121,45,89,252,47,22,190, - 253,60,53,91,62,96,245,146,63,178,252,221,223,71,133,50,25,102,97,51, - 94,70,28,239,63,239,251,45,253,6,157,136,211,85,30,237,99,182,76,190, - 243,69,181,252,221,223,179,122,201,31,169,217,242,1,43,63,94,16,147,172, - 211,216,216,24,181,144,140,54,143,61,237,10,206,56,255,22,206,152,112,115, - 116,194,248,214,13,239,234,215,37,82,182,181,181,21,175,215,27,227,234,245, - 120,60,209,237,183,220,126,15,67,71,157,23,227,234,205,182,142,41,83,166, - 0,186,171,218,102,235,240,94,59,28,197,12,26,124,42,83,110,188,23,187, - 189,40,106,161,213,212,236,224,203,47,55,3,68,147,72,150,45,123,159,79, - 62,249,152,250,250,122,154,154,154,114,186,134,130,32,8,133,160,83,22,165, - 211,85,142,163,184,130,171,174,254,118,52,110,19,12,6,153,63,127,62,151, - 95,126,121,76,220,38,24,12,242,210,115,255,199,93,63,249,93,52,107,241, - 165,63,124,75,51,68,230,235,151,126,147,183,223,124,57,235,58,12,87,163, - 249,73,37,55,223,254,64,202,164,13,32,42,170,55,79,91,174,204,89,148, - 6,134,152,153,133,210,72,80,57,246,180,43,24,126,210,36,218,91,247,177, - 254,227,231,210,94,184,68,86,73,52,6,185,249,125,214,175,94,2,164,78, - 138,49,218,76,52,23,175,121,223,214,168,171,119,231,206,157,52,55,55,115, - 221,117,215,1,29,194,212,208,208,16,77,210,25,58,234,60,78,25,247,157, - 24,87,111,54,117,220,124,203,84,202,170,134,226,247,52,227,48,89,108,0, - 115,102,157,173,221,112,223,98,85,90,218,143,77,107,95,99,254,75,79,96, - 179,217,162,169,255,70,118,100,91,91,91,212,106,243,251,253,81,215,165,65, - 170,4,19,65,16,132,66,211,73,224,202,42,170,25,124,220,120,90,27,107, - 163,2,101,220,225,27,226,103,36,45,24,219,227,39,105,39,18,185,108,235, - 128,236,132,14,224,213,151,254,198,237,63,250,117,204,20,1,35,89,196,108, - 173,65,103,97,51,68,230,250,159,46,84,27,215,188,14,116,204,115,75,230, - 98,139,223,110,136,202,250,213,75,114,18,54,3,243,228,123,195,69,107,22, - 32,32,38,3,53,94,220,114,169,227,232,81,231,208,167,106,8,187,54,47, - 235,100,193,1,252,229,151,19,181,27,238,91,172,220,238,6,46,159,124,7, - 141,123,183,48,239,181,231,58,101,83,26,215,235,206,187,238,165,178,255,136, - 104,22,165,207,231,75,153,149,154,46,99,85,16,4,33,91,162,163,152,49, - 56,57,75,42,25,50,234,28,224,28,236,54,23,95,191,244,155,209,57,93, - 241,226,103,108,79,68,188,200,229,82,135,65,58,161,51,91,102,137,132,210, - 16,25,72,46,108,198,177,198,252,49,227,122,24,226,148,10,99,190,89,34, - 81,201,70,216,226,241,120,60,81,247,163,89,128,60,30,15,110,183,59,169, - 184,229,82,199,113,103,92,9,192,254,221,159,119,138,193,25,252,229,151,19, - 181,91,167,45,87,253,6,141,98,247,214,21,92,119,211,207,104,57,80,195, - 115,207,254,9,191,223,79,48,24,228,7,183,223,67,121,223,161,28,127,186, - 94,223,222,157,235,162,147,184,147,213,107,96,236,179,196,89,144,130,32,8, - 185,96,51,6,116,227,14,218,110,119,81,94,117,12,127,251,245,164,168,64, - 93,61,249,122,158,123,102,14,206,146,74,70,158,116,17,126,127,27,118,155, - 43,186,61,209,36,109,136,21,185,92,235,48,147,76,232,90,154,119,243,204, - 220,39,8,6,131,209,122,140,243,50,38,152,103,42,50,14,87,25,253,6, - 159,196,148,27,127,158,213,179,40,93,165,21,248,189,7,163,226,232,245,122, - 185,225,198,219,114,18,54,243,119,50,229,186,91,163,2,228,112,148,176,127, - 247,231,248,253,126,174,187,241,142,148,226,150,75,29,215,255,116,161,138,255, - 45,196,51,103,214,217,218,61,143,212,169,170,1,199,113,244,200,177,236,222, - 186,130,219,254,99,22,45,7,106,248,235,220,39,40,239,59,148,147,199,78, - 166,122,196,217,132,253,126,156,37,149,92,127,199,195,25,63,139,114,200,240, - 177,56,28,185,197,63,5,65,16,204,200,106,2,9,200,102,53,1,0,87, - 105,69,175,90,77,192,192,120,248,114,227,190,205,236,222,186,130,182,182,3, - 84,13,24,197,113,99,46,229,47,191,156,168,215,41,171,9,8,130,112,136, - 208,52,210,175,1,118,243,180,229,42,24,108,239,180,47,217,246,68,20,162, - 142,84,117,251,189,238,152,165,107,32,86,168,28,174,210,110,93,15,46,223, - 54,15,247,245,224,204,220,243,72,157,114,55,237,194,88,31,110,78,33,174, - 179,8,156,32,8,121,162,253,238,119,191,83,94,111,114,87,156,203,149,216, - 117,56,121,242,213,188,244,210,171,228,90,22,96,200,144,225,89,116,181,131, - 218,218,237,71,92,89,13,248,217,125,247,69,63,255,234,151,191,36,147,17, - 252,193,7,31,204,169,61,128,7,30,120,32,229,254,109,219,182,49,114,196, - 136,12,251,149,74,179,58,151,40,196,157,68,54,10,247,240,195,15,103,116, - 220,253,247,223,31,243,217,162,105,93,118,211,83,191,111,159,218,176,97,3, - 27,54,108,96,237,218,181,0,204,121,250,105,89,24,86,16,186,9,27,192, - 213,87,95,157,85,161,19,79,60,145,218,218,237,228,91,22,96,227,198,141, - 0,104,154,134,197,210,121,90,158,82,250,255,111,56,28,6,224,173,183,222, - 138,10,100,33,202,102,74,190,101,185,231,30,70,140,24,209,105,223,182,109, - 219,82,150,253,238,119,191,203,179,207,62,11,16,125,140,88,42,46,186,232, - 162,104,189,233,234,126,246,217,103,225,129,7,18,246,171,131,76,198,99,227, - 152,142,177,118,107,154,182,71,142,24,193,222,250,250,212,213,14,28,152,65, - 219,29,196,139,87,60,75,150,44,225,225,135,31,78,123,92,174,172,88,185, - 82,189,241,198,27,172,92,185,146,53,107,214,80,93,93,205,160,65,131,56, - 238,184,227,24,59,118,108,151,180,41,8,66,114,18,78,244,238,110,52,77, - 139,138,84,252,203,106,181,98,177,88,72,118,163,157,79,217,238,102,196,136, - 17,209,87,54,124,247,187,223,5,244,71,157,85,86,86,38,125,153,197,173, - 48,253,202,246,186,197,30,63,98,196,8,222,125,247,221,164,159,1,6,14, - 28,200,186,117,235,146,126,46,52,247,223,127,127,66,107,111,197,83,103,42, - 243,107,203,214,173,170,185,165,37,43,235,232,141,55,222,96,247,238,221,92, - 114,201,37,60,243,204,51,212,213,213,177,123,215,46,109,209,194,133,218,175, - 127,245,43,237,196,19,211,63,151,115,209,226,197,106,209,226,197,98,149,9, - 66,1,232,52,15,174,187,49,4,202,106,181,118,154,123,5,186,21,166,148, - 138,90,97,133,42,123,40,200,86,216,204,24,150,220,130,5,11,184,228,146, - 75,58,237,63,243,204,51,129,236,197,45,121,191,114,189,41,208,48,44,185, - 109,219,182,69,69,55,209,103,128,250,250,122,78,61,245,212,164,159,11,137, - 185,237,105,211,166,69,39,158,175,120,234,76,53,246,182,85,49,39,188,226, - 169,107,85,211,153,79,209,220,210,162,42,202,203,51,186,24,167,159,126,58, - 51,166,79,207,249,110,106,195,198,141,106,234,212,169,76,154,52,41,215,42, - 4,65,48,113,88,8,156,97,113,13,27,54,44,225,49,53,53,53,132,66, - 161,78,66,149,79,89,51,39,158,120,98,194,237,153,184,34,179,41,155,143, - 192,65,114,145,203,71,220,10,209,175,238,66,211,180,168,219,57,23,12,65, - 91,178,100,73,84,236,12,113,11,171,167,98,42,182,104,183,105,43,158,186, - 77,125,185,74,63,38,186,99,21,84,254,236,5,250,245,235,71,166,194,151, - 41,75,151,46,101,233,210,165,244,237,219,55,43,97,21,4,33,49,157,4, - 206,120,102,100,60,230,231,83,38,35,215,178,134,37,246,200,35,143,36,220, - 63,121,242,228,180,46,202,92,202,26,36,43,155,201,57,103,83,54,70,128, - 114,20,149,120,145,203,87,220,18,247,43,223,113,85,3,182,50,98,196,8, - 158,126,250,233,168,152,196,127,6,221,37,249,246,219,111,71,173,182,248,207, - 157,106,206,83,228,18,17,47,110,198,54,139,118,91,167,11,241,228,15,80, - 7,158,127,158,111,127,251,219,5,237,195,134,141,27,213,77,55,221,4,192, - 43,175,188,210,201,210,21,4,33,123,58,9,220,61,247,220,147,240,192,76, - 172,153,92,202,26,226,163,105,26,223,249,206,119,18,30,99,60,225,34,94, - 168,242,41,107,38,19,33,43,68,217,66,8,28,116,136,92,33,196,173,144, - 253,74,84,111,87,184,40,187,66,228,88,5,171,86,61,29,179,41,198,114, - 139,225,101,154,222,125,153,45,91,183,170,81,35,71,230,109,101,213,239,219, - 167,166,78,157,202,138,21,43,162,219,126,245,171,95,177,104,241,98,117,193, - 196,137,98,197,9,66,142,116,18,184,108,51,4,11,85,182,55,16,47,68, - 219,182,109,139,102,72,230,74,62,211,8,204,253,40,52,35,51,16,202,65, - 233,178,36,83,220,148,20,84,228,86,173,98,213,170,85,196,199,225,18,17, - 94,249,148,178,156,117,155,246,228,15,80,7,14,60,95,144,230,63,254,248, - 99,70,140,24,193,169,167,158,202,186,117,235,168,170,170,98,224,192,129,44, - 91,182,140,157,181,181,234,152,33,67,98,250,181,179,182,86,1,196,111,23, - 4,33,150,67,30,131,51,51,104,208,160,132,219,119,237,218,213,165,101,187, - 43,6,119,219,15,126,16,243,121,228,136,17,144,102,174,90,42,254,27,242, - 42,111,16,223,47,45,171,25,104,137,209,18,76,219,200,150,116,189,40,180, - 37,151,200,85,217,137,85,171,8,171,167,212,211,183,221,22,93,99,47,31, - 154,91,90,84,67,67,3,87,93,121,165,246,139,7,31,84,70,6,233,253, - 247,223,207,184,113,227,58,45,22,91,191,111,159,122,229,149,87,56,254,248, - 227,243,110,91,16,122,58,135,69,12,206,32,89,60,235,91,223,250,86,194, - 237,93,93,182,208,49,184,127,60,215,177,12,207,119,166,76,201,72,70,94, - 125,11,55,181,47,0,0,32,0,73,68,65,84,245,213,12,142,74,76,186, - 57,138,251,246,237,99,224,128,1,9,250,149,191,97,96,41,200,84,239,212, - 204,152,49,163,203,219,40,4,139,22,47,86,75,150,44,97,227,198,245,157, - 246,153,19,73,170,170,170,0,253,1,217,31,124,240,1,87,93,121,101,204, - 69,172,223,183,79,61,240,192,3,84,86,86,70,215,238,19,4,33,57,135, - 60,6,103,38,93,28,173,171,202,118,87,12,110,192,128,1,157,182,237,219, - 183,47,101,153,115,207,61,151,15,63,252,16,160,211,221,124,34,140,228,135, - 125,251,246,165,173,251,195,15,63,132,171,175,78,216,175,195,129,120,1,51, - 127,158,49,99,6,211,167,79,239,222,14,1,171,88,197,153,156,217,105,251, - 206,218,90,181,102,205,154,78,219,103,204,156,169,140,184,227,132,9,19,82, - 214,61,120,240,96,6,13,26,196,222,189,123,121,241,197,23,121,242,169,167, - 212,53,215,92,131,207,231,99,205,154,53,92,117,213,85,52,55,55,243,196, - 19,79,20,60,131,83,16,122,34,18,131,235,70,246,239,223,159,83,57,67, - 228,156,78,103,210,4,12,165,84,52,221,63,157,176,21,170,95,93,77,188, - 128,25,2,215,165,226,182,106,85,154,253,96,214,183,13,27,55,170,203,46, - 187,140,225,195,135,39,20,176,57,115,230,68,255,254,209,143,126,196,162,133, - 11,147,86,61,110,220,56,206,57,231,28,94,121,229,21,118,238,220,201,47, - 126,241,11,230,207,159,15,192,39,159,124,66,99,99,35,179,103,207,70,18, - 79,4,33,51,36,6,71,247,197,224,46,184,224,130,180,245,37,195,16,185, - 117,235,214,117,18,185,124,196,45,223,126,117,55,135,202,114,75,198,117,215, - 93,199,206,157,59,1,24,53,106,84,39,1,123,231,157,119,88,180,104,17, - 23,92,112,1,39,157,120,98,74,97,26,56,96,128,54,251,15,127,80,175, - 188,242,10,0,123,247,238,101,193,130,5,128,238,190,156,49,99,6,183,223, - 214,121,234,130,32,8,137,145,24,92,138,178,133,142,193,229,235,10,52,139, - 220,152,49,99,0,61,209,34,31,113,43,68,191,186,139,174,16,183,202,139, - 94,96,213,187,215,2,176,234,182,167,89,69,26,11,14,88,117,219,109,204, - 223,115,5,231,156,51,140,202,202,74,154,154,154,184,232,162,139,248,205,111, - 126,195,156,167,99,167,26,164,19,181,120,38,79,158,76,99,99,35,191,252, - 229,47,241,122,189,184,92,46,70,143,30,205,109,183,77,229,154,107,174,224, - 191,11,144,84,36,8,189,5,137,193,209,125,49,184,24,1,202,81,84,12, - 145,251,244,211,79,25,51,102,12,195,135,15,239,92,119,150,20,162,95,221, - 65,58,113,91,178,100,73,214,117,246,235,215,143,166,51,159,226,237,183,223, - 102,7,59,32,65,124,45,17,231,156,51,140,175,127,253,235,140,61,235,44, - 13,96,206,211,79,119,18,183,92,24,56,96,64,140,32,182,185,221,124,252, - 209,71,124,252,209,71,252,251,141,121,87,47,8,189,10,137,193,117,35,139, - 22,45,234,248,144,199,147,48,12,145,203,215,114,43,116,191,14,37,211,166, - 77,203,169,92,69,121,185,214,220,210,162,42,43,43,163,43,153,103,130,195, - 225,160,95,191,126,57,181,41,8,66,247,32,49,56,186,47,6,215,191,127, - 255,152,207,251,246,237,139,102,72,230,74,62,211,8,12,226,251,117,184,144, - 104,9,164,130,215,175,105,170,162,162,34,247,74,100,61,54,65,56,108,145, - 24,92,138,178,133,142,193,93,24,247,148,248,129,3,6,64,150,235,233,117, - 34,223,242,116,238,87,65,38,122,31,30,43,49,9,130,208,139,145,24,28, - 221,23,131,203,101,69,239,174,36,249,138,222,71,198,68,111,65,16,132,84, - 72,12,174,27,201,101,69,239,116,117,61,248,224,131,209,5,81,179,37,179, - 21,189,5,65,16,142,76,36,6,199,145,179,30,92,124,61,171,34,147,146, - 159,125,246,217,156,69,174,144,253,18,4,65,56,156,56,162,99,112,198,131, - 118,149,82,41,215,131,51,31,155,77,187,133,142,193,21,66,72,226,197,237, - 146,75,46,97,193,130,5,121,137,92,231,126,41,242,91,19,78,129,196,224, - 4,65,56,196,28,209,49,56,165,20,225,112,24,77,211,162,66,22,191,223, - 88,205,59,149,192,117,87,12,46,95,129,139,23,55,131,124,69,78,44,56, - 65,16,122,34,71,116,12,46,20,10,69,69,206,192,44,100,74,169,24,145, - 59,212,228,179,176,104,50,113,51,200,71,228,18,247,43,87,43,238,80,167, - 206,8,130,32,232,28,209,49,56,143,199,131,166,105,104,154,22,51,103,202, - 236,186,132,14,33,76,70,62,49,184,108,200,85,224,12,113,123,247,221,119, - 83,30,55,110,220,56,62,254,248,227,172,69,46,121,191,178,21,57,17,55, - 65,16,14,31,10,26,131,203,151,108,99,112,123,246,236,65,139,172,250,108, - 44,126,153,200,29,105,88,114,217,182,91,232,115,238,138,21,189,147,145,77, - 189,169,51,57,141,235,150,74,232,68,216,4,65,56,252,200,43,6,151,236, - 216,92,201,54,6,183,117,235,214,78,219,188,94,111,210,250,93,46,87,194, - 237,217,8,89,50,49,204,164,221,66,175,232,93,40,226,251,149,248,9,34, - 169,4,78,18,74,4,65,56,252,200,43,6,151,207,163,148,106,106,58,139, - 83,166,12,29,58,50,231,178,147,39,231,254,228,143,124,218,229,158,123,114, - 90,209,187,43,73,182,162,183,32,8,66,79,224,136,142,193,21,138,238,138, - 193,229,178,162,119,186,186,94,125,245,85,206,61,247,220,156,234,56,220,87, - 244,22,4,65,200,135,35,58,6,215,213,237,22,250,156,11,181,114,182,33, - 72,219,183,111,7,116,161,202,85,228,10,217,47,65,16,132,195,137,130,206, - 131,203,151,124,158,39,153,15,221,33,222,80,152,149,179,227,197,109,204,152, - 49,124,250,233,167,121,137,220,145,180,162,183,32,8,66,166,20,116,30,156, - 144,154,124,93,129,70,249,109,219,182,69,179,71,33,127,145,19,23,165,32, - 8,61,17,137,193,209,125,49,184,124,86,206,54,139,27,232,83,31,140,57, - 128,0,167,158,122,42,235,214,173,203,73,228,142,148,21,189,5,65,16,178, - 65,98,112,41,218,45,244,57,231,186,114,182,33,110,207,63,255,124,218,99, - 157,78,103,214,34,215,19,86,244,22,4,65,136,71,98,112,116,95,12,46, - 223,21,189,157,78,103,198,199,102,83,239,225,186,162,183,32,8,66,62,72, - 12,174,155,208,44,22,46,50,127,6,18,59,100,187,23,13,58,245,75,16, - 4,161,39,32,49,56,186,47,6,39,8,130,32,116,31,18,131,75,209,110, - 119,185,46,5,65,16,132,194,35,49,56,68,200,4,65,16,122,34,18,131, - 19,4,65,16,122,36,18,131,67,98,112,130,32,8,61,17,137,193,165,104, - 87,92,151,130,32,8,71,46,18,131,67,132,76,16,4,161,39,34,49,56, - 65,16,4,161,71,34,49,56,36,6,39,8,130,208,19,145,24,92,138,118, - 197,117,41,8,130,112,228,34,49,56,68,200,4,65,16,122,34,18,131,19, - 4,65,16,122,36,18,131,67,98,112,130,32,8,61,145,67,30,131,83,74, - 69,223,147,197,194,38,79,158,28,115,108,161,145,24,156,32,8,66,207,227, - 144,199,224,148,82,132,195,97,52,77,139,10,89,252,254,80,40,68,56,28, - 238,50,129,19,33,19,4,65,232,121,28,242,24,92,40,20,138,138,156,129, - 89,200,148,82,49,34,39,8,130,32,8,153,112,200,99,112,30,143,7,77, - 211,208,52,13,139,197,18,221,110,118,93,66,135,16,10,130,32,8,66,38, - 28,114,129,219,179,103,15,154,166,175,35,173,105,90,212,154,139,23,51,195, - 146,19,4,65,16,132,76,176,37,139,185,117,23,91,183,110,237,180,205,235, - 245,38,61,222,229,114,229,221,102,178,164,146,174,110,87,16,4,65,232,62, - 52,37,102,145,32,8,9,208,12,215,74,10,166,78,157,122,198,236,217,179, - 87,27,239,89,54,49,3,152,14,204,140,252,29,223,190,140,77,66,94,28, - 114,23,165,32,8,71,38,83,167,78,93,21,121,55,54,157,153,97,209,19, - 128,159,0,95,7,66,192,77,192,96,224,183,192,166,194,246,82,232,205,136, - 5,39,8,66,66,18,89,112,83,167,78,181,3,197,64,17,48,22,120,24, - 112,161,139,149,7,104,7,60,179,103,207,14,36,169,246,90,224,111,15,62, - 248,144,227,202,43,191,201,137,39,142,160,166,166,134,23,94,120,129,159,255, - 252,231,126,224,122,224,133,72,251,50,54,9,121,33,2,39,8,66,66,226, - 5,110,234,212,169,197,192,113,192,201,192,49,192,16,96,104,100,119,13,80, - 11,236,4,62,7,54,207,158,61,219,19,87,229,9,192,186,69,139,22,57, - 86,175,174,192,237,14,48,109,218,216,232,206,197,139,23,115,193,5,23,248, - 129,83,129,77,34,112,66,190,88,210,31,34,8,66,111,103,234,212,169,229, - 192,121,192,20,224,2,96,32,208,130,238,90,172,141,252,61,48,178,111,10, - 112,94,164,140,153,159,60,244,208,67,142,137,19,39,114,253,245,199,243,226, - 139,91,216,179,167,45,186,115,226,196,137,60,244,208,67,14,116,247,165,32, - 228,141,88,112,130,32,36,196,176,224,34,66,117,49,48,30,61,102,214,4, - 180,162,187,35,7,0,245,128,134,238,182,236,3,84,2,86,224,125,224,95, - 179,103,207,110,137,84,185,115,203,150,45,67,70,142,28,9,192,180,105,159, - 208,214,22,164,184,216,198,160,65,197,76,157,58,154,173,91,183,50,106,212, - 168,90,224,24,177,224,132,124,17,129,19,132,195,18,133,82,33,194,97,216, - 179,199,199,194,69,173,44,255,164,149,77,155,154,217,187,199,79,107,171,23, - 139,69,209,183,159,149,234,106,27,99,70,87,112,222,121,149,156,55,126,0, - 101,101,246,200,195,19,242,115,208,104,154,166,69,220,146,151,0,231,3,126, - 96,31,112,44,240,125,224,223,0,35,214,102,196,230,250,0,125,209,133,207, - 1,44,1,22,68,220,149,193,64,32,96,181,217,244,220,182,189,123,61,124, - 237,107,175,113,245,213,35,184,243,206,83,56,234,168,18,130,193,32,118,187, - 61,4,216,68,224,132,124,17,129,19,132,195,10,253,223,177,189,61,196,43, - 175,54,240,151,185,7,248,116,93,19,62,223,94,252,254,26,194,170,142,112, - 184,153,96,40,128,166,44,132,85,31,160,15,26,149,64,57,21,149,118,46, - 190,120,48,183,223,126,18,227,198,13,192,106,181,160,219,97,105,51,254,59, - 113,215,93,119,57,128,115,209,5,206,5,212,161,91,107,13,192,203,192,47, - 128,249,145,195,109,116,8,92,63,116,119,101,53,224,5,22,0,31,206,158, - 61,123,171,217,130,211,207,51,72,81,81,71,50,183,88,112,66,33,145,105, - 2,130,112,152,16,14,7,9,135,21,11,22,180,240,203,135,235,216,183,175, - 129,182,182,197,52,53,125,72,105,153,135,51,207,28,193,136,17,131,41,175, - 24,69,81,81,17,161,96,24,143,199,199,254,253,45,108,218,180,137,47,191, - 108,164,169,105,0,255,248,199,96,94,124,241,115,46,185,228,104,30,124,112, - 60,199,31,95,137,205,102,39,131,105,109,241,84,3,227,208,5,171,22,104, - 68,23,183,3,192,107,192,221,192,95,35,199,218,208,93,150,102,139,174,8, - 61,17,101,28,176,3,120,251,133,23,94,184,249,254,251,239,143,54,96,22, - 55,128,23,94,120,1,224,237,108,59,42,8,137,16,11,78,16,14,49,74, - 233,143,166,115,187,67,252,252,254,93,44,91,182,15,143,119,62,187,119,205, - 103,252,248,211,184,248,27,19,57,101,244,49,56,28,54,28,14,43,14,187, - 3,171,213,138,197,170,139,131,10,43,130,161,0,77,77,94,22,45,218,194, - 188,121,107,216,176,193,139,10,15,165,172,204,193,195,191,58,143,27,190,127, - 26,46,151,29,139,37,243,123,218,187,238,186,107,28,112,53,186,80,213,0, - 187,128,189,232,2,119,16,61,99,242,2,96,29,186,192,61,2,156,14,220, - 14,12,66,79,64,25,138,46,124,175,70,98,113,235,22,45,90,228,152,56, - 113,98,167,246,36,139,82,40,52,98,193,9,194,33,70,41,69,83,83,144, - 27,190,95,67,155,167,150,29,53,211,25,125,242,32,254,251,191,102,48,248, - 152,74,156,78,59,165,37,165,148,150,150,82,92,92,140,211,233,196,106,181, - 118,196,216,148,34,20,14,225,247,251,57,246,216,33,76,153,50,150,183,255, - 181,157,71,31,125,135,221,117,101,220,125,215,191,248,114,243,62,166,79,159, - 72,89,89,89,204,67,205,211,48,16,40,167,35,161,196,67,199,92,55,47, - 122,18,201,76,116,23,230,189,192,247,128,17,64,149,233,184,246,72,29,3, - 129,79,128,235,47,184,224,130,191,61,244,208,67,142,107,175,189,150,161,67, - 135,38,154,7,39,147,189,133,130,32,22,156,32,28,66,116,203,45,192,183, - 175,221,65,187,111,13,203,63,121,152,219,111,159,204,229,151,143,199,238,176, - 83,81,81,78,85,101,37,165,165,101,184,92,46,108,54,91,116,245,141,184, - 154,8,135,245,101,165,252,254,32,158,182,131,212,214,54,242,192,3,11,248, - 215,219,13,104,132,249,209,143,198,50,109,218,69,148,148,150,96,181,90,211, - 246,237,174,187,238,250,119,224,66,116,247,226,14,116,55,101,61,186,171,210, - 13,156,8,124,0,60,8,60,128,46,108,165,232,89,148,131,208,221,147,195, - 34,175,247,102,207,158,61,55,82,181,249,73,38,213,232,177,189,183,137,123, - 146,137,88,112,66,190,136,5,39,8,135,8,125,157,195,0,63,253,233,46, - 14,186,183,178,118,237,131,252,247,3,119,114,246,184,19,40,41,45,97,64, - 255,254,244,237,219,151,162,162,34,140,204,195,228,104,88,44,250,146,83,118, - 187,29,151,203,78,105,89,41,79,61,253,109,238,191,255,61,254,241,236,54, - 30,127,124,41,199,159,80,197,148,41,103,82,90,90,154,75,76,46,158,181, - 232,49,183,251,208,231,200,165,238,97,114,193,26,2,220,28,121,9,66,193, - 144,137,222,130,112,200,80,188,243,238,65,150,45,107,96,253,250,223,112,219, - 173,223,99,220,184,19,40,239,211,135,33,71,31,205,160,65,71,81,90,90, - 154,129,184,117,198,106,181,225,114,21,49,104,208,0,126,251,219,203,56,255, - 252,106,130,193,65,76,159,254,50,59,182,213,227,245,122,51,89,126,42,20, - 121,183,155,94,54,211,203,10,84,0,191,6,214,155,182,199,31,15,16,204, - 250,36,4,33,79,196,130,75,66,56,28,198,98,177,16,10,117,60,105,65, - 211,140,37,115,58,223,249,90,44,22,194,97,125,60,80,202,27,57,86,139, - 108,55,86,34,87,248,253,33,218,253,77,52,181,58,104,62,96,167,118,103, - 152,166,134,125,108,171,117,113,176,217,193,246,173,117,236,172,241,211,230,46, - 162,169,201,139,199,211,144,176,127,37,125,224,232,163,250,114,204,80,7,165, - 101,125,232,223,191,141,33,67,7,83,49,192,74,223,50,24,114,140,133,138, - 190,1,42,42,138,41,182,105,56,28,182,104,236,37,16,8,68,93,84,230, - 115,52,206,207,98,233,112,95,133,195,33,148,210,151,17,178,90,75,98,174, - 141,144,31,193,160,226,87,15,215,209,238,121,135,19,79,44,231,146,203,206, - 161,180,180,136,234,163,142,162,111,191,126,56,28,142,188,234,215,52,13,187, - 221,70,255,254,125,120,228,209,203,184,224,252,23,168,175,183,50,231,143,139, - 185,255,254,75,233,63,96,64,58,241,172,71,127,66,137,11,61,209,164,56, - 242,106,167,67,176,130,232,174,69,87,130,227,138,34,175,22,244,249,115,130, - 208,173,136,192,37,69,191,187,53,15,234,230,125,198,160,111,16,14,187,76, - 194,80,66,32,16,32,20,82,28,116,135,169,221,29,164,118,103,152,173,91, - 67,172,94,217,196,134,207,26,216,241,229,78,90,188,26,40,47,104,46,148, - 42,167,216,25,192,227,179,3,160,105,198,120,224,139,188,59,77,173,249,104, - 111,128,134,6,15,235,214,3,202,139,166,181,3,159,160,148,23,151,211,129, - 215,231,167,111,223,129,156,123,238,177,12,31,89,205,169,163,91,169,236,55, - 128,33,199,88,24,125,146,19,79,139,155,162,62,86,66,161,142,90,99,133, - 45,108,218,86,98,218,110,42,32,228,140,82,97,62,250,168,153,173,91,155, - 56,112,224,53,238,187,255,94,92,46,43,253,250,247,167,178,170,42,169,184, - 41,165,80,97,31,42,236,7,139,29,139,197,142,166,25,223,155,134,241,187, - 53,223,132,89,173,54,78,62,169,31,183,220,122,22,191,251,127,33,94,126, - 121,25,55,222,120,14,165,101,165,148,150,150,165,114,85,26,2,55,16,125, - 126,91,57,122,242,136,49,21,192,70,135,208,217,232,120,146,137,113,108,31, - 244,152,92,125,228,37,8,221,138,8,92,18,140,193,94,31,232,85,220,103, - 13,171,181,36,186,207,56,62,28,14,115,160,209,79,237,238,32,107,63,15, - 179,126,165,151,85,107,215,176,105,125,43,7,26,139,208,180,190,166,22,142, - 70,211,32,172,218,64,129,166,121,105,247,131,166,197,63,159,22,98,197,45, - 66,68,24,1,93,32,137,60,246,79,3,175,31,138,156,86,14,28,104,100, - 254,252,149,40,85,132,254,116,37,24,118,212,16,70,159,53,148,73,23,66, - 159,178,82,198,156,49,136,147,142,119,224,112,216,8,4,2,88,44,254,104, - 19,154,86,148,240,218,232,226,94,146,112,159,144,30,99,90,192,155,111,54, - 209,222,190,129,225,195,251,49,98,100,127,250,244,41,167,170,170,47,78,167, - 51,193,241,65,148,2,165,124,224,171,67,243,237,1,107,41,33,215,96,52, - 91,21,154,6,42,236,71,161,176,88,156,104,154,213,36,124,250,239,243,134, - 27,142,227,209,255,253,130,189,245,110,62,93,191,157,234,163,251,82,92,156, - 50,225,100,79,228,53,4,61,113,36,126,158,155,135,196,79,50,233,135,158, - 112,82,137,254,52,19,163,30,65,232,86,68,224,146,16,8,4,176,219,237, - 81,215,99,172,27,79,195,235,245,99,181,234,119,190,251,246,237,99,229,138, - 6,182,238,56,134,165,139,106,248,112,89,128,150,214,18,66,170,133,112,216, - 138,166,21,161,148,11,165,140,58,116,235,79,41,87,204,103,221,90,235,44, - 102,69,14,43,237,126,179,229,228,140,245,146,42,47,122,214,118,7,237,62, - 208,180,246,136,184,129,62,214,192,142,61,110,118,204,251,156,121,243,244,173, - 167,157,82,201,105,167,6,248,234,164,147,25,50,170,31,99,78,116,209,183, - 202,65,40,20,194,106,85,120,189,126,66,161,0,69,69,29,238,217,100,194, - 39,100,131,98,197,138,70,124,190,45,156,122,234,201,216,237,118,250,244,41, - 167,200,85,20,99,81,133,195,1,194,129,6,8,52,2,26,154,10,18,110, - 91,75,208,253,57,154,179,63,225,224,4,40,182,97,167,29,124,117,122,25, - 231,32,52,199,160,24,225,210,52,141,19,78,168,98,240,144,190,212,236,24, - 200,250,79,183,48,126,252,9,84,84,84,36,21,184,217,179,103,239,155,58, - 117,234,123,232,98,53,156,88,107,173,152,228,2,103,60,170,171,28,216,130, - 158,65,185,175,0,73,45,130,144,21,34,112,73,176,88,252,132,195,29,113, - 38,195,98,51,4,239,160,59,204,167,27,189,172,91,165,88,186,104,63,243, - 223,104,7,54,17,14,183,161,105,45,40,85,142,197,162,91,57,74,185,208, - 52,175,73,208,250,82,212,103,63,170,93,31,27,138,139,7,162,217,26,80, - 193,99,244,253,182,6,60,1,243,114,90,97,138,44,237,177,29,12,247,1, - 192,227,179,163,105,177,238,75,3,35,135,64,119,95,98,218,238,5,237,40, - 0,214,126,214,196,218,207,154,248,251,139,155,56,106,96,21,231,125,245,66, - 38,93,218,143,211,78,182,48,228,104,27,125,171,28,128,13,165,218,9,4, - 236,184,92,249,197,133,4,48,238,78,182,111,111,195,31,216,207,49,199,140, - 193,101,183,83,92,82,132,213,102,142,109,42,84,200,13,109,155,9,123,34, - 139,101,91,42,81,237,107,8,214,173,131,129,131,241,249,143,134,96,25,125, - 44,187,8,123,86,160,84,8,138,190,66,184,172,4,167,211,138,213,106,211, - 221,154,42,140,166,105,28,127,124,21,53,59,138,217,189,187,30,111,187,135, - 96,32,168,71,206,146,48,123,246,236,141,83,167,78,93,132,158,76,210,151, - 14,87,164,49,55,46,254,201,37,198,195,150,203,209,221,6,139,102,207,158, - 189,177,80,87,78,16,178,65,4,46,9,154,86,20,147,128,17,14,23,113, - 160,209,207,135,31,249,217,186,53,196,107,175,185,217,91,219,204,151,219,234, - 177,88,74,8,135,219,76,165,157,88,180,29,20,245,25,64,81,68,72,160, - 99,229,16,205,214,64,223,10,23,7,154,67,168,176,27,165,182,162,66,128, - 182,149,131,238,54,44,52,225,243,219,233,24,121,204,214,153,190,205,238,208, - 191,58,135,3,252,126,27,69,206,50,124,126,125,112,84,170,136,162,34,27, - 237,17,93,139,90,113,81,151,38,17,171,207,160,146,96,192,69,237,46,120, - 246,217,87,120,233,165,32,71,13,172,226,234,127,27,199,240,225,33,198,159, - 63,138,97,35,237,84,20,219,162,73,39,154,230,138,137,217,9,217,160,240, - 251,195,248,124,86,172,86,133,221,81,76,155,215,206,182,173,1,42,43,194, - 88,44,86,148,10,19,14,121,80,237,59,8,183,173,33,216,176,8,205,229, - 36,100,25,130,37,188,3,107,221,1,194,253,66,4,125,27,176,134,33,96, - 221,139,230,251,20,220,62,188,21,253,9,107,195,209,44,69,56,53,11,160, - 88,183,182,129,81,199,86,80,92,228,194,102,43,161,221,235,195,31,8,17, - 12,5,81,74,165,156,50,48,123,246,236,247,35,171,118,95,133,110,153,149, - 162,207,131,51,39,155,24,194,87,138,238,150,220,7,188,54,123,246,236,247, - 187,236,50,10,66,26,68,224,82,16,14,135,9,135,29,212,214,187,89,188, - 52,196,250,21,53,44,89,212,206,218,79,91,59,137,154,197,82,66,85,185, - 126,57,43,43,7,98,172,3,105,181,238,161,221,91,19,61,206,221,230,163, - 181,165,141,253,251,245,236,72,133,23,13,47,29,15,135,136,117,53,38,195, - 239,55,142,211,147,215,218,125,122,2,155,138,8,96,123,251,160,72,253,46, - 138,156,101,0,120,125,122,28,78,211,92,81,23,167,82,69,49,22,158,134, - 147,128,223,201,206,90,31,143,61,186,4,133,143,211,79,169,99,194,133,67, - 152,56,105,40,231,158,227,160,111,149,43,114,125,66,132,66,225,200,121,198, - 138,157,100,89,38,38,28,14,178,105,147,151,59,110,175,161,184,168,15,173, - 45,141,40,5,159,127,230,227,241,199,95,229,197,23,255,141,99,143,173,192, - 102,245,67,251,86,194,7,151,19,246,127,132,165,125,39,161,128,141,128,211, - 135,205,218,136,179,161,21,101,245,97,87,43,192,215,138,178,121,208,60,123, - 8,248,53,124,237,77,4,236,109,56,138,66,216,109,138,119,222,109,228,190, - 123,223,228,159,175,94,69,40,20,100,196,200,211,88,176,96,37,46,199,167, - 252,234,55,213,244,233,19,142,137,215,37,34,34,114,13,192,53,192,241,232, - 86,90,223,184,195,140,76,172,77,192,43,98,185,9,135,26,17,184,36,4, - 3,7,104,106,14,177,224,77,55,239,190,103,225,237,5,7,104,108,209,111, - 86,13,215,163,241,94,85,110,163,178,210,69,73,169,33,20,237,180,236,223, - 195,65,191,159,54,119,19,94,95,45,10,47,122,156,189,25,93,196,90,0, - 103,68,103,124,232,2,151,136,248,44,74,227,115,69,228,189,197,180,207,21, - 169,207,133,98,15,134,181,215,238,43,2,42,208,168,64,225,66,41,31,26, - 78,92,78,7,208,134,215,87,18,21,57,77,115,161,148,23,133,143,226,162, - 193,120,189,7,89,247,121,29,159,111,94,207,171,255,172,226,155,223,236,199, - 87,47,184,144,111,124,77,175,219,136,67,134,34,233,152,153,60,33,163,247, - 162,216,178,197,199,229,151,109,71,169,48,22,235,6,60,237,187,81,88,216, - 179,55,192,206,154,29,28,104,216,77,255,126,1,170,74,219,224,224,106,194, - 205,111,161,149,110,2,75,19,150,198,98,180,163,237,88,44,237,40,247,65, - 236,142,86,180,80,0,95,168,133,80,216,129,214,218,128,53,88,66,208,213, - 70,40,208,78,40,236,71,41,23,27,55,180,176,109,199,70,14,28,24,143, - 223,239,199,106,237,75,223,170,81,188,244,207,117,52,183,180,242,215,191,125, - 151,126,253,146,199,226,12,34,238,202,3,232,79,48,57,22,24,133,30,159, - 3,253,233,38,91,128,47,129,141,179,103,207,150,105,1,194,33,167,87,8, - 156,57,181,221,72,239,215,180,34,66,161,16,118,187,157,80,168,141,80,208, - 131,205,222,23,139,197,66,32,16,224,247,79,216,88,189,242,32,239,188,243, - 37,7,14,84,152,234,106,139,90,107,131,135,40,142,25,170,199,164,106,183, - 215,210,216,180,27,119,155,15,79,155,3,21,94,136,55,16,164,195,42,107, - 65,23,49,31,201,173,52,23,137,220,145,58,62,58,211,142,238,21,242,197, - 29,211,98,58,198,137,97,229,41,42,48,172,60,5,120,125,21,40,42,176, - 104,22,20,149,20,185,130,120,189,7,1,176,104,229,120,189,7,163,98,23, - 240,151,80,83,219,202,19,79,40,254,250,183,127,241,189,235,78,96,226,164, - 161,124,245,2,39,229,69,186,240,7,2,118,172,86,93,236,244,36,21,11, - 193,64,35,0,14,103,255,200,245,11,163,84,123,116,250,69,111,65,169,48, - 109,109,1,190,127,195,54,148,10,243,147,123,203,248,207,255,252,24,165,124, - 132,67,65,236,246,16,74,41,218,15,54,227,107,246,160,212,110,148,111,5, - 184,191,192,214,175,30,21,244,163,29,8,163,29,83,140,197,238,197,234,13, - 131,213,139,85,133,112,5,33,232,40,195,210,238,199,103,183,161,194,173,16, - 216,11,190,50,112,89,9,134,20,42,28,166,181,165,137,64,48,200,166,77, - 45,84,15,42,5,85,194,187,239,173,228,161,255,169,96,250,140,75,41,47, - 175,136,79,76,233,52,19,252,15,127,248,67,70,231,43,9,37,194,225,64, - 143,21,184,80,168,45,26,39,50,82,248,117,183,89,73,100,162,179,138,36, - 146,88,9,4,236,56,28,186,183,101,238,255,109,137,90,108,30,79,3,30, - 159,29,179,183,173,95,101,57,231,142,183,71,63,111,222,180,143,154,157,59, - 240,250,246,163,216,1,108,39,86,96,58,68,77,197,9,155,214,41,186,111, - 222,95,110,250,59,81,214,98,51,186,120,25,239,144,44,11,179,163,238,102, - 192,135,70,59,48,44,226,206,172,36,172,116,235,206,211,238,138,90,118,94, - 95,71,95,52,83,157,94,223,126,66,170,137,199,30,221,204,171,255,28,192, - 213,255,54,142,235,111,28,206,241,163,52,236,182,22,60,45,78,138,203,75, - 163,19,220,29,206,254,132,66,109,180,181,181,81,82,82,18,217,222,27,179, - 48,53,158,126,250,0,235,214,120,248,249,127,29,205,11,47,172,198,239,63, - 0,40,125,189,54,165,129,210,8,133,218,177,248,107,80,173,31,161,217,215, - 161,133,26,208,180,54,104,7,237,96,59,54,187,7,13,63,4,252,104,22, - 208,218,131,88,194,45,216,92,1,44,190,32,86,171,134,221,86,131,43,180, - 4,139,187,134,160,101,44,225,128,19,5,132,195,186,94,133,195,26,7,221, - 86,208,74,80,202,201,156,63,206,231,178,203,78,226,156,115,143,167,180,180, - 68,196,73,232,49,244,92,129,11,122,208,87,19,49,220,137,22,188,94,63, - 14,135,13,171,213,74,48,112,0,135,179,191,62,8,59,108,204,123,195,205, - 139,207,55,176,226,227,118,190,220,86,143,221,90,77,72,5,177,88,192,170, - 149,115,242,201,110,78,58,165,31,238,131,173,236,172,241,211,212,180,142,250, - 250,173,120,253,187,208,133,195,120,117,136,153,33,96,198,223,198,103,151,83, - 127,30,109,159,226,129,244,235,87,130,211,213,143,225,67,135,3,80,61,196, - 142,195,169,39,166,244,41,129,178,74,253,43,58,216,20,164,172,210,198,193, - 38,221,90,106,53,229,180,52,237,173,161,197,173,81,83,3,97,182,227,243, - 54,176,225,75,195,21,234,37,214,5,90,129,46,158,134,224,237,165,195,186, - 171,68,81,65,187,15,28,142,126,248,253,182,168,184,233,162,167,207,250,243, - 251,65,67,183,232,30,125,244,109,94,253,103,31,238,249,207,177,140,63,127, - 20,39,29,239,32,24,56,64,155,47,76,105,81,21,126,127,16,135,163,136, - 162,34,240,122,245,57,118,14,71,143,253,217,37,197,231,15,49,123,118,29, - 213,213,86,118,239,110,224,195,15,182,160,135,172,20,74,105,40,20,154,166, - 176,226,195,26,218,137,106,221,136,181,186,22,139,114,235,23,221,173,160,61, - 140,221,217,142,114,7,209,130,65,180,160,194,210,170,8,251,252,88,71,248, - 209,148,21,171,102,197,229,220,141,197,91,143,173,109,3,97,26,9,122,198, - 2,138,176,82,17,23,182,66,133,67,104,20,161,40,193,235,221,203,255,253, - 223,219,156,112,98,127,156,78,71,222,79,80,17,132,195,133,30,61,210,24, - 143,158,242,122,253,184,92,14,92,46,7,129,72,250,189,205,222,23,175,215, - 79,93,67,27,143,255,46,192,191,222,88,203,222,186,32,173,237,149,56,173, - 39,224,11,109,194,98,41,97,204,41,86,206,159,212,143,253,251,92,108,252, - 116,19,107,63,91,131,211,190,11,111,224,75,98,197,163,37,198,66,211,180, - 131,192,65,148,42,67,195,197,128,202,179,56,122,240,80,134,15,29,206,144, - 145,147,24,59,102,51,101,253,173,20,23,149,161,84,17,193,112,135,213,103, - 179,148,19,12,183,96,183,58,76,243,216,98,49,31,239,116,157,132,207,171, - 187,97,3,126,61,185,37,28,28,206,182,109,59,217,190,181,150,143,150,5, - 216,85,183,131,150,214,61,120,3,110,116,97,51,158,172,100,176,55,114,62, - 122,34,138,207,111,8,180,30,183,243,250,34,215,51,234,180,106,193,225,176, - 225,247,219,168,169,109,229,158,31,45,227,140,209,75,184,254,230,243,185,238, - 166,19,41,47,9,18,14,235,98,166,187,44,85,116,138,65,236,83,97,122, - 7,31,126,224,166,166,198,195,248,241,101,188,251,206,182,136,219,92,161,207, - 43,180,70,159,65,162,133,218,176,134,247,163,249,27,176,20,181,65,48,4, - 154,130,131,26,22,119,136,176,211,139,229,96,16,2,160,2,160,246,40,104, - 12,97,253,170,34,164,133,177,210,134,203,181,7,213,20,194,90,108,193,231, - 111,67,249,250,1,17,247,48,0,26,10,13,133,5,61,233,177,136,119,223, - 93,206,190,125,151,82,94,94,46,2,39,244,24,122,172,192,217,236,85,81, - 215,164,62,200,234,38,143,197,162,15,212,161,80,136,127,189,227,101,230,127, - 127,201,231,159,151,2,131,9,132,234,128,54,2,150,90,198,95,88,197,153, - 163,7,3,176,244,221,149,17,97,91,143,203,217,76,187,111,23,137,44,181, - 14,151,163,139,1,21,227,57,122,240,80,206,27,127,28,195,71,14,97,244, - 152,190,184,92,97,124,62,31,22,251,30,66,126,221,74,51,230,170,217,44, - 102,151,164,78,81,145,194,23,116,3,16,14,88,41,85,205,184,181,10,2, - 33,63,118,107,199,32,20,14,128,221,106,69,169,34,108,46,125,222,155,221, - 226,97,204,169,197,140,57,245,120,174,249,118,8,180,175,176,123,139,141,181, - 235,107,217,177,101,39,203,62,88,204,65,79,59,237,190,32,177,66,167,91, - 125,122,102,167,139,48,71,69,133,46,28,73,78,1,208,180,129,4,252,245, - 64,3,14,71,63,2,126,47,171,214,55,179,99,214,50,222,95,184,131,251, - 103,94,196,144,163,67,148,149,234,79,204,119,56,28,120,189,126,130,237,94, - 138,250,196,62,254,171,55,240,206,59,245,104,90,16,175,167,141,221,187,247, - 163,34,226,6,26,22,45,16,121,240,177,134,93,237,193,102,173,195,226,241, - 128,37,128,242,135,117,171,171,30,104,13,99,113,249,9,31,12,163,121,20, - 248,65,251,2,52,119,0,172,86,240,132,177,226,69,235,19,70,251,60,136, - 54,18,108,95,214,162,216,13,74,161,66,173,104,24,143,130,179,160,161,69, - 220,212,118,26,155,106,249,108,125,13,71,85,247,163,180,180,84,146,133,132, - 30,65,143,21,56,139,197,26,243,80,97,128,112,88,95,9,249,64,163,159, - 135,254,231,75,158,125,118,23,205,141,186,197,19,82,45,38,139,109,24,101, - 21,126,22,47,94,195,242,15,215,226,247,175,0,246,226,13,212,3,94,208, - 246,71,45,51,167,75,195,231,213,69,174,127,197,49,156,122,220,25,156,112, - 230,137,92,122,213,240,168,104,105,90,59,69,69,30,218,219,53,2,33,63, - 78,187,53,250,148,17,115,138,190,97,173,105,90,59,125,74,245,129,200,26, - 42,195,98,15,97,87,245,248,172,213,20,57,219,112,134,203,176,88,188,145, - 115,114,17,8,123,112,218,44,4,125,26,129,176,7,165,138,112,57,107,241, - 184,245,233,1,118,28,148,148,106,140,58,41,196,209,35,75,240,121,143,227, - 246,187,199,178,254,211,3,44,93,184,140,157,181,62,54,110,218,27,177,238, - 12,203,174,89,239,11,123,208,93,151,58,246,136,235,210,110,111,35,224,47, - 71,163,28,191,223,135,70,16,13,23,141,141,45,188,252,186,143,149,107,246, - 51,125,198,5,92,118,197,96,108,14,55,254,118,40,47,237,143,213,90,132, - 215,235,167,164,119,233,27,235,215,31,196,162,41,14,28,240,16,8,4,98, - 158,26,233,176,4,9,134,218,64,131,62,206,229,56,203,54,163,237,106,1, - 75,24,237,160,134,106,5,246,40,56,168,80,225,0,90,3,112,80,129,71, - 67,173,1,205,10,161,230,48,150,173,26,170,26,180,50,159,190,114,219,233, - 26,214,186,22,172,142,253,160,85,98,87,13,104,106,0,96,204,18,209,208, - 176,161,112,160,148,98,219,182,221,120,218,78,34,24,12,137,192,9,61,130, - 30,43,112,225,112,56,250,79,170,103,244,21,17,10,5,121,243,45,61,214, - 246,242,243,149,248,66,245,104,218,54,52,173,47,85,229,54,190,126,73,95, - 206,56,171,146,213,43,155,120,226,15,47,226,247,175,71,95,242,202,135,203, - 105,35,172,181,224,243,234,113,12,167,75,195,239,5,139,26,197,25,163,207, - 230,130,11,207,231,180,209,67,24,118,172,23,139,197,75,123,187,134,57,245, - 223,16,55,0,159,55,68,105,113,49,118,239,30,220,84,80,84,164,162,125, - 54,132,203,98,45,35,24,8,96,177,135,176,217,237,40,251,96,138,44,165, - 104,22,221,114,11,6,237,145,227,192,70,57,54,155,13,135,19,244,57,182, - 160,194,39,211,183,18,52,139,23,111,123,59,237,62,221,165,105,183,20,83, - 214,183,8,111,123,59,167,141,237,207,248,175,126,159,186,221,65,182,109,219, - 201,7,139,183,241,193,71,59,168,63,240,37,46,123,63,147,59,211,112,93, - 186,162,174,203,128,223,133,194,134,69,43,71,195,133,82,70,34,138,23,135, - 195,198,206,218,125,220,121,199,31,185,115,253,87,184,243,199,19,169,168,40, - 166,169,169,137,146,146,50,28,142,14,87,177,129,221,110,167,39,179,171,214, - 131,82,62,90,91,218,245,39,139,152,246,89,53,47,168,38,80,33,138,42, - 215,227,168,173,135,93,94,180,150,48,106,31,68,115,151,172,26,150,58,69, - 120,139,166,39,229,239,4,109,183,238,238,213,62,181,192,138,16,218,16,13, - 174,208,80,171,194,168,19,172,88,215,183,99,119,4,209,148,194,174,234,9, - 171,190,128,185,125,45,242,242,211,122,176,5,159,207,71,40,24,4,167,184, - 41,133,35,159,30,43,112,198,3,146,13,161,107,246,4,120,253,197,90,30, - 127,100,51,235,54,84,98,213,202,113,90,79,32,76,43,151,92,234,103,194, - 5,67,169,173,217,197,63,254,111,30,171,214,127,134,62,162,128,177,218,135, - 215,191,31,0,141,254,184,28,253,232,83,116,2,227,47,154,200,121,19,71, - 68,221,143,1,21,17,236,167,215,0,0,32,0,73,68,65,84,196,235,181, - 0,197,56,172,26,254,80,108,150,117,177,189,56,250,183,197,210,70,168,184, - 28,103,216,137,17,146,178,217,237,216,108,186,21,231,34,8,54,59,1,91, - 17,246,96,59,1,91,17,250,242,92,17,203,206,102,199,17,121,172,147,63, - 24,27,211,10,250,173,20,89,220,145,50,118,156,78,23,37,142,62,132,130, - 186,168,4,131,65,156,206,74,240,53,17,8,236,161,255,0,232,211,183,63, - 167,126,101,20,87,111,110,99,237,250,90,22,189,183,36,98,213,65,71,66, - 138,43,234,186,132,19,209,104,70,41,125,187,194,133,22,201,252,244,251,27, - 208,112,225,243,151,241,200,255,174,102,199,150,157,220,113,239,13,156,126,122, - 41,237,254,38,28,214,210,94,23,231,113,183,249,9,171,32,222,128,130,24, - 121,83,88,9,65,200,131,166,52,172,190,54,180,5,237,96,213,8,109,5, - 203,70,244,135,97,109,80,112,52,168,26,11,172,6,26,52,248,204,2,77, - 97,148,15,212,75,26,218,78,96,151,130,127,162,207,70,91,24,70,109,128, - 240,208,96,36,139,210,139,10,7,232,16,53,69,199,16,16,34,24,244,18, - 10,135,8,201,138,17,66,15,225,136,21,56,191,111,63,14,103,255,232,178, - 52,118,123,128,80,208,67,32,88,76,81,81,17,160,17,10,181,17,8,216, - 169,107,104,99,238,159,219,120,242,209,38,90,90,135,1,45,4,66,117,28, - 59,34,196,165,87,192,240,225,240,254,194,37,188,241,214,199,120,253,203,0, - 23,104,203,162,109,41,85,6,170,140,34,103,63,78,60,238,27,156,54,230, - 2,174,254,182,162,184,168,44,242,228,119,61,182,6,62,140,12,235,64,24, - 52,13,74,85,51,7,57,10,151,75,23,33,91,196,82,177,217,42,99,206, - 167,200,21,159,222,175,127,118,0,216,74,40,209,83,66,177,218,59,127,101, - 230,8,90,40,16,196,90,106,35,20,176,162,133,130,216,173,54,2,182,32, - 96,1,155,209,134,19,127,48,132,102,49,150,235,210,219,9,6,91,25,118, - 108,128,97,199,246,231,210,111,222,198,186,79,182,176,116,225,50,62,254,196, - 79,253,129,253,116,100,101,238,141,12,209,250,4,114,135,163,148,128,223,25, - 153,36,78,68,232,234,81,52,163,225,226,159,243,119,177,106,221,139,81,151, - 37,142,22,188,173,54,92,46,189,231,37,37,37,132,195,33,130,129,70,172, - 182,98,66,65,79,116,222,92,79,161,184,72,161,84,64,127,246,99,28,74, - 249,177,104,65,194,74,67,237,10,163,109,1,205,29,70,149,88,96,113,8, - 181,221,130,230,86,208,10,106,29,104,155,194,168,70,13,150,40,44,45,10, - 66,160,205,11,161,133,129,144,34,252,135,48,90,11,80,175,80,125,52,148, - 223,6,132,208,226,44,199,72,235,232,79,219,242,69,166,112,164,93,4,85, - 16,142,24,142,88,129,51,196,205,110,183,99,181,134,1,43,86,27,56,156, - 198,250,109,161,168,184,253,120,106,13,11,222,116,0,37,4,66,117,216,173, - 213,76,249,238,64,206,56,171,146,218,154,93,60,242,255,86,80,83,187,4, - 248,2,104,142,12,204,224,112,246,193,239,117,82,228,44,101,196,49,103,50, - 233,162,115,185,240,107,231,81,125,180,141,214,214,189,88,236,250,157,174,46, - 110,157,113,58,157,252,127,246,222,60,76,146,187,188,243,252,252,34,34,35, - 35,242,172,234,67,125,168,15,169,133,64,128,36,131,64,216,128,56,4,22, - 12,198,35,155,177,13,99,204,53,48,94,179,158,193,54,207,120,125,141,189, - 140,199,187,235,93,219,15,107,60,152,181,215,120,0,11,49,44,54,216,150, - 64,92,58,26,1,22,70,66,72,180,110,212,221,213,93,173,62,170,171,42, - 239,140,243,23,191,253,227,23,17,25,153,85,221,18,72,178,212,234,248,62, - 79,62,149,25,25,25,17,121,84,124,227,251,190,223,247,125,35,182,208,168, - 152,232,225,199,228,3,38,139,10,12,160,98,90,107,200,75,38,53,76,99, - 140,227,172,117,82,38,193,16,79,54,169,215,84,254,216,168,54,40,248,92, - 114,248,254,218,46,41,149,40,38,42,236,63,83,129,150,101,17,199,49,68, - 43,188,244,229,231,240,35,63,250,46,126,230,161,17,255,240,247,223,228,155, - 183,101,78,204,57,38,101,17,157,60,108,169,212,86,4,25,209,101,101,17, - 58,228,186,176,248,61,126,251,55,238,227,158,125,175,228,173,239,188,138,103, - 239,74,240,125,159,122,189,201,104,52,194,182,109,236,234,102,134,157,62,110, - 171,54,123,184,103,60,182,109,183,185,247,62,125,49,54,81,80,26,6,49, - 9,33,2,5,15,42,196,137,68,183,50,254,91,116,100,120,168,80,182,129, - 216,106,32,238,75,224,152,64,4,10,113,167,66,164,230,20,21,162,121,170, - 34,48,150,18,136,4,140,20,72,19,122,18,68,246,93,167,251,87,73,250, - 40,4,70,64,72,205,117,17,156,125,14,215,18,207,92,156,177,4,7,58, - 111,147,36,178,48,171,205,45,204,104,19,124,243,246,49,255,237,79,244,248, - 26,3,109,149,54,140,30,191,252,190,77,236,220,85,225,182,189,69,213,214, - 197,169,74,188,160,139,16,218,222,31,250,109,158,119,225,143,78,17,219,208, - 31,208,79,139,208,146,200,36,152,233,48,146,205,242,154,40,181,233,143,56, - 83,106,153,122,209,247,221,148,160,38,68,102,89,25,33,78,43,189,194,139, - 168,205,60,46,34,142,35,44,43,59,6,115,230,57,137,143,55,69,168,14, - 90,253,69,50,70,43,188,4,25,71,180,172,49,173,75,5,239,221,121,57, - 175,252,241,87,241,245,155,23,248,194,23,191,140,31,117,243,215,138,66,91, - 176,138,189,137,40,212,46,203,68,245,152,152,85,28,142,175,248,92,123,205, - 173,116,78,26,252,230,255,122,57,243,243,27,144,50,194,247,125,76,179,130, - 148,33,181,118,3,207,243,158,113,38,148,75,46,105,114,227,87,15,34,227, - 116,78,155,82,100,85,105,134,136,49,240,181,228,191,31,68,8,201,6,19, - 113,60,129,45,2,33,21,188,72,144,60,43,65,124,43,165,198,170,64,89, - 10,53,111,64,32,80,231,131,88,76,80,182,64,109,177,16,75,18,85,51, - 97,12,34,72,16,106,58,48,138,32,117,110,234,18,23,33,60,182,109,223, - 134,145,155,75,74,37,87,226,204,199,25,75,112,89,103,146,48,148,152,102, - 130,105,26,121,206,13,4,215,127,97,200,239,255,222,67,28,89,20,233,108, - 182,69,46,56,175,193,47,253,199,139,216,208,94,225,207,255,244,11,220,251, - 192,3,248,209,215,177,157,37,2,95,225,135,131,180,171,196,102,206,153,219, - 197,203,94,118,5,63,247,51,47,97,207,243,118,0,62,253,254,144,72,134, - 52,106,205,53,170,109,118,72,101,70,108,197,208,227,44,169,233,245,82,34, - 115,54,61,234,123,118,28,7,223,247,243,237,168,112,58,87,34,108,115,178, - 188,240,205,102,68,87,124,156,109,35,142,35,226,88,111,167,72,122,149,164, - 70,20,174,226,249,1,181,120,25,115,243,54,94,251,90,131,221,187,206,103, - 247,158,215,241,181,155,14,115,239,3,183,225,71,67,156,74,3,136,241,163, - 99,132,97,23,199,222,72,24,61,43,45,41,152,180,57,19,192,210,138,207, - 199,175,189,131,94,111,129,223,249,131,247,176,123,71,64,24,104,243,9,104, - 67,144,109,219,83,23,46,207,4,188,250,213,155,248,211,255,59,64,97,1, - 6,19,5,167,205,250,217,212,25,241,8,40,19,196,11,149,14,67,158,11, - 226,30,224,71,20,226,121,2,113,103,130,122,149,129,184,39,85,90,239,51, - 81,127,43,225,117,160,238,53,244,107,63,0,252,207,2,245,203,6,124,26, - 212,200,70,29,158,158,244,173,72,208,57,221,85,96,149,102,115,142,103,61, - 107,51,150,101,165,230,172,178,155,73,137,51,31,103,44,193,233,249,100,186, - 120,59,73,146,188,51,9,192,245,95,24,242,27,239,63,68,167,163,201,13, - 224,210,139,77,254,227,111,236,102,184,124,128,63,255,211,175,113,199,190,135, - 17,220,8,98,145,48,208,23,207,74,53,113,171,23,242,202,75,183,241,250, - 183,188,139,61,123,118,177,101,155,207,104,56,204,107,207,44,163,141,159,94, - 108,131,38,54,109,14,153,254,40,179,16,100,49,244,232,56,110,65,153,173, - 117,13,58,51,42,108,61,212,235,77,164,140,48,205,10,184,149,201,125,152, - 90,46,228,169,201,193,247,125,170,70,133,32,209,42,175,168,244,50,178,27, - 141,97,110,110,158,57,160,219,173,18,12,71,72,203,226,89,23,86,217,126, - 238,179,185,248,146,75,184,241,182,157,220,244,247,95,231,196,202,34,90,193, - 105,210,246,195,35,8,154,147,239,42,175,19,204,218,149,29,227,239,63,15, - 194,184,145,223,254,253,31,231,252,243,155,116,86,15,99,87,231,113,28,7, - 215,117,243,230,205,32,158,17,147,9,94,253,234,45,108,219,86,225,232,209, - 49,66,88,104,133,148,118,50,1,29,50,84,9,201,11,5,28,23,122,170, - 218,191,209,117,110,180,13,216,149,32,46,5,213,50,48,126,18,146,142,129, - 216,35,224,53,9,124,27,248,49,129,114,5,60,87,65,61,33,185,194,192, - 184,66,161,150,5,198,189,105,24,51,177,152,140,145,0,29,62,62,10,44, - 241,242,151,190,142,122,221,198,169,58,152,230,25,123,90,40,81,98,10,103, - 236,47,89,55,71,118,114,37,103,85,54,16,69,17,55,124,201,227,99,31, - 61,192,225,67,155,210,110,36,49,47,127,197,14,222,249,139,59,216,119,251, - 33,62,121,205,55,88,89,189,29,193,131,128,38,181,44,36,185,101,254,10, - 222,248,250,87,241,243,239,126,9,181,218,152,36,25,48,28,24,128,139,101, - 184,218,64,33,60,92,87,145,36,19,50,42,146,155,235,84,167,136,74,38, - 53,28,71,97,89,230,163,146,90,70,84,250,254,169,175,160,77,211,78,115, - 57,179,175,169,228,175,51,205,105,151,162,44,56,58,235,245,180,216,87,78, - 20,95,145,236,226,56,162,89,215,5,230,99,15,42,246,6,182,159,179,25, - 211,142,233,118,59,8,195,231,71,46,147,60,255,226,231,240,162,139,42,124, - 234,19,7,82,53,60,64,49,143,118,85,30,215,251,192,1,182,166,106,46, - 43,140,247,169,216,13,254,238,186,155,168,158,147,240,171,191,248,28,118,237, - 218,72,213,208,199,181,178,26,210,108,24,105,121,71,26,198,59,195,73,206, - 117,13,254,221,187,47,228,127,255,223,190,73,146,151,84,232,247,36,149,77, - 162,218,8,49,132,203,76,24,9,125,173,112,169,130,19,144,92,4,194,48, - 48,26,10,181,19,212,14,96,167,34,121,41,136,86,2,91,12,146,103,9, - 140,177,128,182,64,36,10,181,195,68,41,136,247,212,137,190,151,54,215,78, - 54,163,132,9,72,164,12,81,28,4,246,99,89,49,63,241,198,43,113,28, - 135,122,189,190,230,98,173,68,137,51,21,103,236,47,57,81,109,180,83,82, - 166,131,73,147,156,220,244,116,237,69,12,163,206,79,190,209,229,234,183,180, - 185,121,239,141,124,238,111,190,13,106,1,216,159,54,70,78,91,106,169,205, - 92,118,201,207,240,182,119,190,150,151,190,252,28,134,3,137,231,9,92,215, - 135,66,166,171,209,52,137,35,125,162,118,220,73,190,108,54,12,89,52,133, - 88,150,49,69,108,143,70,104,82,42,221,48,55,205,47,74,153,228,53,98, - 153,169,6,32,43,27,155,206,65,202,52,76,91,92,150,164,235,27,249,84, - 133,108,134,91,86,114,48,171,248,84,88,33,74,143,199,174,234,159,72,28, - 71,4,99,139,138,189,1,199,25,19,251,29,98,203,229,138,87,236,97,207, - 158,93,92,247,217,243,184,225,75,123,83,183,229,54,244,104,32,23,199,174, - 19,132,126,154,209,209,198,19,197,54,130,240,8,6,115,92,251,209,91,240, - 143,47,230,225,74,252,136,154,235,144,157,252,225,204,39,55,208,223,245,175, - 252,202,101,124,250,211,223,101,255,254,19,160,234,105,184,18,66,213,32,97, - 19,138,69,146,115,155,168,241,42,84,37,70,3,146,182,208,132,118,212,66, - 142,13,196,206,152,196,146,136,109,6,198,115,0,97,146,108,53,48,170,2, - 181,33,37,183,88,64,195,36,92,106,49,54,183,226,123,231,130,234,16,25, - 155,208,255,242,9,126,176,4,220,131,16,71,120,227,27,126,154,103,95,180, - 133,86,171,77,173,86,195,52,207,252,207,187,68,9,56,131,9,206,182,173, - 244,196,167,79,157,223,250,198,152,15,253,241,2,123,191,177,60,85,223,118, - 245,91,246,112,243,222,27,249,212,71,191,136,182,164,221,13,98,49,207,48, - 56,246,249,188,254,181,87,243,31,126,237,167,104,183,219,244,122,61,106,181, - 49,227,113,141,241,88,43,182,72,134,84,29,19,47,208,133,210,134,57,9, - 191,205,42,182,44,12,121,58,82,155,85,103,197,34,103,211,156,228,213,178, - 73,8,235,173,87,92,103,246,254,244,50,125,178,210,74,119,250,121,211,44, - 14,44,157,168,66,220,10,97,172,73,59,73,123,137,89,214,8,106,17,21, - 57,214,203,157,237,169,59,211,231,185,23,85,217,249,235,175,229,226,23,26, - 124,242,19,55,241,221,125,154,220,192,195,15,87,210,246,80,78,170,226,118, - 35,232,161,184,141,132,243,49,216,202,13,95,57,70,187,241,81,222,251,254, - 171,216,179,103,107,154,103,204,223,53,16,61,35,10,193,55,108,112,249,171, - 191,250,9,222,244,166,191,162,219,61,130,38,113,131,80,213,81,198,70,16, - 130,136,45,196,219,79,96,85,124,18,51,70,181,4,230,156,34,60,86,65, - 12,106,152,219,6,24,102,130,154,135,100,83,5,124,129,218,36,144,253,42, - 212,18,196,106,132,41,5,177,211,164,191,242,108,58,222,243,24,69,231,161, - 232,33,204,38,154,187,150,145,242,102,16,247,243,188,231,190,128,119,188,235, - 77,52,27,45,230,231,231,215,117,236,150,40,113,166,226,105,79,112,197,89, - 110,197,19,183,82,30,73,226,162,148,207,157,119,43,62,240,129,5,110,187, - 109,35,134,49,38,161,207,213,111,124,136,183,189,231,53,92,247,153,91,248, - 212,181,95,196,173,46,50,14,190,3,164,89,8,245,44,156,170,228,223,191, - 251,125,188,245,29,47,2,32,8,58,212,106,186,11,73,177,133,86,163,166, - 9,45,203,181,205,58,33,103,73,45,11,181,101,166,143,76,169,21,137,237, - 84,39,236,39,203,88,177,158,10,154,37,208,140,92,165,76,104,102,138,210, - 82,233,50,7,223,7,82,87,167,38,33,125,50,148,81,76,213,90,224,141, - 63,113,33,155,231,183,241,217,207,254,45,255,120,67,162,167,137,87,98,252, - 232,32,176,13,149,135,42,33,47,20,231,187,248,225,60,255,227,115,128,249, - 48,255,225,215,119,179,109,243,113,172,120,68,104,62,135,102,3,194,48,68, - 37,93,172,202,6,178,28,210,153,168,234,12,195,224,165,47,221,193,39,175, - 125,59,191,250,190,143,179,255,192,1,192,66,41,19,101,85,80,106,153,208, - 223,78,92,63,134,80,39,16,67,129,209,16,72,37,80,102,155,96,84,199, - 110,199,84,172,24,54,130,178,42,36,99,27,90,38,126,175,137,105,68,84, - 43,3,146,88,17,219,13,70,225,30,252,202,139,168,52,218,168,164,167,115, - 107,106,12,220,136,97,220,193,203,95,246,26,222,247,190,183,178,105,83,147, - 205,155,55,209,110,183,215,56,110,75,148,56,147,33,148,82,79,123,63,112, - 22,102,155,61,169,133,193,73,18,213,230,245,111,56,193,253,223,59,206,114, - 167,71,197,220,206,243,159,63,228,3,127,112,17,31,251,232,1,190,242,165, - 191,196,143,190,78,54,163,45,235,248,127,206,220,179,249,173,223,253,45,174, - 120,197,30,130,160,147,183,215,42,186,36,179,92,91,209,242,255,88,200,237, - 84,196,150,57,61,159,174,40,94,76,76,194,152,58,108,42,229,164,181,86, - 230,228,244,125,31,223,247,49,132,199,160,31,131,217,194,114,93,142,126,255, - 56,31,250,208,131,124,246,186,191,3,64,49,95,104,72,61,135,83,221,140, - 31,232,194,241,164,80,70,224,216,38,191,252,203,186,181,151,107,172,96,87, - 231,73,84,157,154,43,113,28,240,125,253,153,102,83,9,206,68,40,149,16, - 132,1,135,15,157,224,83,159,218,203,183,191,253,61,94,247,186,203,217,186, - 117,27,142,24,240,188,29,15,83,79,238,160,238,44,96,84,187,136,48,68, - 218,54,225,96,51,82,213,169,87,15,224,52,143,162,142,216,68,187,90,168, - 113,149,184,91,33,168,110,199,48,198,184,98,9,163,145,208,235,110,161,151, - 92,137,116,95,141,221,216,193,87,190,124,128,23,94,118,14,215,93,119,132, - 163,71,111,231,178,23,157,207,243,158,191,131,102,189,193,57,91,54,115,206, - 57,91,104,54,235,8,241,204,10,13,151,56,187,241,180,37,184,217,60,210, - 122,255,108,157,254,9,254,235,127,17,124,228,191,45,35,85,143,138,216,201, - 249,123,238,227,215,63,240,99,236,187,253,16,127,249,145,143,224,71,119,160, - 88,72,199,215,104,156,51,247,6,126,243,63,191,155,43,94,177,7,128,149, - 206,97,0,42,166,141,235,42,60,79,228,182,255,44,215,150,185,34,79,69, - 108,217,242,89,82,59,147,67,107,186,89,181,145,147,93,22,194,204,200,206, - 247,211,190,153,149,152,208,83,196,177,68,134,22,126,44,57,178,212,227,191, - 127,226,126,110,250,251,175,115,124,37,158,26,238,234,86,47,196,15,66,20, - 65,170,226,124,28,219,196,15,143,176,101,227,102,126,251,247,222,201,207,191, - 245,34,250,189,35,108,216,220,196,54,27,168,80,98,185,14,82,70,212,207, - 240,34,57,165,20,97,24,210,235,245,232,116,58,120,222,152,118,123,142,154, - 99,19,12,142,144,140,23,48,195,5,100,176,132,72,134,196,202,33,82,13, - 44,161,152,179,239,161,218,56,8,67,131,145,53,143,140,90,36,170,73,144, - 108,199,32,166,102,29,71,17,227,39,155,24,155,47,198,158,191,140,249,77, - 231,98,24,22,158,231,165,249,106,73,183,219,69,8,65,187,221,98,110,110, - 158,90,173,182,230,127,172,36,184,18,103,58,206,8,130,203,32,229,8,211, - 212,39,55,223,15,249,200,95,140,248,237,255,229,88,78,110,9,125,62,243, - 185,29,92,247,153,91,248,216,181,159,7,246,98,59,61,66,191,10,66,247, - 146,124,221,139,223,200,219,222,251,219,60,255,50,155,149,147,195,124,238,26, - 144,171,55,223,55,104,52,205,169,90,182,204,238,127,58,98,51,77,129,148, - 10,219,54,159,214,74,237,135,69,214,32,185,168,232,50,146,3,109,68,73, - 228,144,65,63,166,222,108,114,244,104,151,255,239,127,60,196,181,215,220,202, - 241,149,24,35,173,137,83,248,24,226,57,105,33,56,192,241,156,224,160,203, - 139,46,185,138,223,253,253,87,243,226,203,55,97,8,143,68,185,216,213,141, - 52,27,147,19,238,153,172,226,50,72,41,9,130,32,189,144,176,168,84,76, - 100,36,9,131,62,161,215,199,31,119,241,253,49,74,42,132,89,193,52,98, - 42,241,9,146,96,129,36,140,9,100,13,101,212,81,118,27,163,210,194,52, - 45,76,124,100,28,32,149,141,225,108,165,57,191,133,246,220,102,236,170,157, - 183,225,146,82,18,199,17,134,48,176,171,85,42,21,107,221,41,222,37,193, - 149,56,211,113,198,16,156,148,163,188,71,97,146,36,133,90,55,159,213,158, - 238,239,247,71,127,114,17,0,191,251,155,191,3,198,221,248,193,162,182,165, - 167,234,237,133,23,191,151,247,255,218,219,184,252,37,138,35,199,251,83,251, - 203,148,27,64,123,110,82,156,92,52,145,56,142,155,223,207,66,145,179,166, - 145,51,89,177,61,26,138,33,204,48,148,216,182,137,148,137,206,145,165,165, - 6,70,69,127,23,171,39,7,56,142,203,209,163,93,110,187,45,226,15,255, - 224,19,28,95,137,169,218,59,8,194,35,8,206,67,80,69,17,160,123,91, - 102,51,232,0,60,254,205,79,94,206,239,252,193,123,104,55,142,35,42,9, - 219,207,57,143,209,104,192,220,156,67,20,85,114,167,233,51,1,74,169,41, - 130,145,82,18,69,49,97,20,33,227,40,111,94,96,152,6,42,86,248,129, - 135,31,120,200,56,198,52,13,76,203,161,82,177,168,88,22,166,97,16,203, - 136,56,78,176,42,22,174,227,80,117,92,108,187,114,218,125,174,135,146,224, - 74,156,233,120,90,155,76,38,147,159,21,50,30,99,90,53,146,36,225,174, - 125,99,62,246,209,3,116,58,17,171,189,24,165,86,248,149,95,217,205,5, - 23,152,188,229,231,254,31,194,104,17,197,247,17,56,121,141,219,101,151,252, - 2,239,255,181,183,113,209,165,130,135,14,30,161,209,170,145,68,154,64,35, - 25,130,103,83,111,52,136,83,149,114,42,213,54,155,99,43,146,219,51,125, - 134,86,177,28,161,82,137,144,82,164,189,64,77,112,21,194,243,9,229,144, - 208,83,52,26,13,226,88,210,158,155,231,138,87,181,248,133,133,87,242,145, - 143,252,51,126,248,48,130,57,244,4,241,185,212,50,162,123,91,42,72,77, - 41,240,185,207,127,157,243,158,181,139,183,190,243,42,118,158,107,177,116,172, - 67,115,99,150,135,211,199,83,44,155,56,147,49,75,52,166,105,98,24,6, - 182,109,161,84,218,192,58,171,207,86,80,147,13,18,25,163,18,133,48,4, - 66,8,76,211,200,183,163,148,238,203,37,12,93,36,191,222,239,242,209,200, - 173,68,137,103,2,158,214,4,167,187,155,107,123,187,105,213,16,194,101,225, - 104,143,107,62,126,132,127,250,70,148,155,74,222,240,70,151,87,191,102,55, - 255,254,223,253,13,97,248,48,78,117,63,126,56,192,174,10,2,191,201,243, - 47,124,61,239,255,181,183,241,156,139,93,186,222,67,52,218,219,144,65,66, - 156,244,176,140,54,115,237,9,177,101,57,183,245,114,109,142,227,60,163,114, - 108,63,44,52,209,213,137,162,112,170,172,193,117,93,240,64,213,45,164,175, - 104,219,33,134,88,98,227,134,42,111,125,231,85,0,124,240,79,111,200,167, - 160,103,211,6,20,115,232,98,240,227,248,209,49,116,135,141,121,174,189,230, - 86,46,190,228,18,230,54,110,36,26,31,166,185,113,87,161,132,64,95,92, - 60,83,72,110,22,66,8,221,179,114,29,232,200,121,229,49,169,176,18,37, - 206,102,60,237,99,16,25,201,9,161,137,103,223,119,77,174,251,204,1,86, - 123,49,21,115,59,231,237,150,92,253,150,61,124,242,175,111,102,117,245,4, - 176,23,47,88,6,32,240,21,91,230,175,224,61,191,244,22,46,186,84,104, - 51,137,191,133,36,28,33,132,71,163,214,68,8,143,56,138,112,92,23,203, - 178,104,213,235,180,234,117,106,238,36,36,89,236,221,8,167,239,50,114,182, - 32,138,34,236,172,247,165,242,241,60,29,94,180,109,155,154,37,112,77,61, - 220,213,174,206,211,27,173,176,101,83,143,183,190,243,42,126,230,234,55,98, - 176,181,176,37,93,31,103,136,54,176,53,237,132,162,113,98,101,200,223,252, - 191,95,224,192,3,247,211,154,159,103,105,241,48,137,170,231,61,56,165,124, - 90,70,215,255,197,80,146,91,137,18,167,199,211,154,224,146,36,201,29,148, - 113,180,194,93,251,198,124,240,131,61,14,157,56,135,138,216,137,84,61,222, - 242,142,121,246,221,126,136,235,191,244,32,138,91,32,203,185,169,75,112,171, - 155,120,243,191,189,138,203,95,50,143,239,121,121,61,155,82,154,44,147,200, - 164,90,173,230,170,205,117,170,186,111,164,217,194,48,27,56,142,67,213,168, - 80,175,55,49,205,10,182,109,231,185,159,236,118,182,162,82,169,228,117,116, - 166,89,79,157,141,10,211,52,49,77,65,181,225,98,185,250,162,96,126,78, - 215,87,157,187,117,200,219,222,117,62,175,125,201,241,116,43,91,81,116,129, - 19,40,117,2,67,180,83,242,155,71,119,185,63,200,222,127,190,135,47,124, - 161,201,96,164,59,202,196,225,17,60,105,51,26,13,144,82,143,159,153,157, - 14,94,162,68,137,18,240,52,38,56,125,242,52,82,91,243,136,97,212,98, - 239,45,17,251,238,216,135,41,218,68,106,145,151,93,89,101,208,181,249,135, - 207,125,11,67,125,23,8,242,58,55,232,242,243,111,250,37,174,126,211,11, - 0,61,179,45,8,2,173,216,146,30,174,171,48,42,50,175,113,203,204,36, - 53,23,218,173,73,123,173,73,190,237,236,13,73,62,118,100,245,126,102,222, - 114,204,113,28,108,179,129,101,85,104,183,55,240,178,43,158,195,91,127,233, - 87,121,209,37,59,128,227,216,182,158,162,144,53,100,86,233,116,112,13,7, - 56,198,55,110,190,153,111,127,227,40,173,249,121,6,253,24,111,160,221,151, - 69,7,103,73,114,37,74,148,152,197,211,150,224,64,59,39,51,44,236,143, - 248,228,199,191,79,24,235,147,232,198,141,93,126,250,141,231,115,235,141,119, - 112,104,241,203,248,209,55,113,170,195,220,84,242,186,203,47,229,234,55,95, - 73,187,221,198,247,13,92,87,105,51,9,186,51,73,146,56,121,88,50,35, - 55,199,113,49,210,147,113,213,152,228,220,74,114,123,108,40,186,238,108,219, - 76,213,92,37,207,91,142,70,3,76,71,240,202,171,54,242,246,247,188,138, - 45,27,99,162,48,38,155,37,167,84,90,87,199,86,178,105,225,0,223,217, - 247,85,110,185,249,17,142,157,220,138,146,3,162,100,64,28,103,37,11,81, - 90,182,160,149,92,209,233,249,84,35,187,64,59,83,111,37,74,156,233,120, - 218,254,138,51,7,101,24,156,196,52,235,236,189,37,226,222,123,27,248,209, - 28,82,245,184,234,170,231,176,120,56,226,232,177,175,2,15,224,84,27,248, - 225,65,0,182,204,95,193,59,222,251,86,182,159,107,209,235,245,166,219,110, - 41,221,57,99,86,185,205,58,37,45,119,66,110,166,105,148,228,246,24,81, - 60,57,106,7,159,192,113,108,90,173,22,85,163,130,244,21,245,74,192,21, - 175,122,22,191,240,246,87,162,232,22,212,91,144,182,242,106,167,203,92,52, - 249,117,185,235,123,183,240,189,59,143,35,204,38,190,239,19,199,186,150,203, - 247,253,169,46,43,197,14,44,37,74,148,56,187,241,180,37,56,32,47,234, - 190,243,238,33,127,249,225,35,0,36,201,136,11,206,107,176,231,217,54,183, - 222,120,7,189,190,190,234,79,196,138,126,145,218,204,219,222,249,14,46,188, - 248,34,134,254,32,39,55,207,19,204,27,99,34,103,11,134,225,79,41,55, - 153,212,166,156,146,154,220,68,158,111,43,218,227,75,60,54,20,107,24,51, - 167,99,173,173,219,110,217,174,96,231,185,22,175,184,242,181,121,168,18,192, - 182,99,77,114,194,73,139,194,231,208,142,74,135,239,238,27,241,245,155,239, - 165,55,144,120,126,128,239,123,249,236,58,21,202,41,146,43,81,162,68,9, - 120,26,19,156,148,146,36,73,176,171,155,185,230,227,7,217,191,48,204,159, - 187,252,199,234,124,239,59,203,220,255,208,173,248,209,62,192,37,12,116,225, - 246,57,243,47,230,21,175,220,67,175,215,35,9,71,185,161,4,64,53,119, - 96,85,42,180,170,205,117,115,110,85,163,50,51,83,109,182,117,209,51,187, - 206,237,201,64,166,124,179,98,229,12,134,24,241,178,151,218,188,245,157,123, - 242,34,111,29,174,212,80,204,165,245,114,78,122,235,112,195,151,246,114,219, - 109,17,173,214,54,0,124,223,195,247,125,130,100,210,97,69,239,171,188,16, - 41,81,162,196,211,152,224,178,19,227,157,119,15,249,242,13,199,180,177,68, - 30,229,194,61,91,0,184,251,174,219,211,217,110,39,64,236,3,244,232,155, - 223,252,207,239,230,220,157,49,142,163,67,85,153,130,203,122,75,2,8,167, - 158,219,254,179,156,91,166,220,138,251,47,9,237,241,35,73,100,218,100,218, - 72,139,151,109,92,123,158,86,171,69,179,97,240,170,215,94,201,207,94,253, - 90,244,48,212,174,158,250,173,124,4,85,42,182,133,98,27,89,152,242,196, - 202,73,110,189,241,107,28,89,234,233,208,100,164,9,113,54,84,89,134,41, - 75,148,40,1,79,99,130,75,146,4,165,60,174,249,248,65,30,218,223,212, - 253,38,205,237,60,247,249,146,96,248,61,22,22,191,135,31,45,67,234,154, - 84,170,201,79,92,245,94,174,120,197,30,150,87,150,8,130,32,223,86,197, - 208,22,115,211,104,208,108,76,26,245,234,188,219,68,185,1,121,206,173,196, - 19,3,165,52,97,77,186,210,232,62,146,82,42,188,176,195,121,23,84,120, - 195,155,95,195,174,157,187,176,237,77,41,169,233,48,101,24,46,207,108,173, - 203,55,111,91,224,248,67,247,17,198,9,145,140,167,66,149,64,110,56,41, - 81,162,68,137,167,236,76,94,12,35,37,137,92,115,139,163,21,162,168,194, - 13,215,79,94,115,193,158,35,52,154,45,238,248,238,73,4,247,3,135,242, - 38,202,110,245,66,222,254,238,87,19,69,199,176,140,246,212,190,140,138,196, - 113,93,132,161,201,176,104,42,129,233,82,128,127,41,114,203,106,252,214,127, - 238,212,159,205,227,217,238,169,95,35,215,236,247,137,130,105,214,49,205,122, - 110,60,201,148,185,33,122,184,246,60,210,87,252,212,235,35,94,243,202,115, - 136,163,141,68,97,156,207,140,19,236,166,106,239,64,215,197,233,118,94,253, - 225,253,220,112,155,32,14,77,60,63,64,70,49,134,208,161,202,177,103,230, - 219,46,203,6,74,148,40,241,148,17,220,163,133,255,172,202,6,62,245,57, - 159,78,39,53,145,36,35,28,119,142,96,248,61,78,156,216,15,76,106,160, - 148,106,242,243,111,122,51,245,198,136,32,158,62,185,87,171,213,53,142,73, - 96,77,251,45,77,110,230,154,33,160,79,38,214,179,98,207,146,27,76,84, - 208,169,158,159,221,230,15,98,241,206,154,90,23,255,254,75,64,15,47,37, - 157,245,230,112,245,155,175,100,195,134,118,161,6,110,130,98,93,156,23,196, - 60,248,207,139,28,125,36,70,37,122,121,236,75,44,203,196,16,163,41,179, - 201,15,74,244,37,74,148,120,102,225,41,143,197,205,158,80,51,130,145,50, - 225,139,159,185,153,213,94,140,41,218,108,154,111,179,107,183,205,129,3,54, - 126,120,15,208,5,124,148,106,114,206,220,179,185,250,205,87,2,32,195,6, - 166,173,13,41,25,185,89,150,133,105,85,168,152,186,245,102,163,209,88,99, - 42,209,57,183,127,185,143,99,118,95,153,66,155,132,244,228,20,177,1,83, - 207,101,53,130,63,136,186,91,255,56,204,117,255,62,217,144,50,73,75,8, - 244,227,87,92,89,229,95,255,43,27,183,218,76,39,12,104,132,161,149,206, - 146,155,16,223,119,246,125,149,3,7,244,12,191,72,198,120,161,14,73,250, - 190,143,10,37,81,92,75,247,81,154,77,74,148,56,155,241,148,134,40,51, - 213,80,84,77,89,136,109,223,125,1,55,221,164,103,126,73,213,67,88,203, - 172,142,19,14,31,61,128,38,183,0,196,73,4,14,175,184,226,205,108,63, - 87,147,151,227,36,72,99,132,81,153,62,185,217,150,129,89,177,114,114,43, - 150,3,60,153,53,110,143,37,252,87,84,106,25,178,251,50,30,175,185,101, - 207,197,209,234,15,164,238,126,16,34,92,143,56,159,104,117,87,169,84,144, - 241,24,128,185,90,133,183,254,79,175,162,222,152,159,24,77,132,131,33,218, - 105,183,19,93,19,231,86,45,160,203,245,127,123,128,163,143,196,140,199,130, - 254,104,68,34,135,248,190,71,144,100,134,147,50,23,87,162,196,217,142,167, - 92,193,21,81,108,207,117,205,199,15,210,247,38,141,119,231,154,59,24,157, - 56,206,242,234,131,192,137,180,135,33,108,158,219,197,79,191,233,229,12,125, - 61,243,45,82,22,94,87,80,11,245,227,217,78,37,25,50,83,201,191,196, - 123,154,13,255,21,255,22,201,109,61,50,179,226,213,252,150,33,123,46,187, - 159,189,190,184,205,108,127,197,125,61,214,122,190,226,243,197,227,126,34,235, - 1,139,23,21,174,235,18,71,43,188,240,133,46,175,122,249,236,220,50,151, - 40,172,67,94,50,160,113,223,67,123,233,116,38,134,161,177,55,245,178,60, - 84,89,230,226,74,148,56,123,241,180,33,184,217,19,209,119,238,137,216,208, - 214,170,44,73,70,108,57,63,98,181,247,8,2,61,78,69,55,84,222,204, - 142,157,151,211,156,175,16,120,29,173,222,130,132,154,219,36,114,182,96,85, - 42,152,214,228,132,89,236,84,2,79,238,84,128,89,5,116,42,37,151,41, - 176,140,168,242,99,157,33,181,226,178,217,229,69,146,59,157,154,123,52,99, - 207,122,10,47,123,44,229,232,113,133,66,103,145,229,199,18,53,49,4,53, - 171,6,111,120,243,107,214,172,43,132,147,215,196,121,193,16,8,88,234,68, - 244,7,147,218,200,217,201,226,37,74,148,40,241,148,18,92,150,79,154,197, - 201,101,159,7,238,148,140,199,203,36,201,136,90,53,98,67,205,72,205,37, - 199,11,107,182,121,249,21,207,102,203,54,159,138,105,19,37,99,76,123,136, - 82,110,158,123,179,45,3,199,113,166,66,147,153,107,18,158,186,254,146,167, - 34,138,156,188,100,239,180,183,89,178,203,72,46,138,30,219,251,201,200,240, - 84,183,89,8,225,76,189,246,241,194,243,180,228,114,28,155,48,140,49,173, - 26,97,24,242,175,95,103,179,97,67,193,5,43,28,148,114,169,216,197,209, - 133,30,208,229,225,7,255,41,87,238,158,175,243,118,69,162,43,187,155,148, - 40,113,118,227,41,37,56,33,156,60,236,149,17,141,239,135,116,150,23,232, - 245,235,120,225,24,195,168,83,171,109,226,240,161,16,47,28,65,26,154,204, - 240,146,23,191,132,110,111,21,163,34,9,124,73,213,210,111,201,178,78,61, - 203,181,216,99,242,201,198,122,121,181,217,199,235,169,183,12,50,88,157,186, - 157,14,50,30,83,169,68,235,154,83,214,187,95,220,239,169,238,175,247,218, - 34,217,253,176,200,204,37,190,31,226,56,118,222,150,173,217,48,216,181,125, - 79,193,104,82,5,225,164,93,78,178,222,148,58,212,188,120,232,16,129,215, - 33,142,117,193,183,140,98,130,212,124,147,205,140,43,81,162,196,217,139,167, - 108,162,183,54,17,184,249,188,183,40,138,80,73,23,219,222,200,231,191,180, - 5,169,30,64,169,54,74,141,152,159,223,66,167,243,45,4,7,33,61,241, - 41,213,228,249,23,234,81,56,85,199,68,134,13,106,21,65,16,15,48,171, - 154,184,178,220,219,169,92,147,79,20,138,106,108,61,117,19,71,154,152,76, - 171,150,155,39,178,101,69,88,241,42,200,222,52,145,197,61,72,82,82,55, - 230,144,113,47,93,185,141,89,213,86,123,11,136,45,125,95,198,99,76,171, - 150,31,139,16,78,78,72,217,177,21,67,162,143,149,216,178,237,60,81,46, - 203,108,128,109,165,18,33,101,132,16,14,245,122,157,147,203,62,63,245,83, - 1,119,223,219,70,41,23,197,131,105,93,220,121,100,206,89,168,2,1,223, - 250,231,144,119,141,183,51,174,219,56,242,17,148,147,16,7,231,18,155,146, - 192,138,192,143,210,92,235,51,115,234,119,137,18,37,78,143,167,84,193,21, - 173,242,153,154,10,195,152,91,111,57,52,181,94,189,225,49,28,5,20,107, - 223,0,46,122,78,154,127,243,37,66,120,132,169,107,174,89,155,156,204,100, - 82,203,239,23,67,147,79,20,214,171,85,131,105,247,99,113,89,182,238,44, - 50,114,203,17,247,166,201,13,244,253,194,99,25,172,18,167,74,101,54,47, - 23,69,21,162,168,178,38,236,88,52,175,172,247,186,98,200,243,84,132,247, - 68,224,84,37,25,27,55,216,252,228,207,94,149,63,22,84,53,65,11,7, - 129,131,91,109,160,85,156,71,127,120,63,7,14,28,70,36,250,115,139,252, - 83,215,189,149,102,147,18,37,206,62,60,45,76,38,81,20,229,202,96,28, - 43,246,221,113,136,36,209,161,38,195,208,161,171,209,240,72,190,190,194,199, - 173,110,226,188,103,237,98,251,185,22,81,24,228,237,184,0,76,75,155,75, - 28,199,161,94,83,107,140,37,79,212,213,252,172,189,127,61,82,59,157,3, - 114,246,249,56,148,90,189,101,196,151,82,63,188,0,0,32,0,73,68,65, - 84,150,116,145,126,7,149,244,167,111,241,97,136,123,140,194,4,161,122,196, - 158,126,253,40,72,242,125,24,162,135,148,81,158,147,155,221,111,182,239,226, - 49,204,62,158,125,93,150,51,125,34,203,5,138,10,83,255,14,12,46,121, - 94,149,221,91,55,231,207,43,229,226,58,122,110,156,23,52,242,215,122,193, - 144,71,142,196,200,244,125,247,131,1,72,221,116,123,118,94,92,217,126,173, - 68,137,179,15,79,89,136,18,38,78,186,34,225,116,187,99,6,97,136,16, - 38,74,57,108,104,91,248,94,7,63,148,76,43,184,121,94,112,201,78,188, - 97,159,138,93,197,174,25,132,3,137,91,213,6,5,219,154,62,161,9,219, - 124,66,75,3,178,66,108,96,13,97,173,135,83,45,215,27,208,10,68,168, - 137,106,83,73,31,21,172,34,0,21,128,74,58,8,67,151,77,136,234,6, - 72,186,212,13,24,133,77,234,118,143,193,176,70,187,209,165,23,204,81,79, - 67,180,21,43,11,67,174,115,28,69,181,56,11,179,61,181,110,108,109,200, - 67,159,89,184,50,251,12,126,216,144,101,177,6,178,120,223,247,67,42,149, - 136,75,94,188,155,67,159,191,35,159,6,225,249,86,218,209,36,203,255,233, - 229,157,227,135,128,45,24,102,19,32,239,79,153,245,25,205,160,27,48,139, - 114,144,103,137,18,103,17,158,50,130,203,114,48,69,68,113,141,238,138,130, - 228,60,224,4,66,248,8,43,98,121,117,72,94,220,157,162,85,211,83,5, - 162,100,70,149,88,22,50,142,192,170,166,115,222,158,220,19,218,186,228,118, - 58,242,0,77,32,51,235,20,149,155,74,250,72,177,132,72,6,249,243,225, - 120,9,59,21,169,137,136,49,19,61,124,166,110,0,104,66,26,12,125,112, - 181,146,203,72,238,84,199,22,135,82,19,234,186,88,197,172,157,63,245,218, - 34,201,193,19,83,11,151,17,155,148,73,78,116,149,74,132,140,199,156,191, - 199,212,23,16,98,30,178,73,223,162,141,109,53,241,163,46,160,143,125,181, - 127,76,111,75,14,114,146,147,81,12,78,54,101,0,234,245,140,232,202,194, - 239,18,37,206,38,60,165,10,46,67,118,162,171,215,235,220,117,111,255,20, - 107,101,149,188,250,100,119,238,142,221,24,28,34,146,53,106,149,57,226,40, - 194,180,199,168,164,141,101,203,180,176,91,173,233,55,249,68,161,104,212,88, - 143,216,114,163,72,193,20,66,220,211,127,89,197,172,110,88,215,76,146,43, - 55,251,0,176,25,210,9,228,241,82,2,231,44,97,187,54,208,68,138,165, - 156,228,70,97,19,120,4,97,157,139,225,29,167,217,112,232,5,115,249,166, - 115,178,75,143,79,166,202,48,63,182,130,137,37,59,86,57,62,152,155,88, - 50,69,7,224,251,96,154,50,119,161,102,195,76,127,24,132,161,196,182,11, - 13,152,13,147,36,113,176,42,14,151,92,174,115,111,25,37,185,118,13,63, - 236,224,69,86,58,85,78,255,30,14,47,6,140,134,117,132,240,104,181,26, - 132,177,4,226,169,253,72,25,97,154,246,15,117,140,37,74,148,56,115,241, - 180,136,215,100,243,187,146,36,97,184,124,128,213,94,140,82,197,186,171,19, - 107,94,115,254,238,243,217,112,238,36,239,86,241,79,228,121,56,219,50,16, - 149,245,13,7,79,154,155,174,64,30,185,26,43,228,210,8,83,227,76,186, - 124,13,185,165,80,217,114,175,2,142,158,148,16,122,33,238,61,251,53,201, - 137,57,68,114,64,239,75,44,209,237,6,212,141,137,210,3,56,209,155,132, - 13,147,200,202,13,44,121,142,47,219,103,210,69,197,135,243,220,222,236,177, - 230,38,150,180,238,46,127,171,105,94,43,223,71,34,127,168,198,198,246,140, - 233,39,138,34,164,76,144,50,225,5,207,55,168,218,9,164,147,5,188,176, - 168,212,179,80,181,199,35,71,14,49,232,68,121,107,54,153,230,222,214,31, - 163,83,54,95,46,81,226,108,194,211,128,224,166,13,0,119,223,126,104,205, - 26,227,145,77,62,247,13,159,170,35,104,183,207,203,199,226,68,201,152,161, - 152,203,167,6,100,200,198,225,60,209,234,237,49,97,198,241,152,19,200,44, - 10,42,74,37,90,189,38,78,12,116,193,27,229,171,141,173,133,116,67,93, - 70,133,14,30,0,221,85,125,1,48,236,77,250,85,249,67,77,122,70,37, - 29,10,90,172,11,43,168,69,208,164,42,197,210,132,232,128,81,152,76,76, - 44,161,100,48,244,25,5,9,161,212,251,158,37,167,31,28,2,195,208,97, - 72,223,15,1,125,241,145,221,118,158,155,5,23,116,88,218,117,226,194,116, - 246,73,45,220,82,39,194,96,242,155,9,131,206,227,60,174,18,37,74,60, - 83,240,148,133,40,179,100,127,86,7,23,6,39,17,198,28,43,253,221,36, - 201,50,66,248,232,147,91,13,169,178,147,86,23,129,67,232,183,169,183,30, - 193,113,54,82,241,199,68,198,121,36,105,1,120,187,153,158,120,141,205,88, - 150,190,98,183,109,109,96,24,141,70,152,166,129,82,126,94,88,124,42,172, - 103,160,40,26,75,50,172,169,93,155,201,163,1,152,234,156,169,144,162,74, - 250,136,164,53,181,29,233,119,16,170,167,205,36,99,128,57,148,187,31,198, - 93,226,165,173,212,226,243,232,183,124,192,167,222,108,192,120,64,207,171,209, - 218,184,200,176,183,19,175,23,82,111,175,2,231,82,51,83,98,76,9,50, - 54,181,250,17,170,55,81,103,126,7,85,93,65,140,7,8,99,30,49,30, - 32,83,65,108,38,80,55,22,211,144,229,36,60,217,54,187,105,189,221,24, - 207,211,197,218,82,86,48,77,0,149,230,229,180,145,35,251,94,179,207,13, - 152,50,168,132,161,14,115,26,134,238,102,162,215,75,210,215,74,76,71,176, - 117,195,22,22,142,199,32,218,120,126,128,83,237,225,7,115,83,153,52,167, - 186,202,137,142,205,54,209,98,232,61,194,230,122,27,11,15,25,89,185,31, - 197,247,253,66,30,174,68,137,18,103,11,158,50,5,151,245,54,4,125,2, - 52,173,26,166,105,210,239,8,132,232,165,33,202,42,209,88,165,205,118,39, - 112,170,45,236,234,54,134,227,1,67,49,135,47,59,88,213,17,243,13,131, - 213,94,15,171,102,16,123,94,110,21,247,60,31,41,71,212,235,117,12,195, - 124,84,114,123,76,199,159,213,146,205,26,74,10,202,40,67,22,118,204,84, - 210,172,90,90,3,213,101,182,99,11,64,195,232,160,220,21,77,92,105,110, - 174,191,50,109,246,24,246,188,41,37,151,33,119,104,22,31,23,48,94,56, - 142,24,79,66,157,185,226,140,123,140,11,170,104,20,36,140,130,132,138,53, - 38,235,138,53,9,253,77,84,114,209,173,152,57,36,245,224,83,125,95,119, - 47,49,211,215,143,210,11,138,140,24,245,242,185,141,167,34,165,137,147,210, - 15,244,103,216,112,154,84,45,131,174,23,17,51,109,96,170,26,149,178,109, - 87,137,18,103,33,158,58,130,43,140,125,49,12,19,33,92,194,48,166,219, - 15,114,215,28,64,84,137,169,216,35,244,73,173,154,47,111,213,201,67,148, - 141,84,181,69,126,66,179,81,39,26,244,104,214,199,216,174,192,113,28,108, - 219,38,138,42,63,208,180,235,181,234,109,242,186,217,122,178,162,122,203,76, - 34,218,5,121,128,104,121,63,74,30,212,74,105,60,200,85,93,18,74,146, - 80,34,253,14,210,239,208,27,234,229,25,113,21,225,222,179,95,31,211,137, - 66,104,82,204,77,173,99,169,195,120,189,16,63,58,73,189,174,143,167,72, - 118,203,39,211,146,134,116,127,128,38,52,213,69,37,19,2,19,227,1,42, - 88,37,9,37,221,110,48,181,143,193,112,242,189,100,53,119,186,19,137,74, - 191,75,53,69,108,217,231,93,188,21,151,103,235,102,191,5,61,227,78,43, - 193,102,213,64,25,155,40,126,231,26,25,185,121,56,213,10,89,168,178,215, - 235,49,30,107,9,26,206,12,189,13,146,114,8,106,137,18,103,35,158,50, - 130,51,173,218,84,79,67,41,37,118,214,80,87,76,194,98,181,60,175,230, - 227,84,91,128,131,31,24,244,71,96,86,13,34,169,243,55,73,226,48,76, - 205,115,149,246,179,168,153,163,60,15,149,25,34,178,81,60,97,112,242,49, - 31,231,228,196,172,214,58,39,179,208,100,193,80,162,130,213,52,204,168,247, - 29,47,37,140,15,249,218,48,162,186,57,209,245,134,75,58,68,152,42,169, - 185,122,149,229,147,147,80,44,0,99,147,164,175,48,151,103,39,16,116,193, - 57,137,171,22,244,49,198,250,111,175,119,130,154,144,120,189,16,21,63,66, - 189,190,74,189,190,202,56,232,176,105,62,200,115,128,89,40,52,39,83,213, - 213,36,170,186,57,225,169,234,138,62,146,213,19,249,246,0,12,111,210,236, - 58,148,195,92,197,69,81,5,41,147,188,99,72,146,36,83,3,71,139,147, - 198,149,242,200,44,251,166,89,199,170,108,152,42,248,214,165,3,197,64,164, - 38,90,97,100,191,11,7,8,82,245,54,81,171,142,147,224,184,46,113,152, - 14,111,21,211,74,182,156,15,87,162,196,217,133,167,140,224,116,29,220,36, - 164,165,146,46,97,24,167,207,109,76,59,152,76,43,8,63,200,174,196,3, - 90,117,72,194,17,21,211,102,52,28,234,209,56,70,131,219,191,237,208,93, - 169,16,154,207,161,213,222,70,160,44,28,199,198,182,77,58,253,19,36,137, - 196,170,108,120,76,199,168,67,168,10,165,188,245,203,2,166,86,158,9,77, - 58,39,167,76,34,26,221,117,21,90,70,56,77,119,137,140,220,148,234,66, - 77,78,171,182,12,53,201,104,48,76,75,6,38,216,216,10,176,212,225,169, - 101,94,47,196,235,133,121,87,148,105,114,211,251,10,189,112,114,124,110,4, - 170,139,225,91,52,29,253,126,221,182,222,79,166,6,67,111,66,20,21,75, - 55,120,6,221,110,45,11,59,26,134,145,79,73,55,12,3,41,71,147,91, - 250,57,38,73,146,26,76,180,225,36,12,37,158,167,187,165,216,182,133,72, - 150,161,216,116,121,10,85,102,127,31,65,16,16,199,49,194,240,137,100,204, - 216,43,71,231,148,40,113,54,227,41,116,81,234,147,100,24,198,105,104,74, - 163,177,121,218,247,178,99,139,194,32,83,54,233,136,149,106,133,254,72,15, - 195,116,93,69,181,90,37,142,34,130,161,193,225,3,251,248,212,39,190,202, - 95,252,217,18,55,222,172,21,68,20,69,196,209,42,173,122,3,195,48,233, - 142,167,235,164,214,67,118,76,179,221,74,138,53,111,179,197,217,153,122,67, - 45,160,152,16,141,123,207,254,105,178,115,78,210,118,199,244,87,36,221,81, - 64,119,52,125,162,62,29,44,163,7,99,77,34,163,184,131,101,221,11,76, - 84,28,232,112,101,212,125,152,168,251,48,155,218,39,216,212,62,145,135,37, - 39,232,206,252,157,121,118,20,228,234,50,234,62,60,245,92,34,39,164,27, - 197,181,92,197,133,161,68,74,57,213,247,177,216,218,203,52,235,186,193,182, - 106,35,101,194,245,95,24,242,246,127,123,3,31,254,240,247,56,185,236,227, - 56,54,174,59,105,232,60,27,162,172,213,140,153,177,57,115,184,213,29,0, - 108,216,124,41,173,214,86,188,160,135,195,233,191,223,50,76,89,162,196,217, - 129,167,176,208,91,160,148,135,109,59,128,69,111,96,114,253,87,124,78,28, - 172,144,36,154,68,94,112,233,78,158,123,241,38,190,123,207,45,100,101,2, - 78,117,114,200,102,213,160,63,140,104,212,28,162,100,204,185,59,246,240,147, - 63,123,21,119,221,155,240,43,191,248,69,92,247,36,87,191,97,39,87,191, - 249,74,126,226,95,205,97,154,21,124,63,100,67,163,154,135,29,139,185,182, - 162,115,82,19,218,58,189,27,11,245,110,179,118,123,96,141,66,115,131,239, - 3,6,74,117,17,98,14,77,40,117,80,93,218,110,214,161,228,28,194,241, - 210,100,19,217,54,188,1,198,209,46,176,1,115,89,210,63,255,56,109,54, - 129,232,82,51,193,75,64,169,54,201,232,40,70,125,59,73,188,128,97,157, - 55,181,255,44,143,214,116,214,9,77,2,48,71,188,228,147,5,130,71,131, - 33,245,102,131,86,221,164,187,18,96,164,31,247,74,87,226,20,60,31,161, - 167,176,93,129,10,37,194,54,169,84,38,125,47,179,2,240,236,190,254,171, - 141,61,43,171,33,15,236,11,248,179,15,221,194,29,223,61,201,161,197,135, - 216,113,254,5,250,51,77,47,42,146,68,231,99,181,130,155,96,211,134,54, - 176,135,229,149,125,232,9,223,115,120,193,28,223,220,123,0,211,218,201,238, - 93,130,115,119,110,100,24,199,52,41,81,162,196,217,142,167,124,30,28,8, - 238,218,55,230,253,191,118,148,223,250,213,47,115,248,208,60,134,81,199,48, - 234,60,239,226,77,92,246,226,121,138,42,195,15,204,220,57,7,208,106,84, - 48,12,159,170,101,208,235,118,184,239,206,7,120,193,243,13,94,244,146,151, - 209,233,56,124,252,218,123,120,239,187,63,192,111,252,198,3,248,126,136,105, - 138,52,7,167,21,100,20,69,133,169,213,201,41,155,9,159,182,151,36,76, - 212,27,5,130,114,235,240,253,201,71,172,84,151,81,172,247,59,138,59,57, - 169,117,150,167,73,49,233,23,114,69,157,245,213,134,87,88,108,183,39,234, - 44,137,23,166,212,220,212,49,38,235,213,136,173,85,112,163,193,112,141,59, - 179,38,244,227,97,207,155,148,33,0,145,169,85,181,63,51,108,192,52,205, - 156,220,178,30,147,119,222,61,228,250,175,132,252,217,135,110,225,214,219,170, - 28,62,178,13,193,110,189,190,35,166,26,59,143,227,181,249,50,199,157,75, - 73,206,69,19,220,54,28,123,7,159,253,252,195,252,225,31,124,130,235,62, - 115,11,221,78,112,218,89,128,37,74,148,56,123,240,164,17,92,49,236,40, - 229,136,48,56,89,48,32,72,226,104,133,149,213,136,255,244,235,203,252,252, - 207,28,228,211,159,62,193,106,103,7,145,90,196,20,109,90,110,135,159,123, - 203,38,238,188,163,131,83,177,0,31,219,89,66,247,32,220,170,55,172,250, - 4,82,119,151,175,84,182,33,147,33,31,252,80,194,53,159,24,243,206,95, - 108,83,181,19,20,93,78,172,44,178,239,59,7,56,186,60,66,74,69,20, - 215,210,210,1,205,18,97,168,195,106,89,254,104,22,185,161,100,124,80,119, - 42,25,29,212,245,100,73,151,196,91,72,109,255,58,52,9,90,169,89,70, - 79,135,41,47,76,153,232,251,3,168,73,48,14,131,55,162,110,173,45,60, - 183,221,49,178,215,193,104,9,198,105,120,80,244,55,97,178,140,201,50,117, - 107,27,0,227,214,9,220,244,155,19,66,175,103,89,247,226,170,5,218,110, - 154,223,74,137,174,85,61,70,171,122,108,141,75,83,169,174,46,57,64,135, - 80,143,108,213,199,83,107,174,82,111,54,104,59,71,167,142,109,172,76,252, - 232,36,129,179,129,177,172,51,74,47,50,146,72,147,73,177,145,117,246,185, - 106,53,172,47,40,238,123,48,100,239,45,17,221,37,73,171,41,104,88,33, - 168,127,70,177,87,191,198,87,36,170,77,162,218,196,209,74,193,69,57,9, - 223,138,100,153,103,95,116,14,110,245,114,20,231,163,112,240,194,17,2,135, - 165,149,6,31,255,244,136,223,254,79,183,115,235,215,247,16,198,9,177,223, - 33,145,67,124,223,71,133,186,207,101,28,173,172,251,29,151,40,81,226,153, - 135,39,141,224,178,144,148,148,35,132,112,176,171,155,167,122,14,126,241,43, - 85,126,241,61,15,240,169,107,191,195,194,161,180,227,136,104,99,138,54,6, - 45,54,111,217,201,222,91,124,30,220,119,61,126,20,3,62,161,175,243,49, - 110,26,166,76,34,51,31,149,98,217,146,56,138,120,232,251,7,249,218,205, - 11,0,236,222,117,30,142,109,146,133,55,99,207,155,170,135,210,237,155,84, - 225,241,244,248,27,88,71,185,21,102,180,169,164,79,226,196,218,49,153,182, - 213,82,170,59,81,112,99,115,74,193,101,185,179,76,201,69,21,125,17,80, - 175,105,147,71,232,213,48,90,211,196,103,178,140,100,211,212,178,22,54,212, - 36,174,153,186,34,197,164,166,45,28,47,229,36,7,228,57,190,226,178,245, - 84,219,142,227,138,177,212,203,71,131,33,61,127,59,48,201,237,101,10,174, - 136,162,217,100,182,206,44,51,12,1,121,131,230,207,127,238,48,119,222,209, - 225,229,111,184,146,246,230,109,84,237,136,217,25,127,149,74,196,40,72,8, - 134,30,190,55,125,156,202,216,196,249,23,108,231,121,207,246,48,216,138,193, - 28,2,61,39,14,28,20,93,238,216,247,48,191,251,91,255,23,31,254,147, - 131,140,226,231,146,40,151,90,211,34,72,34,86,59,38,81,92,163,108,186, - 92,162,196,217,129,39,141,224,146,100,98,25,207,66,84,0,171,195,128,143, - 127,236,97,126,255,247,30,224,186,235,151,89,89,153,91,251,90,250,108,221, - 57,199,151,191,112,23,223,217,119,4,232,160,175,228,179,19,153,86,15,145, - 12,17,169,21,60,14,77,170,213,121,60,223,226,238,125,139,124,241,51,55, - 179,188,218,195,15,143,0,105,43,171,113,139,177,103,226,251,62,161,28,50, - 26,13,210,190,138,17,97,24,98,24,225,41,155,40,79,205,105,35,237,4, - 18,172,78,200,205,27,229,206,71,106,41,25,212,36,70,93,19,159,113,116, - 125,229,144,145,92,84,25,17,85,70,120,137,14,63,214,12,133,232,11,226, - 150,38,57,64,147,165,217,163,79,168,205,38,128,42,144,91,182,173,34,201, - 181,221,113,126,95,135,68,215,55,149,0,84,135,10,111,104,82,137,214,22, - 194,119,7,154,136,170,254,42,94,156,224,90,6,182,43,242,86,96,25,178, - 217,107,118,193,12,34,132,195,226,225,132,111,127,231,1,238,188,253,97,186, - 75,146,222,201,99,248,225,10,224,211,95,78,123,107,74,221,253,63,244,20, - 163,112,140,227,206,145,153,76,148,114,120,228,216,10,59,119,85,120,206,143, - 238,4,206,67,49,135,96,242,251,17,204,97,48,135,31,74,62,118,237,55, - 248,165,119,252,53,119,220,217,36,244,20,70,37,198,53,67,92,215,37,12, - 229,19,62,215,174,68,137,18,79,63,60,105,4,23,134,49,166,105,230,99, - 113,28,199,38,73,18,254,225,186,128,63,250,63,15,112,239,189,13,42,230, - 118,76,209,70,170,94,254,55,146,71,57,111,183,100,208,57,198,161,195,11, - 250,181,21,139,98,189,83,86,46,80,117,76,170,213,42,253,225,68,61,180, - 107,46,80,229,107,223,140,24,13,59,232,19,186,71,18,45,208,168,245,49, - 196,136,48,232,228,234,35,11,95,169,80,78,229,128,78,231,150,148,126,7, - 228,130,14,75,206,144,155,101,244,52,249,152,19,226,49,194,19,121,46,173, - 213,212,39,85,49,67,76,241,64,224,140,186,184,6,185,50,179,84,7,171, - 224,95,201,200,178,133,77,223,60,137,105,246,97,238,56,74,244,16,162,71, - 205,236,97,134,143,16,85,70,132,227,37,92,181,64,56,94,210,196,150,170, - 202,81,172,244,177,10,253,184,151,166,229,204,229,73,73,66,84,25,145,140, - 38,33,202,149,254,196,201,232,71,147,26,194,208,83,36,145,149,247,167,204, - 84,92,24,102,29,106,38,161,202,198,92,130,231,91,44,158,244,185,246,191, - 223,70,63,88,68,95,184,248,204,111,78,24,248,94,126,241,177,6,202,199, - 48,234,44,47,143,185,243,142,14,175,121,245,143,243,130,139,245,108,60,167, - 186,25,149,147,156,143,194,71,224,160,240,185,115,223,50,255,245,63,127,131, - 111,125,187,134,63,28,96,215,2,198,189,236,88,75,39,101,137,18,207,116, - 60,105,4,151,213,70,101,136,162,136,143,127,122,200,135,255,232,1,246,31, - 216,145,47,207,200,13,32,73,70,108,222,28,177,229,252,136,35,143,28,194, - 11,116,177,180,48,244,44,56,237,160,156,174,135,138,148,69,171,161,67,159, - 131,208,32,140,5,74,57,196,99,29,234,115,171,19,133,49,28,183,242,19, - 104,150,155,57,45,228,116,215,255,188,20,160,186,146,22,69,47,76,200,77, - 116,115,85,5,96,182,99,44,163,199,48,24,33,250,155,24,214,60,42,253, - 133,169,205,23,73,206,106,42,130,198,116,120,178,104,118,204,84,107,134,22, - 54,162,46,117,184,18,112,13,16,131,30,158,57,162,102,246,114,69,152,221, - 70,113,135,168,162,159,155,218,206,201,69,253,86,55,153,136,173,9,110,67, - 147,83,22,54,5,48,146,46,118,67,171,58,167,162,39,109,123,113,50,165, - 224,178,225,170,48,105,196,92,236,106,50,236,26,184,118,13,229,85,120,112, - 255,128,149,213,67,20,195,147,177,231,17,6,43,248,190,79,28,203,60,199, - 55,141,42,119,222,254,48,27,155,240,202,31,127,49,2,31,47,24,32,168, - 166,195,80,117,51,110,197,65,92,187,142,194,231,187,247,220,194,53,127,245, - 49,142,157,220,202,202,74,15,25,30,36,246,124,164,84,121,238,181,68,137, - 18,207,76,60,105,4,55,233,74,161,119,113,195,151,60,62,252,71,15,112, - 239,189,218,20,34,85,15,89,232,135,40,85,143,23,92,218,226,170,171,158, - 195,134,154,145,170,175,227,192,49,188,64,231,224,252,96,8,4,184,213,141, - 0,4,190,36,9,103,139,169,83,24,53,188,96,144,190,22,6,99,168,90, - 11,122,140,138,47,241,226,132,64,142,240,125,159,81,56,206,221,128,86,188, - 58,53,94,6,88,219,165,100,148,146,66,175,51,81,110,245,84,17,152,90, - 189,117,122,211,10,161,49,118,81,93,136,71,6,94,50,81,105,206,168,139, - 51,234,146,140,214,158,208,123,163,112,205,50,204,62,166,61,162,207,228,185, - 214,220,106,174,200,56,124,52,253,252,123,83,4,10,76,147,155,154,3,79, - 95,64,152,203,18,115,89,162,142,175,255,115,152,159,115,137,250,19,69,87, - 245,53,233,251,195,65,174,132,117,110,75,35,12,37,74,121,5,119,234,72, - 43,184,244,243,20,85,55,205,141,106,116,78,234,253,142,210,139,146,209,88, - 160,162,236,88,2,16,14,73,50,66,41,135,7,191,255,16,123,111,62,196, - 171,175,116,120,193,197,47,204,183,33,168,82,177,27,136,148,52,245,4,248, - 99,192,65,237,178,252,192,141,28,59,185,149,177,172,19,153,94,30,154,150, - 82,17,69,209,76,237,94,169,238,74,148,120,38,224,73,44,19,16,128,62, - 121,252,227,245,125,62,244,199,7,167,200,13,180,169,100,67,219,162,221,26, - 113,233,197,38,111,186,122,43,151,189,120,158,195,135,66,252,224,36,58,188, - 120,28,125,165,175,195,78,0,94,160,243,59,85,87,135,169,130,56,65,24, - 250,57,219,82,8,225,83,169,9,4,85,116,222,110,142,221,187,201,157,117, - 125,47,34,30,39,168,200,32,9,134,196,177,196,31,14,242,254,138,249,59, - 200,26,20,167,93,64,18,39,46,200,170,46,198,137,33,98,80,32,141,2, - 129,184,155,6,96,246,104,84,181,242,177,250,154,176,172,122,146,59,32,129, - 92,181,153,141,212,248,32,166,115,100,227,180,221,152,55,20,83,37,3,243, - 246,90,229,97,118,214,150,1,100,164,54,75,118,217,126,70,241,177,53,175, - 201,16,143,181,42,235,116,11,225,225,104,186,205,153,237,78,84,103,177,171, - 137,16,206,148,89,103,190,101,1,65,78,114,26,250,34,40,112,37,72,77, - 240,190,239,77,238,123,93,138,138,93,79,152,152,231,134,235,97,255,126,201, - 115,47,189,8,183,58,169,120,139,194,97,170,228,182,21,8,116,30,129,207, - 223,93,119,19,255,199,239,253,53,199,78,110,229,228,9,137,239,251,248,190, - 191,102,182,29,76,43,207,18,37,74,156,185,120,210,254,147,117,191,65,216, - 119,95,192,199,62,122,128,91,255,73,159,44,229,76,23,123,128,139,159,111, - 243,182,119,93,200,165,151,207,113,231,29,29,30,124,240,46,52,169,121,20, - 195,88,66,12,152,117,221,1,212,45,125,178,174,89,125,72,198,64,64,52, - 156,86,118,135,14,77,134,97,2,68,50,70,70,90,221,101,61,11,13,239, - 56,131,161,207,96,232,79,207,79,203,246,159,119,219,47,56,37,79,1,55, - 112,80,35,19,145,172,78,76,34,104,5,87,36,177,234,80,135,38,171,67, - 69,117,184,214,221,87,107,232,19,184,219,80,24,116,49,87,0,55,61,233, - 155,169,234,147,147,222,157,98,81,191,199,204,124,226,37,154,220,102,183,157, - 41,206,108,253,169,247,57,75,134,167,65,166,224,84,40,137,226,90,94,236, - 61,59,86,104,241,112,2,202,199,181,77,42,65,152,42,44,141,170,103,210, - 27,164,106,47,138,137,100,92,8,31,23,154,111,171,30,136,54,251,23,134, - 220,182,247,107,108,62,167,193,214,13,91,80,4,105,67,110,48,216,138,96, - 14,63,60,130,98,30,152,67,225,32,56,198,231,62,127,15,127,254,39,55, - 97,185,110,222,194,43,35,57,200,106,34,147,50,108,89,162,196,51,4,63, - 52,193,233,38,196,114,170,222,77,47,215,211,157,101,60,102,101,53,226,131, - 127,188,196,231,191,160,9,164,152,111,51,69,155,243,118,75,118,158,123,146, - 159,254,89,197,79,255,172,126,253,131,251,174,199,11,6,40,142,51,113,252, - 5,64,21,212,230,244,177,118,69,6,94,7,165,92,194,68,91,218,189,48, - 59,137,87,193,168,165,235,233,198,188,205,26,196,113,76,140,139,242,71,250, - 38,7,24,113,135,216,151,212,204,17,174,57,206,111,69,245,166,146,62,200, - 133,180,20,32,61,38,209,197,28,159,196,236,116,176,140,30,166,59,9,225, - 69,155,86,80,34,192,88,77,24,68,169,11,144,62,98,49,66,244,5,86, - 43,45,8,23,61,252,102,63,39,57,191,57,9,83,90,173,14,205,37,123, - 242,90,38,243,227,252,74,15,81,133,190,116,176,154,35,176,23,177,234,9, - 189,81,72,179,18,32,6,61,154,149,30,174,153,154,86,12,166,203,15,68, - 151,190,121,18,212,28,181,248,60,0,6,91,23,243,167,151,188,113,238,200, - 92,15,153,138,243,226,4,39,253,46,34,211,163,98,141,49,68,143,74,37, - 34,73,244,4,135,76,13,53,230,18,16,14,94,56,198,170,169,212,253,216, - 165,88,231,54,26,47,19,201,152,48,78,10,19,1,170,32,28,173,222,132, - 131,82,14,74,29,229,222,251,107,156,92,26,50,183,177,130,192,39,12,45, - 200,243,112,93,96,91,26,174,236,34,232,164,207,117,184,225,75,123,249,135, - 191,131,112,212,99,101,53,32,81,117,84,40,25,122,171,169,147,214,192,48, - 194,31,104,242,68,137,18,37,158,158,248,161,9,46,59,113,9,225,228,87, - 188,82,142,80,202,199,48,12,172,202,70,174,249,164,199,87,190,168,237,241, - 25,177,101,10,238,188,221,146,173,59,231,120,229,143,191,152,43,94,245,44, - 154,142,203,222,155,15,177,239,65,63,207,163,60,246,99,209,235,55,107,211, - 243,195,42,118,35,189,55,221,85,222,79,59,148,69,126,194,48,50,49,226, - 78,222,72,120,28,116,214,144,91,54,226,38,67,86,32,13,16,7,27,49, - 55,76,30,155,237,24,39,20,224,234,147,99,99,172,93,164,130,86,126,63, - 67,205,208,132,156,133,41,179,199,57,78,209,197,36,195,84,152,50,13,69, - 102,132,42,165,38,196,172,96,60,239,124,146,170,199,22,118,30,94,149,155, - 204,156,232,198,131,13,156,227,78,242,105,0,172,211,1,165,234,175,178,177, - 58,81,190,48,25,161,147,57,81,139,70,163,97,55,251,169,205,54,77,78, - 15,43,253,14,149,63,33,214,162,65,104,182,177,242,242,106,143,225,160,143, - 50,54,177,97,131,254,109,41,38,211,41,180,217,196,73,29,184,19,156,88, - 89,228,218,143,253,62,199,87,98,230,231,55,144,200,46,189,241,0,215,214, - 225,110,223,15,115,231,111,137,18,37,206,108,60,46,5,7,164,131,44,215, - 118,0,185,107,223,152,127,248,194,65,86,186,39,242,101,25,201,109,104,91, - 156,187,61,225,178,23,86,121,251,59,107,188,224,146,26,255,116,91,200,173, - 55,45,174,25,110,186,22,206,154,37,73,162,151,13,198,81,170,220,32,140, - 5,81,152,53,5,214,39,172,68,14,80,254,40,111,198,91,113,166,223,126, - 62,216,179,64,110,73,40,243,185,105,120,35,77,110,99,19,171,158,160,210, - 147,182,236,89,224,4,152,246,228,228,44,84,106,178,41,212,157,25,116,243, - 60,217,56,17,140,19,65,77,180,73,188,33,137,183,206,212,128,117,160,250, - 73,74,160,10,81,5,37,2,204,186,126,63,173,208,162,53,214,68,96,181, - 58,122,251,134,2,209,213,33,75,209,101,156,172,237,160,98,46,75,198,214, - 130,62,110,209,67,14,245,58,65,161,200,221,72,166,67,178,126,116,114,106, - 176,106,113,140,14,76,70,211,104,37,52,153,122,224,218,235,119,139,1,29, - 66,142,44,151,74,172,183,155,229,90,215,35,197,149,149,144,195,135,180,209, - 166,81,175,226,86,155,216,246,218,38,203,94,148,109,195,207,201,238,187,251, - 142,240,23,127,246,48,3,223,99,121,121,25,203,50,25,141,6,12,135,3, - 12,209,75,27,128,203,50,23,87,162,196,25,142,199,165,224,12,195,44,12, - 177,212,117,100,66,184,156,92,246,249,224,31,47,241,221,239,28,65,136,141, - 121,141,27,104,114,155,159,119,248,145,23,25,188,250,74,135,75,158,87,229, - 225,253,199,185,238,51,183,240,192,247,143,232,109,113,156,137,234,154,237,180, - 191,86,221,173,167,224,108,75,21,20,220,52,250,193,0,35,238,34,135,171, - 88,28,199,136,245,173,110,12,168,179,56,49,149,132,82,171,185,66,123,43, - 198,230,84,14,205,28,79,76,23,162,10,34,41,180,150,82,211,202,71,244, - 13,237,140,148,109,106,134,162,102,40,198,170,135,168,73,68,109,146,147,50, - 211,220,154,177,78,81,182,104,25,248,182,66,249,33,74,204,124,54,153,121, - 39,37,209,172,230,174,72,106,179,42,209,8,245,5,72,81,93,102,134,23, - 215,52,24,246,71,180,91,33,243,115,46,221,222,81,90,28,164,197,65,0, - 234,245,213,124,78,28,64,219,236,230,245,131,134,232,229,74,78,229,228,168, - 137,42,246,235,51,83,1,210,139,19,38,121,210,56,52,103,20,220,12,201, - 9,93,248,45,146,101,140,248,28,252,32,36,10,235,105,190,205,41,116,57, - 241,209,23,56,14,126,100,229,36,247,177,107,63,207,63,126,230,27,84,236, - 13,36,114,72,111,180,130,101,85,210,73,7,147,150,114,37,74,148,56,115, - 241,132,93,162,42,229,99,90,53,194,48,206,67,147,94,127,243,20,185,1, - 204,207,59,92,254,99,117,126,228,82,151,151,189,212,198,52,77,190,244,197, - 37,246,222,12,65,104,0,189,66,136,242,7,11,85,198,113,156,154,76,102, - 225,49,24,103,91,180,152,51,79,113,226,202,198,222,36,125,132,234,77,186, - 239,147,206,78,171,73,93,239,86,79,80,190,86,92,170,107,160,70,105,11, - 174,25,194,81,29,77,106,0,113,11,140,48,166,21,140,192,236,229,121,184, - 89,194,201,200,237,116,112,141,245,195,124,116,102,66,156,102,15,171,158,228, - 251,24,39,2,211,236,79,237,195,122,148,221,205,109,88,208,155,238,122,236, - 106,79,222,95,139,131,249,172,57,21,63,130,107,142,137,61,77,110,197,246, - 102,197,161,167,0,126,52,71,165,38,136,194,105,181,229,218,19,18,246,177, - 176,108,89,80,112,1,179,23,58,174,93,99,52,236,231,235,100,101,41,153, - 138,203,28,183,211,97,74,63,109,251,6,224,241,71,127,120,51,195,113,139, - 227,39,39,191,153,193,48,33,148,195,180,141,91,153,131,43,81,226,76,198, - 227,14,81,22,33,132,203,125,15,134,124,242,227,223,103,181,23,231,33,201, - 12,237,214,136,122,195,227,178,23,207,115,233,101,91,73,100,151,189,183,61, - 200,205,55,193,137,85,155,170,157,164,234,237,116,88,27,162,204,48,142,91, - 51,33,202,181,33,43,135,152,174,52,17,116,168,54,194,188,199,162,165,14, - 231,237,183,178,122,183,226,104,25,165,116,33,183,85,79,242,124,151,72,199, - 250,88,81,71,231,220,220,36,39,57,37,166,201,57,35,146,65,102,28,25, - 77,66,117,153,154,43,162,248,252,122,240,237,201,250,66,77,19,158,42,230, - 238,204,30,227,68,208,172,244,116,189,28,32,234,211,164,99,178,140,213,215, - 106,52,43,244,22,162,151,79,41,24,246,71,144,116,242,6,206,73,188,64, - 211,25,99,169,195,88,234,48,117,22,25,7,29,198,65,135,216,91,101,48, - 244,243,122,194,92,189,201,131,64,128,83,233,50,94,199,165,56,49,8,77, - 48,81,112,235,19,186,109,104,135,233,48,214,191,29,33,156,212,108,50,243, - 89,69,49,89,152,58,131,83,137,57,177,178,200,7,255,252,43,212,171,54, - 241,56,97,212,143,73,100,151,138,116,167,106,228,74,148,40,113,102,226,113, - 43,184,162,217,36,12,99,174,249,196,152,35,139,34,87,110,82,245,72,146, - 81,30,154,220,181,219,230,130,11,76,118,158,107,241,200,241,6,215,255,93, - 204,67,15,44,225,5,171,248,193,201,31,74,189,37,137,131,74,28,68,210, - 203,21,156,14,81,158,126,108,74,56,28,209,29,248,107,166,96,231,196,150, - 78,7,152,42,9,40,212,186,169,94,161,143,166,247,216,62,202,102,69,19, - 160,168,203,60,116,56,78,58,83,97,196,140,128,68,223,88,211,193,100,22, - 25,185,153,221,201,122,170,107,76,74,8,208,4,42,101,75,151,45,212,101, - 78,158,197,186,185,238,214,52,239,53,156,16,107,60,208,199,36,232,208,110, - 77,23,157,247,134,75,36,241,2,237,86,64,183,27,232,208,46,58,143,89, - 51,142,49,24,250,249,236,60,43,94,165,211,209,185,85,111,157,242,11,152, - 86,112,25,166,21,220,52,201,141,131,10,81,37,102,165,155,126,86,134,190, - 152,202,20,156,109,111,74,155,48,231,91,99,114,113,228,227,71,67,192,225, - 198,207,94,195,253,223,215,46,92,63,152,124,30,179,229,3,37,74,148,56, - 243,240,132,132,40,165,148,40,229,115,223,131,33,183,222,120,7,131,254,182, - 169,176,100,173,170,79,16,231,110,79,120,229,149,187,217,185,203,96,241,145, - 152,111,124,237,97,110,189,105,145,67,135,23,80,28,79,237,221,107,155,47, - 107,156,122,234,181,97,248,8,195,215,57,184,130,130,251,65,49,9,73,66, - 232,233,19,122,222,64,89,172,205,135,25,116,39,78,71,183,240,215,77,240, - 165,32,233,234,176,164,162,159,19,213,108,137,217,56,233,80,51,230,117,62, - 46,155,39,55,50,25,212,61,93,220,157,29,91,168,213,151,234,235,253,184, - 70,21,225,164,106,80,4,116,104,33,122,144,48,199,48,152,182,248,91,173, - 14,86,171,51,33,206,250,90,146,153,59,62,81,56,89,13,157,213,156,168, - 170,81,255,200,154,215,180,54,154,72,177,68,163,189,72,183,27,224,245,244, - 103,54,10,39,10,50,11,87,206,207,143,242,122,182,74,176,78,135,150,71, - 197,218,239,191,18,173,189,128,201,202,5,162,48,206,251,82,174,69,182,236, - 56,75,157,58,215,252,213,199,24,6,59,80,114,64,34,135,28,93,78,195, - 207,161,204,205,50,37,201,149,40,113,230,225,113,151,9,232,251,33,166,89, - 231,154,79,140,185,239,254,75,49,173,125,83,235,214,106,155,152,159,119,216, - 190,171,201,5,23,104,133,112,215,189,9,55,223,4,139,199,70,4,161,145, - 43,55,181,70,185,77,174,220,245,115,126,190,204,170,165,125,37,139,46,202, - 76,193,25,217,73,222,1,92,154,5,231,251,188,169,11,175,69,210,99,83, - 67,151,0,36,241,2,74,30,76,27,19,47,80,89,124,16,217,235,76,26, - 40,183,58,121,222,45,115,75,170,54,136,246,132,248,132,114,114,37,231,26, - 85,196,194,116,216,45,73,21,101,166,182,154,149,30,205,202,68,49,101,247, - 69,93,210,218,87,165,94,40,3,72,108,11,163,175,201,95,9,95,223,252, - 16,175,234,227,219,138,230,221,250,56,12,186,180,198,129,46,8,135,188,165, - 151,26,153,168,145,73,191,171,151,245,9,167,67,153,64,223,142,105,182,86, - 243,112,105,86,240,221,222,208,163,189,161,135,101,171,154,203,73,0,0,32, - 0,73,68,65,84,221,155,223,0,162,229,253,136,241,128,254,138,164,209,94, - 100,190,250,0,117,22,169,27,3,84,252,8,253,193,114,174,226,244,247,183, - 37,253,222,20,89,119,154,12,217,144,82,135,24,211,210,102,161,105,147,201, - 52,132,232,17,165,125,48,85,50,68,37,61,148,242,211,238,53,90,205,77, - 38,13,204,49,27,162,4,7,167,58,6,186,124,243,182,5,22,15,238,39, - 198,101,208,143,169,215,20,113,28,17,36,209,186,157,78,74,148,40,113,102, - 224,113,228,224,166,85,192,157,119,15,249,218,205,11,36,244,25,7,149,53, - 235,215,27,30,155,55,107,98,88,60,156,176,239,246,67,44,30,60,202,104, - 216,65,41,63,119,191,61,58,38,235,196,227,172,223,229,90,23,165,62,137, - 102,152,152,76,78,133,172,45,149,237,78,44,237,89,119,125,204,30,200,246, - 68,1,21,162,101,143,214,244,35,89,39,76,26,87,116,205,85,81,73,101, - 198,15,81,151,83,125,38,243,99,73,149,224,20,220,4,199,84,56,230,218, - 19,112,166,244,244,198,39,219,102,46,100,190,109,172,219,234,107,221,227,95, - 167,71,38,232,1,171,158,63,6,231,36,237,249,67,122,159,213,21,186,221, - 0,146,46,117,67,119,125,145,193,170,206,203,117,214,219,159,254,222,86,250, - 187,181,65,8,24,198,218,73,25,135,179,57,200,181,121,184,89,5,231,84, - 237,153,53,78,23,230,238,226,7,6,224,115,98,101,145,155,190,250,77,198, - 99,145,118,81,241,136,99,253,221,20,67,149,37,74,148,56,179,240,184,67, - 148,217,64,211,187,238,77,88,216,191,140,84,61,12,67,231,91,50,147,73, - 150,123,219,185,91,79,17,56,116,240,0,223,185,251,40,135,143,30,192,79, - 195,85,143,189,184,251,212,235,245,253,137,76,203,166,9,156,10,34,209,204, - 148,245,89,220,184,49,123,102,58,20,153,79,8,72,115,111,166,61,66,5, - 169,177,100,6,69,99,137,74,231,223,25,235,24,93,6,209,140,201,163,144, - 47,235,19,210,194,94,163,174,38,251,152,95,251,94,148,179,198,65,41,181, - 147,63,39,50,145,186,54,231,237,8,188,83,135,123,103,97,54,20,66,244, - 166,136,174,102,246,168,91,66,79,34,240,70,224,141,16,163,69,196,120,64, - 163,189,168,205,58,177,206,107,142,194,68,151,90,172,11,7,168,178,177,165, - 9,50,35,185,76,193,61,26,162,153,89,116,218,133,59,189,253,233,139,38, - 151,105,147,146,147,63,254,230,55,30,226,232,35,211,219,43,78,155,144,82, - 225,251,97,218,206,171,44,31,40,81,226,76,192,227,34,184,204,73,185,178, - 26,113,243,13,203,116,71,118,225,185,17,82,245,216,208,182,168,55,60,206, - 223,163,175,200,247,239,151,220,125,251,33,150,31,17,172,174,78,159,172,215, - 134,39,215,195,233,85,94,200,250,39,159,102,109,221,197,250,88,211,169,213, - 83,121,183,71,193,148,66,74,145,21,119,231,143,251,107,63,94,209,55,104, - 15,166,201,55,235,58,2,228,227,111,214,28,163,109,97,244,35,88,93,75, - 172,167,219,95,222,183,18,114,37,87,180,238,39,173,212,37,154,170,195,44, - 12,235,154,221,124,226,1,104,162,171,153,122,66,129,151,128,122,104,145,35, - 3,51,255,172,148,90,0,213,213,147,22,228,2,82,44,17,117,31,166,206, - 34,163,48,193,224,80,190,173,241,56,251,236,124,178,220,90,34,7,121,152, - 114,45,170,76,231,224,244,123,154,85,112,85,123,242,157,168,153,223,137,90, - 67,108,126,225,175,207,253,15,28,231,192,129,195,120,126,64,127,56,102,52, - 24,228,107,151,42,174,68,137,51,19,143,35,7,103,98,24,6,81,84,97, - 241,145,152,219,191,53,202,149,155,126,126,114,127,215,110,125,210,182,140,67, - 116,251,35,238,186,187,194,74,87,230,211,184,213,105,12,36,107,177,62,9, - 102,46,74,155,245,237,245,167,10,81,206,207,185,58,60,89,44,230,78,97, - 85,87,166,148,155,105,143,116,49,119,202,25,167,11,79,202,209,244,201,215, - 8,227,117,213,156,168,203,53,10,206,108,199,176,58,77,178,235,189,22,38, - 164,90,60,22,209,55,160,163,114,183,100,52,63,57,57,23,195,171,168,30, - 70,127,110,42,244,57,107,64,81,162,135,18,61,61,1,65,76,15,100,221, - 53,88,34,233,171,66,235,178,46,184,145,38,186,241,128,86,245,216,148,195, - 50,67,173,150,253,236,38,164,99,152,77,226,56,166,177,46,199,205,254,62, - 214,255,189,204,42,56,85,80,104,107,145,61,167,251,85,250,209,144,111,238, - 61,144,23,156,103,161,202,245,102,6,26,198,233,75,56,74,148,40,241,244, - 192,227,110,182,12,176,247,150,136,135,15,30,74,151,79,59,248,230,231,245, - 9,166,57,175,213,218,129,135,66,186,43,17,163,225,116,110,39,203,193,137, - 124,138,192,15,134,89,23,101,254,183,0,139,85,140,184,203,56,53,62,24, - 73,151,104,233,254,60,60,105,187,167,96,65,179,63,77,12,167,59,14,167, - 144,195,11,99,240,215,201,143,117,153,110,235,85,151,249,173,101,250,200,225, - 58,199,225,43,146,40,53,161,20,148,162,18,62,255,63,123,239,246,44,201, - 149,157,247,253,246,222,153,85,89,247,170,62,125,193,0,232,27,6,51,228, - 112,0,14,6,188,88,34,135,51,24,144,34,41,81,34,41,82,18,105,139, - 180,100,41,66,122,80,216,82,216,10,133,104,217,138,80,132,31,20,254,3, - 20,225,7,71,216,166,30,252,226,7,209,97,203,178,101,91,148,72,81,33, - 145,163,25,145,20,57,36,48,221,13,52,129,110,244,233,174,123,85,86,101, - 238,189,253,176,115,231,165,42,79,223,48,224,52,28,249,69,156,56,231,212, - 201,202,75,85,157,253,229,90,235,91,223,98,43,142,162,55,49,7,249,86, - 201,35,179,119,64,144,157,194,4,218,99,184,59,54,88,206,123,244,188,138, - 212,59,174,252,190,60,82,107,90,59,99,189,92,185,72,56,186,199,108,189, - 163,63,122,215,153,85,227,198,221,216,74,148,91,212,224,140,118,17,211,170, - 150,199,31,239,197,47,71,112,135,112,83,190,157,224,200,161,220,0,238,8, - 243,87,127,237,38,139,251,157,188,254,167,147,226,100,202,68,215,40,42,27, - 52,248,120,224,67,165,40,173,141,89,174,12,255,232,31,173,176,54,58,34, - 183,97,103,74,191,251,46,253,193,144,229,172,197,141,27,138,119,222,251,125, - 150,251,61,214,204,49,103,214,102,30,134,250,59,114,107,162,138,138,178,206, - 209,36,229,28,0,189,82,134,112,213,186,6,20,233,73,132,155,206,45,223, - 43,200,33,232,42,215,192,29,249,38,238,250,8,194,215,221,128,92,197,120, - 8,63,21,64,239,123,133,26,179,212,212,173,84,189,183,39,81,113,210,190, - 214,231,137,46,221,232,60,194,243,68,39,22,18,51,3,182,59,231,93,233, - 159,187,115,215,243,40,120,199,147,138,235,73,207,160,246,127,80,121,76,137, - 133,83,153,246,31,16,244,31,208,29,60,32,109,189,199,122,185,98,52,185, - 197,226,190,198,212,244,190,181,75,34,151,80,220,164,213,158,16,4,65,78, - 116,65,171,252,156,250,215,251,97,53,56,129,39,240,58,241,146,183,238,42, - 251,127,206,152,47,222,231,95,252,243,111,176,219,77,217,198,187,146,224,196, - 155,137,55,138,202,6,13,62,78,248,80,4,167,211,13,255,242,215,246,252, - 198,191,250,45,164,236,33,68,92,73,77,134,93,65,239,210,115,185,122,242, - 222,189,30,235,83,205,122,53,205,23,163,106,122,50,58,170,157,60,46,242, - 8,206,67,118,107,93,45,202,152,140,59,244,247,55,153,111,235,11,116,162, - 212,146,231,157,67,114,167,146,179,75,97,15,133,189,239,34,33,213,90,163, - 51,99,233,60,45,168,22,121,125,236,40,253,25,91,196,193,148,112,23,189, - 73,212,125,88,239,139,107,183,67,131,220,167,44,63,104,85,234,109,62,138, - 179,103,89,125,101,200,167,147,227,4,49,158,232,124,125,110,217,219,34,247, - 119,25,132,59,2,59,205,167,152,251,116,174,45,77,19,31,101,81,177,254, - 224,247,220,117,137,152,205,198,176,219,135,148,111,86,246,89,147,181,84,206, - 157,228,209,42,202,118,94,131,219,234,179,175,231,108,241,210,132,106,186,123, - 71,156,164,252,242,255,253,206,209,150,101,69,37,208,144,92,131,6,31,19, - 60,53,193,105,173,105,181,47,240,246,219,154,36,189,138,49,107,2,249,210, - 81,20,119,206,215,91,236,93,222,185,59,203,251,222,140,157,35,104,231,119, - 218,130,56,107,244,134,227,158,165,122,4,153,123,133,49,145,155,245,150,166, - 236,141,35,141,125,42,50,87,139,59,249,254,212,102,158,205,6,115,233,73, - 175,160,236,216,155,108,227,141,235,123,235,12,8,231,89,61,46,59,29,43, - 118,68,139,8,196,208,57,135,116,12,166,78,135,210,41,136,65,191,59,114, - 164,19,9,228,62,205,219,5,228,192,96,31,76,137,135,113,46,250,200,219, - 2,244,16,165,20,241,48,62,74,57,250,244,228,33,226,150,197,220,50,116, - 63,72,144,139,4,59,52,168,83,131,105,5,140,238,36,240,213,81,222,124, - 238,93,79,226,112,238,102,202,221,180,149,57,115,190,110,151,92,250,70,174, - 186,236,74,151,90,94,246,182,172,95,186,155,247,232,1,88,121,14,115,78, - 186,250,228,200,145,231,38,124,139,174,24,185,1,171,219,53,235,228,134,155, - 165,7,121,122,178,219,149,88,226,172,207,173,120,15,193,245,195,233,52,65, - 200,184,228,100,226,159,219,174,29,198,218,81,59,132,28,29,136,76,178,27, - 145,172,214,38,142,34,57,63,35,14,28,121,182,129,59,108,227,127,195,91, - 191,255,28,251,44,138,3,142,162,56,165,68,163,164,108,208,224,99,128,167, - 38,56,165,20,113,188,231,43,191,62,205,93,75,124,139,128,39,185,241,192, - 181,5,220,187,215,115,209,219,221,59,37,5,93,1,241,88,53,150,242,54, - 197,66,213,82,34,239,131,43,163,21,60,198,93,118,230,28,210,234,180,24, - 121,65,231,214,165,200,204,250,66,101,211,60,18,234,216,35,181,100,25,86, - 196,249,223,59,187,98,17,172,136,68,166,150,206,46,219,135,90,48,84,213, - 243,47,167,20,15,197,37,102,6,177,46,254,30,41,123,68,182,166,21,156, - 41,106,241,207,137,148,101,209,205,136,106,152,77,247,206,184,35,156,134,44, - 116,132,232,233,220,20,122,168,98,204,93,71,134,34,123,221,86,187,53,162, - 167,243,215,198,167,92,197,114,94,244,16,66,54,40,182,192,102,99,136,90, - 170,66,96,82,198,121,155,64,254,180,78,17,66,139,188,5,163,254,179,98, - 205,188,166,77,224,56,130,59,206,16,248,223,29,153,157,158,174,249,173,223, - 252,205,60,146,244,81,155,143,226,188,187,73,99,196,220,160,193,179,143,15, - 149,162,252,247,95,223,243,127,254,147,223,56,138,218,60,122,125,23,33,173, - 150,11,86,203,5,15,230,127,128,53,199,119,224,79,166,162,36,115,160,0, - 33,182,36,89,173,77,201,227,209,56,197,148,231,179,9,84,157,235,128,24, - 179,78,109,101,234,181,31,35,83,134,48,187,108,76,205,163,219,25,242,62, - 182,178,200,36,182,149,223,131,174,202,163,54,53,74,115,130,208,235,160,94, - 160,146,17,89,185,177,187,174,7,46,39,182,216,98,31,76,115,194,181,98, - 87,136,101,182,146,225,102,231,166,133,151,162,197,32,153,162,148,170,144,174, - 232,105,22,58,162,115,62,35,255,25,168,197,34,247,213,84,189,52,239,173, - 27,210,194,222,201,210,207,118,134,16,115,214,203,21,182,119,47,79,95,119, - 187,146,120,175,33,119,166,41,224,73,46,34,69,152,211,163,215,181,92,143, - 11,187,37,43,179,131,8,206,227,201,82,222,59,62,152,46,185,249,214,59, - 164,73,66,154,166,121,20,183,46,245,85,54,227,116,26,52,248,120,224,67, - 17,220,187,239,24,30,60,112,81,155,143,220,140,113,237,2,157,97,245,174, - 253,221,27,239,177,90,239,106,239,178,31,141,106,31,84,188,115,53,179,68, - 239,233,219,25,198,68,8,25,231,2,5,143,242,0,204,73,231,173,252,103, - 105,102,96,166,244,130,25,250,193,150,253,230,131,218,212,23,184,168,36,110, - 217,99,21,98,134,218,222,51,128,7,179,163,154,25,184,84,99,249,80,121, - 212,99,118,46,18,234,180,145,55,204,17,185,213,237,11,128,173,64,190,43, - 15,251,211,243,99,85,200,175,99,160,147,217,112,217,118,30,193,149,81,215, - 223,231,163,204,206,46,114,130,152,210,62,125,106,210,183,79,168,81,202,58, - 125,159,205,141,119,48,139,234,53,68,161,59,201,34,138,207,136,215,100,10, - 220,236,253,75,211,148,152,0,43,207,103,39,85,86,95,22,231,156,108,138, - 253,31,70,112,199,89,129,199,37,186,152,27,183,110,16,199,197,190,226,56, - 70,201,77,110,223,213,140,211,105,208,224,227,129,39,102,155,242,152,156,183, - 223,214,88,155,77,203,62,136,226,186,97,33,122,8,197,77,182,187,0,33, - 46,157,185,223,135,223,105,31,187,201,3,180,35,87,151,242,233,45,159,86, - 178,54,58,82,216,165,226,101,2,123,63,119,48,81,89,45,174,63,185,75, - 171,179,113,125,94,254,92,102,110,188,141,79,197,213,89,97,61,10,143,178, - 240,178,25,95,151,219,15,86,231,179,70,243,146,128,165,206,234,171,140,116, - 217,67,124,163,184,86,117,90,188,63,98,110,16,115,176,179,99,87,151,116, - 217,203,167,127,231,219,47,164,155,97,215,38,143,42,15,33,31,152,227,107, - 235,24,182,237,34,18,27,238,3,250,237,30,114,52,167,211,215,249,205,131, - 183,112,235,118,229,67,109,217,142,122,225,68,53,141,88,135,186,8,174,172, - 164,44,163,248,253,240,28,220,246,187,248,148,15,222,125,31,37,251,121,68, - 169,147,52,79,83,122,52,98,147,6,13,158,109,60,85,4,103,140,97,191, - 79,249,202,175,79,65,140,114,114,243,83,3,252,157,186,199,55,190,209,98, - 183,218,230,119,238,214,62,217,32,83,135,227,197,109,23,107,86,153,212,177, - 44,49,23,34,38,76,130,146,138,114,199,124,115,131,192,46,145,102,198,168, - 127,151,40,16,72,59,43,196,37,112,52,49,160,86,72,226,113,56,92,180, - 4,43,98,71,52,254,249,135,209,88,22,245,109,219,113,78,12,233,166,228, - 46,114,163,216,254,168,150,54,245,17,88,214,224,253,181,89,126,156,35,33, - 202,12,212,109,13,31,28,167,210,212,108,65,252,94,177,253,81,189,46,218, - 33,204,46,143,48,243,8,54,115,82,57,171,190,167,231,129,27,215,51,53, - 136,133,32,144,243,124,58,129,71,157,141,90,192,3,2,30,96,244,146,197, - 46,123,31,75,41,74,87,131,171,79,53,139,154,244,116,254,183,210,115,170, - 66,147,58,130,117,131,85,111,188,115,202,87,126,51,27,84,155,36,236,83, - 131,10,3,214,27,81,17,155,52,104,208,224,217,198,19,19,156,148,18,41, - 37,203,149,225,43,255,230,173,60,117,36,101,143,237,94,87,218,4,0,222, - 185,229,162,146,229,190,232,17,171,171,185,61,190,23,165,67,111,228,22,152, - 126,38,117,60,20,40,28,142,203,57,233,100,139,188,153,98,214,239,33,237, - 140,94,119,79,56,156,33,71,115,54,118,158,203,227,133,153,62,114,14,27, - 56,162,146,251,180,54,173,103,150,238,165,53,137,170,244,176,137,185,147,240, - 107,173,157,216,35,19,148,120,2,17,102,87,141,144,202,117,187,186,52,228, - 13,91,125,220,111,159,61,199,158,138,252,252,202,226,148,186,115,206,73,171, - 99,139,129,170,157,42,169,28,146,190,48,238,189,44,79,25,247,13,224,118, - 104,43,243,243,220,13,208,238,192,8,219,61,127,97,138,136,223,79,92,207, - 83,148,143,128,159,38,240,168,244,247,217,86,112,213,185,113,219,221,138,233, - 29,151,54,149,50,70,167,73,165,233,219,67,235,164,105,250,110,208,224,25, - 198,83,215,224,150,241,150,175,191,181,204,235,111,14,153,172,58,41,212,111, - 222,166,11,96,187,205,22,241,199,116,166,168,162,198,77,94,213,251,54,158, - 133,88,220,65,49,165,53,154,210,235,238,73,66,183,16,111,140,96,56,56, - 176,168,202,148,133,133,122,178,168,95,193,163,83,144,213,3,187,231,213,74, - 253,59,245,117,156,242,182,38,81,181,228,230,207,195,204,212,81,20,151,63, - 103,118,220,179,39,108,132,190,225,84,158,135,145,216,108,219,131,173,168,40, - 57,235,234,143,235,125,88,251,26,148,7,175,138,133,223,135,155,9,231,135, - 157,214,69,112,67,121,76,20,229,8,206,214,40,87,235,68,38,66,156,157, - 250,124,188,105,21,46,229,62,95,9,118,43,247,239,17,81,92,127,154,106, - 226,149,139,48,149,122,60,83,232,6,13,26,124,107,240,212,4,247,155,255, - 86,209,137,82,140,89,99,237,125,140,89,35,196,243,24,179,102,216,41,86, - 212,119,110,57,107,174,116,35,16,98,155,141,198,121,50,213,164,67,245,57, - 207,133,183,73,116,17,21,14,153,209,230,237,188,206,35,58,73,38,50,41, - 84,148,99,110,51,62,119,147,48,233,185,81,47,242,29,172,152,211,21,35, - 22,75,133,58,119,159,182,185,133,153,101,105,68,49,202,93,69,98,45,156, - 122,178,99,42,211,187,205,82,162,191,82,180,14,8,27,161,79,91,136,91, - 94,122,95,168,41,229,32,75,209,222,6,121,195,228,243,227,230,19,167,54, - 29,225,106,99,234,182,70,134,199,105,69,177,178,57,169,248,118,4,117,187, - 186,157,127,94,126,220,140,248,98,45,136,148,101,155,69,92,234,223,141,242, - 109,203,170,203,209,215,87,121,186,116,214,221,66,52,115,190,154,29,67,186, - 209,174,119,110,33,233,236,52,98,33,73,151,189,252,124,182,237,24,187,48, - 140,239,116,8,79,31,32,39,115,215,227,55,222,211,15,190,225,72,202,198, - 36,237,86,230,100,18,1,35,70,125,75,123,229,252,42,3,30,48,211,138, - 110,122,90,137,224,92,138,114,71,185,30,91,22,153,120,156,149,254,46,215, - 225,170,68,119,44,94,129,25,183,110,65,208,93,176,75,13,49,1,251,245, - 28,37,55,172,55,130,168,63,192,158,49,153,188,65,131,6,207,14,158,154, - 224,238,47,31,189,13,184,187,240,229,126,95,113,249,47,171,27,61,30,46, - 50,241,205,224,197,54,139,117,135,221,230,249,252,247,229,114,69,87,141,242, - 58,96,21,213,125,39,225,154,112,56,67,216,145,139,220,196,140,225,248,1, - 108,119,110,86,91,86,231,178,179,226,229,57,20,154,28,169,39,183,46,154, - 176,34,62,178,233,202,163,177,82,45,46,143,170,14,34,56,53,91,96,18, - 117,102,99,119,25,54,222,187,20,228,7,222,112,217,28,61,87,172,92,159, - 156,63,255,72,217,204,187,242,126,237,49,202,34,149,252,177,94,234,200,244, - 12,251,49,143,72,89,236,52,115,107,201,174,181,60,29,65,136,152,78,231, - 108,209,204,64,185,99,7,89,196,87,143,179,163,255,135,165,40,31,157,2, - 247,55,80,238,102,195,112,131,237,222,178,139,117,174,234,244,216,44,211,124, - 24,106,131,6,13,158,93,60,53,193,205,62,208,121,202,177,12,33,226,74, - 253,171,220,204,235,145,212,185,234,63,116,1,114,119,237,229,26,202,176,183, - 165,215,207,4,16,155,57,162,171,115,19,229,99,196,72,251,30,97,228,20, - 125,93,149,57,228,103,174,248,74,45,80,163,180,98,147,37,247,41,194,60, - 32,157,14,143,246,86,158,20,224,35,165,116,163,43,53,46,160,146,86,172, - 16,207,172,42,36,105,107,145,19,157,185,101,92,157,174,20,193,137,121,38, - 88,57,124,137,222,9,72,227,14,180,106,204,169,115,129,11,57,97,251,87, - 199,252,118,130,125,75,184,253,150,72,215,36,10,98,235,136,172,99,50,143, - 145,194,64,218,220,170,42,52,229,34,65,190,83,157,104,110,102,5,209,122, - 148,135,171,110,99,247,218,237,114,107,177,226,162,202,239,159,9,198,196,219, - 89,77,106,242,236,232,255,80,69,249,116,153,130,226,24,122,87,221,95,221, - 100,129,70,73,217,160,193,179,139,167,38,184,119,111,221,6,17,149,28,38, - 142,91,5,60,14,221,75,158,220,111,242,112,30,152,67,154,73,254,135,131, - 4,187,57,142,70,234,188,40,7,195,7,78,45,57,190,67,56,159,161,223, - 87,206,11,210,46,72,38,137,147,193,47,164,75,41,190,43,107,7,155,66, - 161,110,180,35,89,95,143,155,29,124,63,128,152,147,71,125,62,186,18,54, - 202,137,207,19,226,195,34,185,244,107,6,110,102,251,91,149,235,131,142,16, - 197,202,66,236,142,149,187,175,108,93,74,213,215,231,60,169,121,216,83,81, - 33,50,79,218,118,38,152,255,94,11,117,234,136,205,159,163,157,186,125,186, - 116,171,64,220,180,164,113,7,49,55,174,105,60,27,49,4,69,29,205,110, - 195,138,217,50,184,250,232,160,52,170,72,166,51,162,206,184,242,249,122,82, - 60,126,47,156,63,70,113,163,240,222,123,197,205,138,111,250,62,11,77,195, - 119,131,6,207,38,158,154,224,238,221,235,81,159,46,42,53,100,111,103,236, - 86,91,231,61,104,230,121,207,92,29,158,166,15,206,139,76,54,139,5,195, - 65,66,176,90,85,254,126,152,10,221,119,127,23,212,60,183,159,226,193,20, - 249,246,55,64,143,142,82,133,38,81,112,223,96,23,230,200,154,75,221,39, - 39,5,49,119,222,143,234,126,65,84,118,97,92,189,108,85,108,83,65,38, - 223,183,53,1,134,152,187,191,31,214,224,60,89,85,48,181,200,120,79,16, - 156,177,192,102,219,251,116,234,8,64,12,217,253,142,170,16,162,219,214,230, - 196,88,86,74,70,202,98,119,17,230,237,62,147,119,170,145,162,152,27,204, - 13,155,71,120,246,93,141,58,53,4,113,105,187,3,21,230,40,58,140,120, - 138,23,193,200,113,158,166,156,105,117,134,147,73,61,30,71,69,249,120,200, - 60,44,205,77,0,130,110,76,144,245,116,238,83,3,186,16,209,248,58,92, - 211,240,221,160,193,179,137,167,94,17,254,253,111,29,47,62,229,187,109,47, - 0,88,238,247,249,244,0,63,224,244,195,161,228,100,225,69,38,61,203,70, - 207,233,244,210,76,169,247,136,1,153,106,65,231,252,18,51,131,221,191,148, - 232,247,21,108,37,145,178,136,146,228,80,204,77,237,212,0,187,48,46,210, - 201,90,1,236,237,44,181,232,35,148,41,117,46,84,69,170,17,23,41,229, - 253,105,94,180,178,21,136,27,238,199,124,246,91,233,57,196,213,218,95,240, - 182,193,206,74,132,81,138,26,203,209,27,247,13,233,253,108,17,190,181,161, - 251,175,147,163,115,51,137,114,145,215,109,235,132,36,7,164,110,190,49,173, - 182,62,100,17,160,152,131,221,69,108,205,206,189,46,183,171,231,34,204,174, - 210,4,190,55,61,144,139,82,138,18,132,117,23,45,205,140,205,98,145,147, - 92,125,155,192,89,189,112,163,218,199,171,120,252,104,112,177,114,199,73,55, - 17,105,146,20,211,198,213,144,157,174,207,84,52,104,208,224,217,194,83,19, - 220,237,119,125,10,231,128,60,50,21,91,216,21,236,86,142,208,30,103,241, - 121,252,62,184,234,241,2,91,40,31,182,235,128,78,203,17,67,184,219,215, - 214,250,192,185,116,116,100,27,59,159,208,122,39,64,254,250,219,121,4,103, - 167,176,93,137,74,52,115,232,61,89,33,61,159,234,155,101,243,224,182,110, - 14,91,186,82,126,88,116,61,106,30,79,55,58,87,95,30,33,59,5,223, - 190,192,86,98,150,146,224,192,93,195,71,139,58,13,178,239,18,113,203,228, - 2,145,244,107,6,241,86,209,87,231,183,23,115,67,112,103,91,68,151,165, - 217,118,122,181,33,248,117,237,34,182,165,172,40,52,213,109,13,219,29,187, - 76,96,194,205,226,218,124,175,157,111,57,240,55,64,117,83,215,207,71,69, - 100,228,107,113,143,242,162,60,196,195,6,158,58,156,101,180,124,156,61,16, - 178,250,6,165,105,74,152,110,75,191,87,27,190,155,52,101,131,6,207,30, - 158,154,224,210,253,189,135,254,125,147,36,172,210,44,117,85,99,176,252,228, - 120,136,96,96,45,232,9,232,148,250,181,202,170,77,0,241,86,53,125,233, - 73,43,184,179,117,41,187,77,77,250,116,134,19,104,108,235,95,38,49,55, - 224,91,254,202,206,38,83,11,251,179,211,177,98,229,106,96,158,0,124,138, - 111,161,163,156,48,243,253,123,28,164,27,253,223,243,217,171,101,14,158,81, - 31,217,1,226,166,197,172,229,153,193,140,152,187,232,210,11,105,98,45,80, - 247,93,148,154,198,29,244,221,34,130,74,227,142,219,182,52,115,78,172,92, - 13,206,195,138,93,49,75,239,33,83,24,78,227,76,204,211,179,104,220,104, - 135,58,129,210,135,67,249,162,59,53,143,215,189,152,16,198,119,73,147,164, - 162,164,4,216,153,162,142,40,229,163,85,175,13,26,52,248,195,197,83,19, - 92,161,148,108,99,109,84,244,41,137,17,219,253,38,247,162,20,178,159,71, - 112,190,71,169,174,209,251,241,133,39,238,185,125,229,22,163,84,156,16,216, - 37,187,229,10,19,79,179,227,140,16,237,14,97,43,0,98,58,237,19,0, - 212,215,65,13,31,56,99,96,27,33,70,83,24,67,247,247,18,146,95,220, - 67,60,70,76,138,35,153,153,34,120,59,35,161,210,226,108,60,9,149,136, - 67,190,43,243,185,107,234,151,13,97,178,130,184,104,194,174,244,165,197,142, - 8,116,150,142,220,154,29,194,70,244,127,169,93,169,219,217,145,172,28,199, - 172,101,222,179,102,126,251,4,110,130,109,187,253,165,171,106,107,64,184,214, - 164,169,202,175,99,202,16,125,218,66,254,51,131,236,153,202,26,110,79,133, - 59,199,83,139,29,1,55,139,137,228,29,217,198,254,226,128,244,119,59,4, - 209,150,32,222,86,8,204,111,59,182,17,246,171,22,157,6,132,171,13,233, - 157,142,243,181,140,90,236,148,101,240,175,37,66,196,46,133,44,187,153,200, - 228,192,126,203,76,97,45,80,76,243,86,129,42,41,250,185,109,245,55,59, - 229,26,92,89,65,41,104,231,115,225,10,60,60,93,190,221,165,185,136,105, - 167,92,59,138,10,206,110,236,110,34,184,6,13,158,61,124,19,170,242,187, - 218,89,93,155,204,194,200,154,85,205,115,62,220,241,202,8,236,125,82,49, - 168,68,111,15,85,222,149,141,129,167,182,82,75,226,214,230,168,230,102,150, - 18,189,14,176,34,206,21,133,226,230,65,116,52,195,41,11,183,18,125,218, - 170,16,159,10,206,86,223,49,117,181,174,72,89,172,136,145,211,135,244,127, - 149,46,41,214,2,59,115,17,148,216,81,68,113,254,124,106,46,127,188,152, - 185,230,242,219,246,120,251,89,245,121,105,220,201,163,203,244,190,129,111,60, - 32,92,109,242,235,242,34,18,153,165,49,205,45,131,141,247,149,166,243,48, - 221,228,105,219,182,62,78,103,239,246,131,236,167,199,184,177,57,163,121,187, - 236,100,242,116,120,28,235,174,6,13,26,124,92,241,33,9,238,225,125,70, - 155,36,169,53,194,253,102,120,81,150,17,216,106,215,185,181,17,118,87,220, - 161,111,119,5,201,232,211,22,219,211,193,81,93,45,126,79,145,126,205,169, - 2,187,31,36,174,174,22,181,16,95,115,245,171,88,11,118,202,194,215,91, - 185,16,164,76,100,62,173,167,238,187,199,117,154,189,180,7,169,195,226,128, - 7,118,95,91,233,8,162,180,125,69,96,146,63,207,13,43,181,111,103,164, - 67,22,197,149,246,159,174,84,113,124,64,173,82,236,20,244,87,44,233,169, - 34,9,251,142,24,79,75,173,5,167,54,23,198,132,167,155,60,186,180,255, - 143,65,252,86,38,88,185,93,242,189,156,185,253,138,211,108,224,234,59,129, - 139,4,243,227,7,121,218,54,156,134,156,174,78,201,29,72,194,180,244,194, - 212,191,239,94,104,226,78,174,222,24,249,208,201,228,209,53,184,135,97,75, - 113,131,246,144,207,162,94,96,147,227,127,155,38,69,217,160,193,179,135,167, - 38,184,237,126,83,250,109,87,251,115,55,12,107,35,184,39,243,162,124,56, - 137,166,194,165,31,183,89,205,168,37,215,46,130,51,229,6,109,183,96,189, - 120,199,45,136,126,112,103,190,143,184,67,247,131,196,169,7,231,238,119,102, - 46,66,49,51,149,247,133,141,200,212,146,95,171,33,158,153,179,223,178,11, - 227,210,146,7,127,59,58,239,149,66,221,214,164,31,184,27,0,189,118,4, - 145,174,84,94,163,243,169,64,177,170,70,93,194,70,46,117,154,17,169,216, - 1,251,78,254,188,58,232,91,19,118,191,163,144,243,154,33,170,135,81,95, - 214,28,46,54,29,228,191,19,112,39,219,71,26,84,124,47,211,212,9,105, - 196,77,235,94,163,155,197,46,84,154,34,223,149,8,219,70,221,7,245,245, - 76,126,111,35,194,221,158,90,200,34,63,188,212,229,249,69,117,132,243,52, - 126,166,143,194,142,58,114,107,235,247,242,86,129,68,187,155,165,224,32,93, - 217,152,46,55,104,240,236,225,169,9,174,59,10,15,22,30,239,19,232,96, - 119,219,60,77,249,56,56,187,6,119,246,66,150,236,119,185,138,210,167,40, - 247,198,121,35,138,78,82,154,232,13,243,112,137,58,213,168,251,85,231,251, - 188,31,108,230,108,170,14,189,29,237,204,98,110,216,162,199,237,171,54,39, - 176,74,47,217,12,244,13,167,176,84,171,20,21,120,15,202,226,239,135,207, - 177,111,137,220,156,216,71,126,80,40,32,115,196,69,68,104,79,5,118,38, - 92,107,194,90,30,109,7,16,164,186,56,126,246,184,250,202,3,186,191,151, - 28,109,159,198,29,119,61,49,121,186,211,172,93,243,186,125,87,35,190,145, - 98,214,18,93,26,210,150,198,25,153,238,59,238,121,55,64,127,117,148,95, - 155,239,203,219,174,92,68,231,111,16,124,61,109,143,62,106,244,118,27,186, - 252,112,239,41,50,143,79,223,7,87,31,173,117,218,197,245,250,26,92,25, - 94,69,217,160,65,131,103,23,79,79,112,225,163,157,212,237,174,126,6,220, - 211,91,40,129,39,60,219,171,87,113,182,100,209,163,84,142,20,71,201,128, - 183,126,199,84,198,196,136,57,16,187,72,45,141,58,152,165,196,158,10,130, - 120,139,88,89,84,154,18,164,218,9,72,112,233,77,249,213,76,116,82,34, - 70,112,41,62,113,211,145,33,113,41,109,8,199,77,213,100,36,48,171,218, - 95,49,203,200,41,77,221,207,217,121,28,165,57,63,208,71,145,154,23,181, - 136,149,205,137,79,206,45,42,112,74,75,241,53,131,185,153,13,136,221,22, - 209,119,184,218,160,86,199,117,66,117,106,208,255,72,99,190,234,158,83,86, - 101,134,233,166,80,117,238,64,220,50,4,95,125,224,174,251,131,226,70,165, - 251,65,38,161,191,97,9,25,231,83,39,186,93,89,233,131,59,196,250,240, - 229,122,200,132,128,124,147,199,234,131,59,11,245,234,201,50,210,36,33,221, - 159,157,134,12,31,227,255,161,65,131,6,127,184,120,106,130,123,225,19,39, - 174,113,251,12,1,192,54,14,16,237,78,222,243,116,56,198,228,48,77,121, - 118,13,174,158,12,197,250,194,67,206,110,135,221,134,149,223,61,236,180,232, - 87,43,35,184,179,173,151,229,239,112,19,179,183,18,121,195,165,225,84,154, - 86,26,185,211,184,227,82,142,167,6,249,174,36,53,89,221,241,112,93,158, - 85,163,51,51,83,185,107,136,185,101,10,34,44,69,125,182,127,236,111,153, - 150,82,164,42,48,213,122,95,69,224,82,92,143,190,41,177,51,123,20,217, - 85,212,148,237,226,121,246,183,64,254,51,147,63,71,206,29,225,171,85,154, - 31,39,76,92,250,89,220,182,69,255,155,247,197,204,162,195,116,163,217,253, - 78,65,12,221,118,114,100,221,246,97,225,235,188,79,86,131,171,233,196,207, - 222,48,239,121,234,157,114,246,153,223,164,144,197,246,135,41,202,6,13,26, - 60,123,120,106,130,27,76,62,65,20,13,14,30,173,146,214,153,181,22,158, - 36,138,123,186,90,139,232,248,20,82,61,113,10,219,206,123,202,202,81,71, - 217,53,68,7,129,35,143,153,171,145,233,27,85,97,70,121,215,65,170,49, - 75,153,251,52,62,169,16,207,156,161,126,4,10,185,127,167,235,234,113,55, - 109,165,206,39,123,199,11,187,39,61,255,93,206,93,74,209,182,221,246,182, - 172,167,40,165,39,243,231,127,85,34,126,221,34,231,150,164,231,142,165,189, - 155,199,145,240,197,17,40,80,233,255,171,88,118,101,216,236,66,58,157,135, - 247,80,30,161,230,38,202,55,244,195,147,40,117,31,101,232,93,202,50,152, - 113,101,28,147,123,172,120,83,15,83,148,77,13,174,65,131,103,15,79,77, - 112,175,191,54,99,27,247,92,250,200,198,217,34,84,245,140,220,163,43,13, - 215,62,138,251,102,136,76,86,186,77,39,120,175,80,80,102,245,27,87,131, - 107,19,38,1,97,107,77,121,30,28,184,90,17,184,89,103,114,145,32,238, - 66,208,205,22,200,25,164,145,19,152,232,126,128,90,165,152,145,64,220,182, - 164,241,43,200,255,215,22,196,23,4,16,57,194,147,241,30,198,32,127,85, - 147,252,74,151,160,187,114,53,171,108,189,76,130,46,233,157,14,140,179,182, - 129,216,237,223,206,44,246,166,59,31,249,239,50,129,201,206,157,178,247,178, - 44,167,55,229,214,73,245,205,255,220,38,248,131,52,39,182,138,0,165,164, - 204,212,169,204,35,60,217,51,200,237,134,212,244,73,3,149,63,239,136,216, - 50,66,12,215,26,177,35,143,222,32,75,83,102,215,100,214,18,157,202,188, - 15,47,8,52,68,16,72,151,42,101,156,189,158,255,240,101,90,239,4,36, - 204,178,153,129,115,98,115,229,161,239,248,217,40,78,180,42,114,202,254,186, - 151,149,76,129,191,137,178,236,42,25,130,98,42,69,93,20,231,48,236,239, - 8,228,136,80,181,80,109,233,38,123,103,68,26,69,199,77,252,77,138,178, - 65,131,103,15,79,223,38,32,46,29,252,30,21,119,218,103,13,157,60,227, - 113,120,82,145,73,148,55,122,151,161,168,58,166,28,90,117,245,111,167,132, - 167,15,208,235,128,182,22,21,167,126,175,156,244,81,135,58,77,43,107,159, - 250,181,91,136,175,25,196,60,19,145,120,119,121,159,166,204,172,185,194,149, - 171,79,169,85,154,167,42,195,213,134,224,219,183,136,219,174,17,154,136,188, - 190,23,158,62,56,118,74,137,75,169,204,195,151,44,6,113,199,93,187,56, - 120,9,252,239,42,48,152,78,183,146,142,244,100,5,46,218,60,124,110,126, - 157,217,54,182,93,124,201,158,107,14,151,115,91,57,70,249,156,14,207,213, - 159,127,235,244,174,179,0,131,172,6,247,97,212,143,237,51,126,46,220,114, - 252,103,172,213,74,243,27,169,242,13,149,37,46,145,221,241,103,206,147,223, - 249,243,189,252,49,63,54,199,251,81,198,241,182,81,81,54,104,240,49,192, - 83,19,220,171,223,29,225,239,168,189,137,242,55,199,76,249,81,112,169,164, - 149,206,204,112,197,97,154,244,108,172,94,12,176,183,157,98,113,167,108,165, - 230,230,123,202,242,244,91,121,237,139,97,247,171,75,231,244,209,46,82,134, - 126,157,244,34,141,114,100,231,145,110,250,216,243,130,244,203,231,41,175,171, - 58,8,156,98,113,41,225,157,0,238,27,130,84,147,132,253,156,32,125,128, - 81,86,69,154,181,68,206,109,69,196,82,135,48,89,85,106,106,229,199,235, - 34,54,15,79,106,71,198,31,20,245,190,50,201,213,90,133,101,48,51,69, - 250,239,15,156,79,62,148,192,168,120,110,57,69,9,199,34,19,63,42,201, - 178,43,69,114,53,119,11,64,217,213,164,29,137,236,187,51,122,246,105,74, - 99,34,34,82,66,229,246,219,168,40,27,52,120,246,241,212,4,119,50,0, - 193,20,108,124,48,6,39,91,132,108,156,15,183,252,112,56,92,16,171,86, - 93,143,247,28,135,254,237,52,87,46,30,106,238,242,254,51,10,39,254,92, - 44,50,195,57,240,207,200,211,123,101,107,44,112,41,58,19,21,211,171,253, - 218,41,183,27,236,231,36,230,141,177,139,220,50,50,244,17,160,134,250,111, - 174,0,0,32,0,73,68,65,84,152,59,101,167,190,219,70,236,10,225,6, - 20,53,175,50,161,248,175,50,73,229,164,116,6,202,127,203,235,105,37,98, - 243,169,198,218,125,148,136,174,92,191,243,219,62,138,104,235,234,112,79,143, - 226,96,219,125,189,53,214,97,138,242,236,116,120,189,255,228,62,110,87,38, - 199,3,121,138,50,9,206,246,23,109,82,148,13,26,60,123,120,106,130,187, - 124,69,98,108,41,37,88,151,126,180,113,62,245,219,218,14,81,187,117,188, - 77,134,179,85,148,15,95,65,125,13,174,23,84,149,15,206,45,3,142,194, - 144,131,121,103,126,161,15,2,93,95,142,201,68,19,94,68,113,232,222,127, - 152,237,82,229,193,152,173,45,102,36,224,79,11,218,151,239,97,95,20,121, - 250,81,7,65,65,18,83,71,4,121,77,43,131,90,165,164,155,170,19,140, - 109,227,252,34,169,18,155,216,85,201,166,252,179,39,101,157,74,212,53,147, - 63,31,178,26,155,23,169,68,110,219,156,216,235,174,177,68,120,73,120,236, - 82,83,126,45,42,132,95,66,167,230,230,100,244,33,157,64,172,153,211,110, - 153,74,26,220,121,80,86,143,229,62,103,135,164,123,124,62,87,46,183,217, - 198,31,228,74,74,0,157,38,36,58,69,155,110,163,162,108,208,224,99,128, - 167,39,184,23,2,174,94,30,30,255,225,140,58,155,16,219,167,108,196,125, - 250,148,86,93,93,79,172,50,97,71,86,247,170,212,146,252,223,189,52,191, - 181,117,2,148,113,33,162,240,63,123,225,133,143,164,116,16,16,68,219,163, - 212,158,122,205,96,95,151,16,205,216,124,58,204,106,97,25,9,102,147,8, - 204,12,210,59,157,202,185,248,52,104,208,93,213,70,75,117,145,147,239,127, - 43,167,24,15,73,200,126,78,58,162,45,239,39,187,46,34,16,99,81,136, - 110,74,72,3,85,37,184,136,218,237,234,82,155,65,84,37,148,116,115,220, - 201,61,127,164,89,241,195,103,252,9,57,58,250,124,85,201,173,238,115,89, - 144,157,37,206,191,32,226,220,240,19,128,27,60,219,105,85,207,183,215,181, - 141,138,178,65,131,143,1,158,190,77,160,47,249,220,107,223,243,88,219,150, - 199,229,212,69,113,133,219,123,25,254,247,71,139,18,218,234,140,166,239,210, - 68,239,121,232,34,61,157,6,78,216,145,161,66,0,165,190,182,124,12,78, - 9,185,155,71,4,102,36,208,253,32,143,0,61,105,217,190,200,9,35,92, - 107,244,79,72,212,249,61,177,22,68,207,107,108,187,16,96,36,253,174,155, - 24,48,61,110,4,135,82,173,15,71,68,57,201,28,34,58,72,25,122,194, - 42,159,123,118,158,230,53,224,90,137,216,51,66,178,231,5,246,188,200,35, - 208,116,211,207,173,184,136,32,232,235,188,118,88,38,185,67,226,75,83,133, - 14,2,228,88,231,196,86,174,193,117,162,20,100,183,246,122,31,142,234,20, - 129,78,171,186,15,31,193,61,12,85,245,100,25,229,168,47,226,194,248,34, - 147,231,174,2,176,139,53,219,125,169,201,93,125,179,71,248,52,104,208,224, - 163,194,83,19,156,82,130,235,159,124,190,34,44,201,199,225,28,136,77,226, - 93,47,95,124,226,154,222,184,67,25,119,246,172,236,251,227,69,112,34,118, - 119,217,222,201,164,108,182,124,116,188,219,174,175,173,220,172,92,57,252,53, - 72,94,41,45,160,145,35,55,19,181,220,66,30,187,72,199,68,45,151,222, - 139,170,13,217,229,159,229,119,157,115,87,161,44,246,154,32,53,125,236,7, - 17,42,72,115,2,240,210,126,79,78,105,160,8,2,141,24,103,86,87,235, - 82,26,181,116,78,30,201,249,46,250,124,144,167,26,117,63,40,136,54,131, - 10,12,102,36,144,223,117,14,241,98,245,120,21,210,204,126,14,228,138,112, - 173,243,253,37,125,247,122,200,113,246,88,86,31,244,231,148,156,239,194,152, - 252,156,115,140,33,120,174,100,124,29,7,76,134,79,27,237,156,93,131,171, - 139,224,242,191,85,222,92,127,46,245,159,175,168,237,110,120,174,92,187,78, - 216,42,142,39,149,19,51,157,229,69,217,212,224,26,52,120,246,240,196,4, - 103,140,193,24,183,144,190,241,229,8,107,59,8,177,205,73,205,114,7,203, - 115,103,62,255,233,122,225,178,231,226,149,155,81,197,170,171,220,30,224,189, - 40,11,179,101,23,130,244,187,153,77,213,88,59,119,252,172,31,46,175,71, - 141,169,56,129,4,191,176,71,189,102,114,242,81,105,234,250,221,178,30,47, - 57,214,168,191,191,119,17,76,121,253,28,23,17,139,189,10,246,154,219,193, - 8,16,111,74,212,167,51,2,238,11,71,8,115,131,252,170,113,246,87,81, - 70,118,251,14,246,21,129,249,246,22,233,166,239,162,173,177,219,183,239,175, - 211,253,0,179,150,152,181,36,248,239,246,200,107,58,175,159,121,18,34,2, - 123,197,16,244,117,94,127,147,159,92,161,207,203,130,220,74,231,194,56,251, - 57,19,216,164,47,4,172,255,163,22,242,127,4,241,183,247,216,190,200,83, - 184,114,172,157,106,180,31,176,254,169,22,234,239,239,177,47,10,236,7,81, - 181,246,230,123,11,1,107,239,3,109,166,139,111,30,25,212,53,121,123,113, - 137,251,114,82,212,106,123,128,199,173,252,39,33,92,132,191,221,157,114,229, - 242,159,227,252,224,109,32,115,51,177,197,180,241,179,84,148,135,243,224,154, - 249,112,13,26,124,235,241,196,4,39,101,230,140,33,247,92,190,34,57,57, - 105,229,42,202,66,193,118,28,117,61,170,254,86,223,7,87,109,210,246,232, - 180,211,138,85,151,206,52,145,166,164,30,17,157,164,212,7,23,163,230,165, - 136,44,6,59,61,72,103,101,169,184,252,249,67,9,175,159,195,94,34,111, - 238,134,44,173,152,17,130,188,42,93,234,238,16,215,178,148,95,95,160,122, - 7,62,143,227,82,237,202,167,17,203,99,119,218,78,121,41,94,113,191,231, - 190,145,81,169,55,46,42,196,44,242,147,6,49,148,216,171,199,175,175,143, - 36,115,7,146,107,64,180,195,94,19,249,126,236,121,81,156,71,41,173,105, - 175,24,236,95,183,180,255,179,9,226,149,226,181,42,71,167,42,72,145,99, - 77,251,251,7,204,175,22,79,46,215,220,252,121,133,165,157,23,2,32,120, - 178,26,107,117,219,36,76,115,155,174,114,26,220,139,75,220,215,225,231,170, - 156,166,116,225,184,37,198,218,1,66,44,17,68,92,189,10,131,11,69,122, - 184,29,156,253,217,85,170,137,220,26,52,120,86,241,84,41,74,79,114,151, - 95,8,248,246,87,31,45,52,57,76,99,30,250,82,66,157,138,50,203,5, - 30,225,236,200,79,202,106,225,201,77,244,246,251,202,144,69,106,246,198,241, - 159,60,130,120,139,62,1,251,147,18,251,178,168,180,4,132,105,201,65,227, - 106,23,251,178,56,138,224,106,127,6,84,47,205,137,139,49,174,254,86,119, - 29,61,131,253,179,42,151,216,219,145,35,22,21,100,13,230,62,218,4,236, - 143,159,192,69,133,121,141,98,20,206,184,56,118,16,109,157,135,100,96,48, - 175,185,169,227,193,231,36,60,71,181,86,87,138,60,137,64,254,236,14,241, - 211,138,240,250,220,77,42,175,185,30,219,23,108,190,55,68,124,81,48,97, - 81,249,155,153,41,54,223,27,98,222,28,179,191,226,149,180,69,239,100,129, - 199,136,228,243,207,203,129,21,92,18,228,17,92,185,15,174,58,205,187,44, - 30,41,167,39,119,192,184,210,27,103,237,128,168,221,231,249,203,85,210,50, - 37,139,46,21,250,212,172,219,70,235,36,251,94,189,97,106,230,195,53,104, - 240,173,199,135,26,120,58,30,41,190,235,115,207,3,211,74,47,156,79,89, - 150,83,151,197,223,188,161,109,121,17,170,19,153,28,147,155,205,22,166,237, - 174,40,244,183,213,61,20,115,68,219,89,117,185,26,220,67,22,77,111,195, - 117,195,133,77,73,191,123,92,135,154,185,102,112,249,201,21,230,13,89,212, - 194,162,22,73,208,205,23,122,209,142,177,175,59,209,69,89,152,146,71,48, - 227,172,214,231,209,49,36,159,58,159,139,85,100,88,68,127,182,47,72,55, - 125,204,90,98,191,91,32,94,46,22,89,191,189,237,139,60,50,244,47,143, - 254,206,57,116,218,4,111,40,228,137,65,92,44,189,110,37,162,75,122,10, - 123,77,184,169,228,87,82,146,151,187,69,52,54,6,113,222,230,231,109,95, - 20,168,159,80,168,243,123,182,198,189,79,242,32,202,243,215,219,254,62,67, - 112,113,229,110,8,174,74,236,21,103,26,45,199,154,246,103,52,226,139,130, - 214,103,171,93,135,15,243,40,125,56,142,35,184,135,161,124,211,228,83,149, - 135,246,92,62,53,233,127,30,118,191,157,235,159,188,92,169,191,121,116,162, - 234,99,81,20,229,17,156,82,31,114,118,112,131,6,13,190,233,248,80,255, - 149,74,41,222,120,243,42,231,206,57,82,179,54,118,100,245,16,75,174,58, - 212,139,76,60,202,68,88,106,226,205,106,112,59,93,55,85,224,209,105,47, - 113,203,57,242,7,209,214,165,233,50,33,73,133,232,38,91,228,151,5,242, - 154,27,97,19,68,219,10,121,109,205,14,243,185,33,246,69,225,30,207,22, - 127,59,146,142,52,94,228,40,69,169,62,159,9,53,202,219,102,251,243,78, - 252,230,13,9,147,204,50,44,48,69,77,173,68,88,0,226,115,150,224,115, - 18,209,142,225,74,234,136,41,77,93,205,43,219,214,215,191,212,107,89,228, - 6,208,49,168,75,187,227,115,200,142,33,190,0,100,81,87,164,44,194,30, - 220,124,140,129,107,32,94,113,117,197,173,217,185,235,60,41,237,231,26,168, - 215,5,106,148,98,95,159,84,158,30,116,203,170,209,226,189,154,198,103,212, - 173,158,240,243,4,101,114,171,19,47,249,104,110,91,218,62,2,123,129,23, - 94,188,202,203,159,118,231,225,123,224,130,48,204,109,186,206,66,19,177,53, - 104,240,236,225,169,9,78,136,8,173,53,175,126,94,115,229,249,151,128,227, - 9,1,15,35,186,178,200,164,62,130,243,168,139,198,226,71,140,203,57,84, - 81,86,163,26,19,181,16,183,51,35,227,178,184,162,252,252,108,110,156,185, - 46,49,111,72,71,130,7,216,41,75,240,157,75,87,219,42,65,14,156,40, - 68,159,47,94,94,97,35,230,128,28,204,43,219,87,70,244,224,218,15,196, - 155,231,156,108,102,86,234,119,171,105,91,216,124,111,232,136,77,196,46,141, - 120,13,39,233,143,182,57,105,5,177,235,205,179,87,37,250,132,124,112,171, - 28,20,105,71,25,106,136,4,118,36,217,124,58,196,252,144,66,120,161,200, - 182,74,126,254,43,136,182,164,159,148,4,39,146,157,178,208,49,152,203,38, - 191,1,48,175,73,196,203,33,243,104,134,156,204,73,152,209,109,39,116,90, - 221,131,113,57,197,251,59,137,30,69,18,79,46,76,170,166,39,61,185,237, - 74,95,69,20,23,181,47,243,253,95,248,52,221,142,83,76,86,29,122,10, - 4,65,67,102,13,26,124,28,240,212,4,231,239,88,199,227,46,63,246,103, - 190,19,40,250,206,132,136,114,114,123,220,104,174,62,130,171,171,217,184,105, - 203,239,45,198,92,144,110,49,125,96,250,44,214,162,34,50,105,201,1,201, - 62,37,202,106,38,243,112,233,188,40,175,74,183,8,31,30,46,35,62,93, - 190,83,223,186,30,54,249,229,99,33,134,29,73,218,89,186,207,188,150,189, - 140,179,106,207,151,173,155,193,121,37,69,156,207,34,152,168,74,154,65,95, - 163,94,51,200,207,222,119,178,153,113,225,66,146,31,219,215,202,34,104,127, - 255,160,168,143,1,246,165,32,39,106,25,234,60,146,4,176,215,65,157,47, - 82,131,233,39,75,111,125,118,30,114,96,104,127,70,35,127,160,74,186,86, - 100,237,31,47,186,99,136,243,22,59,146,168,215,221,243,242,203,156,184,223, - 109,95,96,175,9,196,56,107,134,239,105,244,183,181,217,236,92,58,79,180, - 235,137,195,60,50,115,89,253,44,132,201,163,122,210,226,131,159,61,185,121, - 197,111,213,253,230,165,43,47,113,253,147,151,115,255,73,33,182,180,219,143, - 38,213,38,61,217,160,193,179,137,15,245,159,41,229,158,126,184,224,187,62, - 63,204,251,220,234,4,36,214,198,71,68,87,142,246,206,158,13,23,195,129, - 19,60,192,118,23,240,137,79,252,62,247,76,135,182,186,199,57,185,98,16, - 212,132,56,64,156,20,41,194,151,63,35,209,215,199,46,186,10,130,74,13, - 202,71,37,190,97,91,12,37,136,33,115,64,188,98,92,173,205,99,12,226, - 100,76,180,23,142,96,94,63,151,19,137,186,180,195,180,30,190,240,234,23, - 15,34,0,127,234,89,164,85,38,173,124,190,90,38,74,177,35,153,59,166, - 200,235,213,183,79,95,29,151,246,37,216,182,179,105,220,125,129,189,62,38, - 214,162,72,55,158,27,87,162,66,211,10,48,173,0,121,93,16,183,44,54, - 222,187,40,50,59,23,49,161,114,93,114,96,48,87,198,176,45,245,252,141, - 33,125,46,75,137,94,7,27,239,25,197,238,32,231,251,231,17,34,46,245, - 175,61,225,192,60,224,48,130,123,120,13,46,206,63,47,103,167,191,157,176, - 4,220,103,171,29,157,231,165,151,174,144,236,119,21,139,174,32,8,232,68, - 109,162,40,170,29,149,211,164,39,27,52,120,54,241,212,4,103,140,65,169, - 30,198,142,248,35,223,187,225,103,255,204,37,210,228,4,107,99,130,240,254, - 35,159,127,152,162,172,162,156,94,172,83,221,21,41,202,157,190,144,183,9, - 84,79,208,169,29,93,4,231,22,211,91,175,4,4,95,158,147,70,157,156, - 200,252,252,55,31,237,248,22,0,187,48,16,205,242,61,139,159,176,149,212, - 162,101,225,210,120,91,137,186,60,119,4,152,5,4,118,104,220,254,38,165, - 230,239,120,207,216,70,136,168,133,250,9,197,230,98,136,109,157,43,162,185, - 25,36,47,119,145,127,35,155,213,102,35,71,164,23,227,252,184,114,96,114, - 97,138,61,47,144,131,121,78,88,115,32,252,51,78,81,104,71,18,211,10, - 232,181,178,94,173,107,160,174,205,137,148,205,69,35,226,203,75,119,14,35, - 89,164,82,191,104,145,63,156,145,70,199,48,242,233,201,236,187,29,58,178, - 91,203,22,250,188,36,57,127,159,109,59,206,207,193,190,46,81,223,145,184, - 215,207,105,126,208,171,13,106,248,128,229,247,86,163,194,66,225,234,94,180, - 200,62,87,169,167,166,184,6,121,33,226,146,138,210,165,21,109,77,104,92, - 110,19,112,239,143,39,181,25,48,205,190,207,113,159,173,34,53,41,196,18, - 236,101,46,142,63,205,151,127,240,75,200,224,6,97,171,157,71,113,65,77, - 3,119,16,132,180,165,23,151,28,167,174,27,52,104,240,108,224,67,164,40, - 37,73,146,160,117,194,133,11,23,249,220,247,92,205,91,0,146,125,250,4, - 19,187,171,56,158,213,245,24,41,162,131,57,112,101,148,35,56,112,145,89, - 185,79,43,136,157,56,196,215,205,106,207,41,106,97,174,75,54,23,139,197, - 206,47,246,116,140,147,233,95,54,121,227,54,184,20,225,65,215,2,54,46, - 114,112,157,190,101,179,90,86,254,94,233,31,19,7,17,111,70,90,57,174, - 85,247,93,94,242,101,168,139,243,131,202,121,3,176,149,4,93,69,175,149, - 84,148,156,224,136,53,218,87,23,109,95,143,179,35,119,221,189,86,194,162, - 219,166,35,219,121,77,15,156,160,198,92,54,185,176,5,156,16,41,191,134, - 140,8,195,221,62,31,103,227,17,139,59,60,46,132,136,177,54,34,76,130, - 188,15,238,112,92,14,80,83,123,131,195,233,1,110,187,25,23,46,92,231, - 245,87,77,94,127,43,71,112,101,248,250,155,104,169,166,7,174,65,131,103, - 28,31,58,69,25,6,27,164,148,124,225,75,47,115,229,178,35,35,47,24, - 41,207,226,130,34,85,249,240,116,101,4,116,120,18,171,174,186,8,46,57, - 240,188,236,119,21,250,219,128,139,170,88,240,179,212,164,120,209,213,164,188, - 133,85,29,84,191,75,251,51,186,66,130,86,100,209,75,180,67,94,23,213, - 148,223,48,68,76,40,210,141,217,119,43,98,39,169,207,136,162,92,135,19, - 47,186,243,3,71,52,226,188,117,174,32,213,82,145,171,23,190,38,11,129, - 137,71,148,41,35,179,125,122,66,140,158,215,46,229,74,166,138,140,90,208, - 177,46,114,203,182,45,19,34,80,136,75,182,178,66,204,30,131,139,165,199, - 178,52,165,136,90,200,235,130,224,59,178,9,12,235,0,189,239,229,173,18, - 66,248,26,88,213,39,244,254,242,32,93,185,22,140,213,217,78,32,214,70, - 217,190,10,39,147,56,118,55,11,78,145,59,59,112,46,57,156,251,86,164, - 47,173,29,32,136,248,246,111,251,30,46,94,254,4,155,109,113,211,209,110, - 183,9,130,128,136,108,222,159,121,26,15,205,6,13,26,124,171,240,161,8, - 78,167,27,130,240,28,113,188,231,242,11,1,111,126,241,34,214,222,69,138, - 42,225,28,18,93,29,158,116,162,247,33,214,198,53,122,123,171,174,170,0, - 33,155,210,140,65,140,45,157,190,117,253,108,25,210,79,74,130,55,20,233, - 119,171,163,40,46,214,194,17,89,59,134,137,200,235,96,249,121,103,10,70, - 121,245,56,194,243,164,2,56,194,200,72,78,245,210,194,77,228,97,136,138, - 246,131,74,164,53,6,241,154,168,214,234,206,128,19,132,128,30,23,13,249, - 86,196,216,120,159,139,96,196,194,157,167,152,212,237,33,219,38,187,22,195, - 24,125,94,186,232,116,43,28,1,138,157,235,175,195,185,187,164,135,189,255, - 250,216,12,160,112,153,233,160,228,243,68,182,176,119,211,189,49,51,173,232, - 180,235,107,108,158,220,202,78,38,237,150,193,216,249,1,185,109,41,238,14, - 102,248,97,185,110,31,203,188,254,118,97,124,133,239,127,227,37,214,171,30, - 117,16,81,143,40,138,232,117,109,158,158,244,209,91,227,65,217,160,193,179, - 139,167,38,184,36,73,80,37,146,56,57,215,226,175,253,205,31,228,202,229, - 139,4,225,125,68,141,247,95,97,159,116,76,118,143,211,7,87,160,152,232, - 13,117,189,112,238,111,225,129,216,67,116,181,91,220,135,166,58,194,101,34, - 16,151,213,81,74,17,92,43,0,56,82,144,99,216,182,85,133,108,132,141, - 242,230,233,246,103,116,173,59,137,95,252,217,202,60,50,146,227,34,194,42, - 63,71,107,157,31,175,220,102,224,35,173,181,108,97,71,50,39,163,124,223, - 184,136,201,239,203,147,22,145,64,94,119,253,104,121,34,55,35,91,121,93, - 56,95,202,44,122,179,211,44,141,26,183,179,107,107,19,183,178,235,207,218, - 38,100,70,24,98,2,86,182,161,99,208,235,128,112,26,230,209,228,170,187, - 197,204,192,46,38,44,102,231,88,28,68,160,46,186,46,222,239,81,223,114, - 207,116,72,197,128,84,156,228,143,111,119,65,158,214,44,163,252,152,143,224, - 188,21,92,125,91,128,191,242,178,171,73,209,87,249,125,223,247,5,94,122, - 233,74,190,207,179,210,147,30,34,155,38,222,212,223,26,52,120,182,241,33, - 166,9,184,127,242,253,94,19,69,45,192,114,249,133,128,159,254,233,243,236, - 247,167,249,118,117,68,7,53,233,203,39,138,224,10,164,194,221,133,107,70, - 104,70,185,20,125,159,86,23,31,121,225,34,247,54,33,177,22,44,186,37, - 101,230,200,69,35,182,187,117,164,225,101,245,83,71,94,149,218,214,85,89, - 8,55,74,136,148,117,68,48,17,200,80,23,228,130,35,160,114,157,170,188, - 47,59,52,69,93,45,35,188,114,99,184,29,81,77,137,250,52,226,137,68, - 12,101,133,220,128,188,217,218,147,150,29,26,244,121,71,134,162,29,231,231, - 147,227,220,164,210,202,32,38,46,205,40,74,47,185,175,199,149,35,56,255, - 187,48,69,228,150,71,105,23,21,253,118,15,113,174,28,14,58,193,136,181, - 145,27,151,115,128,249,170,122,29,11,83,68,69,66,28,127,118,14,31,219, - 108,76,102,50,224,77,149,189,168,164,220,212,189,43,136,77,248,116,102,76, - 167,253,41,190,248,230,23,104,119,223,163,221,125,143,139,145,38,209,123,151, - 158,12,195,92,61,9,213,254,183,134,220,26,52,120,246,241,33,82,148,22, - 165,122,249,63,186,181,49,221,142,230,7,190,252,131,92,189,252,233,210,118, - 85,169,118,93,84,231,31,23,68,21,183,18,135,39,19,171,116,219,135,4, - 116,188,64,14,46,117,156,156,253,32,245,39,134,46,253,152,214,72,193,1, - 244,73,181,121,187,114,150,202,34,95,42,22,245,138,208,47,139,218,242,90, - 84,214,189,125,40,6,180,67,147,255,237,16,166,21,32,22,142,96,205,101, - 131,62,169,217,168,99,208,67,71,52,158,100,237,136,106,170,52,67,172,5, - 230,92,241,248,162,219,118,202,71,47,251,143,143,207,99,153,20,143,233,19, - 176,7,111,141,62,109,49,221,135,152,231,79,176,83,131,214,67,204,178,96, - 104,33,98,182,113,125,26,240,73,224,35,56,187,219,58,114,51,69,132,118, - 108,201,229,27,186,171,228,6,32,24,243,39,254,216,207,240,242,167,53,201, - 222,93,204,146,79,20,14,38,165,158,200,40,234,16,4,97,99,207,213,160, - 193,199,8,79,253,31,234,133,34,97,24,98,140,38,73,66,194,96,195,143, - 252,177,136,159,252,169,63,146,109,85,181,232,63,139,228,196,65,175,91,53, - 154,123,124,247,138,185,209,121,4,231,231,194,213,65,119,93,74,179,220,148, - 237,165,238,50,212,185,201,49,84,35,30,213,175,138,12,132,141,42,125,96, - 249,227,56,146,73,195,9,225,52,139,70,226,54,74,169,60,229,87,75,80, - 135,199,204,218,12,242,241,59,62,226,155,8,130,174,42,34,195,82,234,211, - 227,80,52,82,17,163,196,78,253,40,122,58,39,173,65,184,115,105,71,177, - 59,34,174,67,210,181,35,8,178,241,67,225,52,68,41,69,186,152,176,208, - 213,155,147,141,201,110,126,54,138,85,250,82,37,181,216,110,37,28,222,124, - 164,226,132,169,233,162,76,65,130,117,41,74,128,78,75,209,226,172,254,179, - 178,184,164,152,216,125,180,143,246,39,249,201,63,253,253,152,244,58,151,206, - 237,73,246,187,188,185,251,176,61,160,113,47,105,208,224,227,135,15,145,162, - 44,22,33,41,21,173,150,66,200,49,233,54,230,239,254,189,139,188,246,202, - 231,105,135,167,153,91,196,8,195,29,218,173,37,100,4,38,152,229,68,87, - 30,107,242,232,8,174,248,125,155,62,207,123,187,139,164,98,192,78,95,32, - 224,83,140,59,51,183,40,202,110,73,200,80,60,39,60,61,161,253,125,183, - 224,143,116,8,162,45,102,88,44,100,241,203,9,250,69,69,26,117,92,13, - 41,222,231,36,34,108,4,118,129,189,38,42,207,177,221,45,98,147,17,208, - 181,121,209,196,61,17,4,201,212,165,13,227,118,94,91,203,9,47,219,6, - 92,211,120,158,26,21,197,185,122,239,72,117,41,139,114,23,46,245,168,174, - 187,227,130,75,33,58,85,164,129,105,7,113,109,142,88,200,60,149,40,175, - 11,196,167,93,58,115,52,237,16,45,34,151,130,220,74,84,107,141,61,112, - 206,23,214,157,171,104,67,186,209,16,183,243,115,234,103,215,201,68,228,36, - 104,23,19,210,233,16,165,22,12,214,29,186,139,75,172,159,23,44,94,190, - 136,221,40,140,25,161,147,99,121,234,110,31,226,110,126,182,8,233,166,103, - 79,77,151,137,220,208,14,100,62,96,84,100,3,249,28,209,181,129,182,75, - 81,202,69,174,148,221,238,150,88,110,97,185,3,188,79,209,243,182,115,223, - 197,187,149,200,205,237,240,50,127,247,63,255,9,6,147,16,25,220,224,193, - 106,64,216,106,211,233,88,76,162,142,154,187,235,6,156,54,13,222,13,26, - 60,219,248,166,229,88,164,84,40,37,17,45,69,75,245,249,107,127,251,11, - 244,6,159,165,213,58,143,229,22,130,136,120,175,105,183,146,188,86,2,135, - 81,93,221,221,250,97,4,215,174,108,119,49,114,196,225,107,113,30,135,53, - 56,35,158,7,192,174,61,1,185,116,164,143,182,192,213,210,236,200,245,163, - 213,9,78,30,166,90,108,235,250,154,76,62,77,64,15,11,1,201,206,213, - 48,253,49,236,253,217,241,246,30,53,231,145,167,28,125,3,118,77,157,42, - 223,182,70,25,89,142,208,198,157,108,0,235,124,156,55,103,23,39,83,82, - 94,46,12,146,153,251,26,59,49,140,222,247,88,38,69,138,119,153,104,214, - 43,119,254,189,247,44,86,187,247,100,157,100,105,83,47,237,175,153,182,190, - 77,159,103,34,55,136,174,206,201,205,161,62,130,223,198,1,118,183,101,187, - 45,215,244,188,176,196,255,60,35,106,247,105,181,253,241,179,218,155,29,240, - 19,127,226,167,184,252,242,69,122,253,106,164,111,76,68,171,91,253,183,240, - 209,91,57,61,217,160,65,131,103,31,223,212,34,130,139,228,90,40,21,242, - 147,63,222,230,231,126,254,75,36,251,234,196,229,120,175,143,60,0,15,251, - 149,142,163,184,50,138,122,74,142,94,33,226,216,155,30,66,196,180,130,170, - 176,67,218,247,0,88,38,35,244,190,135,188,14,156,72,44,11,172,156,96, - 69,236,82,131,89,43,0,28,167,230,216,102,130,20,175,58,244,253,97,29, - 203,78,89,39,255,31,57,151,147,50,166,251,16,212,34,23,230,232,125,15, - 58,109,151,18,28,26,23,193,29,224,200,193,31,239,144,82,77,111,10,219, - 62,18,155,128,83,59,250,26,159,221,21,251,210,90,187,47,79,164,153,24, - 196,171,35,173,44,174,89,181,214,104,173,157,117,151,152,228,81,161,219,145, - 35,141,65,168,208,57,17,102,98,18,61,96,113,225,50,0,198,20,207,41, - 167,27,195,86,159,242,251,216,9,220,251,227,29,76,14,81,21,150,56,134, - 118,228,54,205,62,63,51,10,97,137,107,9,176,204,136,119,43,118,113,245, - 179,112,105,242,5,190,248,230,23,184,116,101,76,106,230,132,173,118,173,53, - 87,168,2,186,53,229,216,70,96,210,160,193,199,3,223,244,42,121,24,134, - 249,2,240,243,127,241,58,175,191,122,254,104,155,40,244,164,87,157,205,85, - 173,147,28,14,105,171,57,86,171,205,212,116,73,55,231,209,189,113,69,98, - 94,7,245,245,236,56,107,69,122,117,92,8,50,140,11,93,34,101,93,84, - 229,199,190,116,170,11,163,136,90,121,68,100,71,20,205,219,241,222,69,112, - 153,244,222,19,96,26,186,141,135,42,198,46,38,104,173,43,117,42,39,106, - 1,177,127,80,57,78,164,108,222,16,14,133,16,198,48,118,146,127,165,96, - 43,17,182,141,221,101,74,199,109,253,91,233,213,142,225,52,116,196,154,145, - 145,82,10,173,117,69,104,2,192,214,141,190,73,55,46,66,243,164,44,7, - 46,85,184,232,182,115,82,180,107,197,50,25,177,49,130,101,50,194,110,20, - 86,15,48,102,132,49,99,30,204,175,177,218,78,208,251,19,214,139,106,154, - 210,221,248,20,175,197,54,125,158,233,89,141,212,54,46,13,75,45,141,79, - 18,91,44,59,12,119,40,236,184,10,114,19,98,9,226,94,37,61,217,106, - 15,249,177,31,249,146,19,150,232,125,46,46,233,116,44,161,106,17,132,33, - 42,8,9,85,128,10,3,140,45,196,37,238,117,19,77,239,91,131,6,31, - 19,124,100,50,176,110,32,248,182,151,5,255,213,223,123,131,75,39,153,129, - 113,22,1,196,137,155,229,230,123,146,44,179,163,168,174,138,227,52,213,98, - 237,110,173,253,157,183,221,148,235,33,110,209,114,125,112,197,34,106,46,124, - 22,187,113,17,71,208,51,136,235,176,61,144,168,139,201,241,99,30,86,196, - 199,205,219,20,86,86,117,81,87,69,120,161,135,76,102,142,196,245,60,112, - 4,88,246,171,28,85,173,173,220,99,133,15,164,24,101,61,104,153,75,191, - 221,185,104,208,247,171,249,20,104,158,118,157,8,210,112,66,186,44,136,10, - 181,168,164,30,69,79,87,213,156,157,118,37,77,170,181,62,178,238,2,71, - 110,90,15,93,157,109,57,198,44,199,57,185,173,147,33,91,109,8,162,33, - 154,17,15,76,191,242,220,98,154,64,53,18,63,140,162,138,39,68,71,173, - 1,130,105,38,116,186,83,106,11,168,54,115,31,159,244,5,254,248,155,255, - 9,63,254,231,190,12,144,147,155,63,174,119,46,1,55,185,187,37,244,65, - 107,128,35,54,99,206,118,89,105,208,160,193,179,131,111,42,193,57,53,101, - 33,211,183,123,205,23,126,224,69,254,214,47,188,201,201,185,171,24,238,100, - 209,91,84,34,183,146,109,210,193,239,14,245,35,115,118,242,185,163,199,116, - 119,84,114,171,247,110,25,110,34,129,175,193,117,116,143,173,30,179,80,247, - 16,19,73,167,239,200,34,214,46,10,18,67,73,244,252,177,63,163,55,41, - 214,39,153,244,126,94,212,203,188,24,197,138,184,222,13,36,35,20,187,86, - 76,75,53,63,49,156,86,26,190,207,130,73,20,98,33,89,38,89,90,51, - 222,59,49,200,222,9,125,242,40,206,111,63,156,177,232,182,145,99,71,96, - 64,190,237,66,71,142,156,246,189,130,124,39,2,195,152,217,182,135,158,187, - 115,73,38,238,125,84,74,33,108,27,179,28,193,196,125,92,146,145,187,81, - 217,24,145,215,217,140,25,177,220,93,102,157,12,209,251,19,44,19,78,227, - 33,59,125,161,226,82,82,133,183,101,115,209,120,223,58,2,87,153,59,73, - 212,57,195,28,212,91,190,113,11,71,106,119,178,175,121,118,179,20,31,137, - 74,172,29,240,249,87,127,58,239,121,243,199,244,222,147,233,46,123,45,77, - 68,175,221,66,155,46,173,222,232,168,53,0,154,233,1,13,26,124,92,240, - 77,175,193,149,211,55,237,190,91,188,254,194,95,249,97,126,238,231,191,196, - 115,39,1,113,146,98,153,228,13,224,69,35,248,236,160,125,160,92,252,40, - 71,112,46,173,185,56,232,2,72,162,75,24,19,229,117,158,170,200,100,199, - 253,173,91,148,54,72,218,171,76,170,63,153,228,105,74,15,159,86,172,67, - 172,69,65,86,229,6,233,108,170,192,227,96,16,58,73,189,59,129,225,17, - 33,122,34,2,39,197,47,247,233,13,46,238,93,131,119,203,30,73,249,227, - 150,205,207,77,44,36,131,112,135,149,69,42,49,23,215,100,168,252,46,142, - 189,60,183,167,131,163,243,169,156,103,22,189,1,121,212,230,241,192,244,57, - 141,179,86,9,49,56,18,0,213,161,29,169,252,61,124,40,114,31,211,187, - 217,141,208,251,56,197,228,252,76,98,195,94,224,179,159,250,17,126,238,47, - 252,32,175,125,207,5,30,252,193,166,82,119,107,183,219,180,186,146,168,211, - 161,219,181,168,48,160,215,61,110,206,111,210,147,13,26,124,188,240,145,164, - 40,195,48,164,213,114,170,202,94,111,64,55,16,252,151,127,231,83,252,236, - 207,253,37,90,173,151,75,68,182,45,125,57,60,108,118,151,67,68,212,62, - 86,51,250,190,37,223,232,45,58,73,197,170,235,66,244,46,0,178,87,82, - 6,14,92,84,50,219,246,136,146,98,145,207,197,20,53,61,110,106,228,210, - 173,203,164,141,242,83,129,74,219,89,207,88,37,210,40,91,85,149,85,135, - 170,181,102,54,28,31,27,29,231,251,218,85,204,144,23,237,94,197,83,178, - 140,114,251,129,30,14,17,115,16,217,101,4,137,171,49,46,216,195,236,192, - 134,74,45,16,19,137,100,198,112,87,220,53,12,85,236,210,153,106,81,105, - 93,232,183,123,4,61,195,198,8,100,167,143,49,85,114,212,123,87,56,156, - 68,138,200,62,71,55,187,129,136,163,79,101,91,236,8,119,143,156,108,74, - 154,62,108,214,27,7,142,37,213,168,173,218,204,29,241,29,159,250,18,127, - 249,175,254,12,175,126,231,9,171,249,29,206,189,80,173,245,197,177,68,201, - 126,69,88,18,4,170,18,189,53,228,214,160,193,199,15,31,89,13,206,218, - 152,125,150,46,212,58,33,104,205,249,79,255,139,23,249,59,127,235,63,196, - 18,209,105,191,139,139,198,58,217,215,52,255,114,11,215,150,66,104,226,221, - 78,142,83,86,161,236,178,228,19,164,73,194,94,156,128,92,0,109,236,110, - 155,89,134,69,192,37,0,102,188,136,89,47,80,98,65,244,174,115,91,81, - 159,119,251,241,169,57,0,49,154,225,135,131,207,201,82,144,62,5,184,221, - 21,117,179,139,10,177,233,176,109,199,46,130,154,118,144,131,185,35,72,235, - 68,25,131,172,86,168,245,16,173,135,116,229,132,141,153,178,152,185,232,104, - 16,170,220,58,204,202,115,142,84,60,226,182,179,218,202,70,240,76,158,119, - 4,20,237,133,171,183,101,4,4,165,90,159,24,161,22,11,22,221,54,105, - 70,182,211,113,228,142,189,184,68,87,78,88,38,154,101,50,98,176,238,96, - 23,19,196,56,19,143,136,17,232,140,176,124,157,78,15,11,87,147,169,65, - 94,135,197,50,83,131,102,181,202,117,50,196,50,33,229,37,108,107,68,100, - 159,99,187,189,64,44,175,177,209,115,116,111,140,10,46,35,197,77,172,29, - 177,136,103,149,52,244,112,32,208,251,62,38,81,72,25,211,145,217,132,128, - 237,172,212,255,230,234,110,66,108,129,223,5,110,0,55,33,171,223,30,247, - 185,93,0,123,33,39,183,207,188,18,144,154,249,209,56,156,118,187,205,120, - 210,38,104,101,55,30,106,136,84,253,35,114,59,116,45,209,250,108,35,129, - 6,13,26,60,27,248,200,8,78,136,40,91,24,138,232,230,98,79,241,163, - 127,106,201,223,248,235,127,5,107,95,3,38,184,20,211,251,20,100,230,132, - 3,133,228,251,24,241,174,168,243,201,80,19,69,217,212,233,210,208,203,237, - 54,205,22,81,47,27,119,72,211,171,108,166,223,198,86,185,5,42,45,229, - 8,115,113,197,68,184,118,0,217,174,244,183,117,50,9,189,28,59,231,15, - 168,54,102,67,38,225,159,200,3,47,198,67,56,41,188,79,85,14,194,221, - 241,204,54,112,227,111,224,200,192,185,210,43,167,135,69,45,46,75,59,218, - 161,97,112,113,143,29,90,71,88,179,22,27,35,16,139,226,90,186,178,72, - 193,165,98,82,140,191,81,243,138,31,102,121,27,128,116,87,40,85,15,83, - 147,0,219,237,5,210,126,159,180,223,71,116,53,154,73,46,253,119,243,2, - 93,253,44,106,41,188,0,104,62,191,9,64,167,63,68,170,1,15,22,134, - 126,118,137,185,184,196,206,179,81,75,119,49,204,128,91,20,55,62,245,105, - 205,239,248,212,151,248,107,127,225,117,62,243,74,64,32,71,36,251,93,62, - 200,20,50,215,154,44,42,107,5,50,159,24,80,7,173,171,81,118,221,228, - 250,6,13,26,60,91,248,8,205,244,156,156,221,171,247,70,106,70,171,187, - 227,147,159,121,153,159,255,139,215,249,251,255,237,207,242,93,175,190,2,140, - 137,66,223,19,85,86,82,150,205,114,203,104,227,239,232,3,57,34,142,37, - 113,236,46,99,208,13,157,47,161,157,99,185,67,39,60,118,50,89,172,5, - 219,193,115,244,222,179,152,133,91,204,198,47,180,142,106,84,80,68,117,122, - 29,160,215,129,19,154,116,170,138,78,97,219,68,123,81,117,40,241,207,47, - 169,21,215,171,160,66,48,131,80,161,212,194,137,64,206,21,145,169,39,151, - 88,139,138,31,164,29,193,108,88,108,183,208,17,232,33,106,86,68,124,34, - 42,169,21,15,234,106,158,208,202,231,224,211,165,118,104,171,219,103,199,45, - 43,64,3,59,133,137,36,104,223,167,43,45,118,163,8,6,153,154,147,9, - 154,9,211,88,211,201,206,191,171,138,253,249,198,109,55,171,205,13,54,141, - 247,183,113,239,113,155,209,232,26,0,243,185,187,65,57,185,56,96,107,250, - 116,218,105,222,30,224,34,183,187,24,238,32,248,157,108,207,119,64,188,5, - 226,94,241,58,217,1,216,203,252,165,159,249,41,254,242,95,253,25,174,127, - 247,103,0,216,198,31,16,182,220,117,245,187,3,218,237,54,157,246,168,226, - 88,162,77,55,79,77,250,137,221,224,60,39,15,211,147,141,208,164,65,131, - 103,31,15,151,239,61,37,140,41,238,118,181,214,116,58,29,230,171,49,104, - 131,96,198,229,23,70,252,201,159,186,202,213,43,111,240,15,255,135,171,252, - 111,84,218,186,97,0,0,26,37,73,68,65,84,255,248,159,0,126,145,154, - 81,150,246,119,218,1,219,3,65,133,175,193,185,69,143,220,59,208,154,40, - 155,236,124,15,203,77,226,196,167,65,221,194,22,217,231,24,95,210,44,126, - 251,159,210,122,57,19,100,72,69,223,76,88,39,15,64,71,12,192,69,95, - 89,111,92,153,184,194,105,136,214,1,114,2,204,178,218,216,14,166,251,62, - 147,86,226,148,137,236,25,140,13,32,193,142,89,38,5,161,172,164,130,149, - 27,219,179,76,52,131,48,27,110,154,169,19,197,200,29,51,214,194,165,68, - 163,29,118,36,240,123,240,252,166,238,195,112,236,82,108,105,56,129,53,12, - 123,45,210,181,68,145,245,203,101,251,92,44,231,192,57,54,6,172,84,110, - 100,208,230,2,155,110,189,212,221,174,21,58,27,54,58,84,49,104,103,160, - 60,56,39,1,131,158,76,216,24,144,157,62,201,162,90,163,156,68,138,101, - 86,248,91,106,73,202,57,134,237,76,172,146,190,75,212,186,199,110,95,126, - 127,51,51,100,125,3,184,64,20,25,140,222,176,92,57,37,229,118,23,32, - 196,60,107,9,184,139,229,14,130,247,129,91,32,222,205,143,219,106,15,217, - 239,22,88,59,224,179,159,250,17,126,244,199,126,154,215,95,53,92,188,124, - 66,106,230,36,251,93,46,42,73,244,158,221,110,71,175,223,207,201,205,99, - 52,148,71,170,201,86,171,33,178,6,13,62,174,248,72,8,78,74,153,147, - 156,82,138,253,62,165,223,57,135,214,150,245,122,137,20,107,218,34,230,213, - 215,59,252,194,245,31,226,7,222,188,198,47,254,247,191,204,111,252,230,191, - 33,10,251,196,201,109,252,34,184,221,165,148,163,54,216,229,41,74,159,110, - 10,147,46,41,9,27,33,115,103,121,87,199,115,179,192,46,78,94,228,203, - 63,244,67,192,134,213,98,205,240,165,231,49,6,164,156,99,245,0,141,161, - 183,130,53,15,32,227,179,217,182,199,112,173,16,37,81,202,130,61,67,50, - 33,137,48,104,189,4,61,100,8,232,189,35,156,33,45,210,238,121,196,196, - 176,201,234,112,190,1,186,139,97,131,132,205,18,209,61,199,50,121,192,144, - 66,12,130,24,65,188,33,242,17,103,220,134,73,2,216,74,148,151,134,19, - 150,108,243,250,30,56,33,75,87,194,162,149,50,32,64,79,38,238,121,89, - 122,208,187,250,219,37,8,181,196,44,199,8,165,208,253,148,141,17,12,39, - 50,159,0,16,104,141,93,43,196,208,17,222,176,215,66,79,71,216,117,192, - 90,90,4,26,189,18,121,237,77,51,193,236,65,70,46,141,169,153,208,87, - 35,64,99,128,86,111,196,75,47,69,252,216,143,106,126,229,87,127,153,187, - 247,239,100,239,205,216,125,87,215,143,62,67,65,75,211,105,167,8,166,152, - 44,34,23,220,0,230,180,162,57,251,157,35,182,93,108,145,246,132,168,245, - 50,63,242,131,63,192,23,223,116,179,221,218,221,247,216,198,31,184,207,71, - 171,77,32,71,244,237,251,32,65,119,66,130,32,64,101,254,146,101,191,201, - 106,228,150,13,113,109,162,181,6,13,62,150,248,72,8,174,12,41,37,173, - 86,128,214,26,165,4,189,158,187,163,151,97,138,92,73,210,246,109,254,232, - 31,13,185,122,229,13,126,233,127,185,198,255,254,127,252,51,226,251,43,138, - 244,228,97,173,163,184,227,246,119,230,173,174,164,29,245,96,121,159,110,111, - 207,118,119,11,136,185,56,25,240,39,127,248,179,188,249,195,95,228,243,223, - 145,32,140,36,217,76,152,197,11,134,61,203,108,57,97,60,152,178,2,250, - 210,165,241,150,137,160,55,1,78,20,90,167,168,245,2,173,51,51,97,58, - 88,64,139,17,146,251,44,116,196,32,75,109,106,61,100,99,166,48,222,211, - 5,236,29,137,185,52,68,168,101,222,0,189,194,145,42,56,210,19,221,115, - 44,102,15,24,1,157,190,197,224,34,94,191,156,106,173,65,140,216,182,151, - 68,19,137,35,172,12,179,231,208,178,92,47,18,89,239,194,7,71,239,65, - 89,206,15,46,47,109,204,8,165,150,46,117,218,213,164,187,19,20,247,216, - 24,193,32,107,226,222,232,45,93,61,36,192,69,150,183,159,19,156,116,122, - 88,230,78,141,90,138,172,101,52,97,187,14,232,142,70,216,108,138,158,9, - 28,169,170,48,224,213,239,190,196,223,122,33,224,213,95,178,252,175,191,244, - 14,191,253,187,191,155,69,216,238,253,29,141,220,115,180,89,161,100,31,157, - 22,169,233,168,117,143,120,239,111,88,182,236,98,139,224,2,251,56,162,211, - 14,248,204,167,127,132,47,255,224,151,120,237,213,203,156,127,225,30,201,254, - 6,197,208,91,71,110,66,108,89,49,166,215,239,51,12,32,9,194,188,238, - 22,69,157,220,169,68,180,84,69,88,210,144,91,131,6,31,95,124,228,4, - 231,225,35,185,50,164,234,51,154,224,190,6,51,174,252,205,235,252,248,79, - 95,227,107,191,241,13,254,193,63,248,159,88,110,2,182,59,111,235,53,166, - 32,59,183,112,250,154,10,192,122,185,96,181,89,18,136,183,185,116,2,127, - 254,231,255,60,63,240,197,151,120,253,59,35,246,219,223,99,191,114,81,159, - 140,38,152,24,236,110,206,176,55,205,189,18,87,128,156,75,186,24,52,208, - 209,32,22,11,244,112,232,198,190,152,17,131,176,16,177,0,78,114,31,58, - 114,19,11,1,253,115,121,25,113,117,41,235,151,203,200,45,92,68,236,250, - 238,252,167,106,205,101,221,33,206,60,43,147,209,24,121,21,4,46,234,213, - 107,55,248,52,232,42,142,199,171,86,33,22,2,57,153,131,209,32,44,189, - 224,19,152,150,100,45,173,187,168,210,57,148,17,46,34,62,56,145,156,199, - 56,55,146,75,61,212,141,123,149,109,6,235,14,26,23,197,173,74,11,189, - 221,40,116,114,220,66,145,246,251,236,180,164,175,96,166,21,39,125,73,74, - 7,157,164,40,238,115,229,202,9,63,251,31,255,7,124,249,205,55,249,183, - 191,121,131,127,254,79,127,153,127,252,127,253,99,22,75,203,124,62,231,228, - 66,159,128,14,233,158,60,186,178,246,46,219,253,58,171,221,101,78,46,68, - 68,237,203,121,196,246,242,167,53,97,171,77,178,191,13,180,243,207,69,183, - 51,160,111,103,236,212,24,25,186,52,182,146,125,68,100,233,101,86,92,101, - 114,59,84,77,54,228,214,160,193,199,27,31,57,193,149,109,141,194,208,45, - 215,58,221,208,239,156,99,175,246,44,230,239,3,208,27,12,64,9,94,254, - 212,3,94,184,124,133,63,254,227,255,13,191,242,47,190,193,31,220,78,185, - 249,214,59,220,184,117,131,93,124,202,253,7,23,242,253,181,59,19,84,106, - 217,111,12,173,110,200,231,94,249,20,191,240,95,127,130,47,124,233,101,70, - 253,59,232,36,69,166,83,186,66,211,29,68,204,150,100,20,226,34,146,141, - 30,33,152,50,222,238,129,8,61,158,179,65,50,24,141,208,115,183,141,88, - 8,108,182,208,45,187,154,174,156,176,150,138,94,247,2,112,202,50,25,209, - 91,101,245,181,13,136,238,61,22,23,62,143,100,142,49,163,60,98,187,39, - 58,92,88,109,73,134,112,162,123,128,193,44,199,200,203,119,96,1,102,125, - 1,53,190,11,100,62,145,107,8,186,20,110,43,99,152,103,125,108,131,44, - 139,182,49,130,30,94,204,34,216,24,232,2,124,202,32,59,3,204,118,85, - 114,26,25,179,213,134,94,184,64,205,46,145,12,99,78,116,15,217,183,152, - 237,10,121,119,149,205,201,171,239,201,235,232,30,83,182,88,59,226,148,13, - 94,35,170,179,159,124,237,173,159,137,75,78,178,136,44,84,1,157,150,32, - 9,12,70,175,80,18,190,253,213,115,92,122,241,34,63,250,199,255,44,63, - 255,219,111,128,186,206,201,133,155,108,215,31,184,154,93,171,67,152,186,250, - 106,216,10,152,12,2,158,127,254,21,174,95,253,83,92,123,249,10,47,188, - 24,240,210,75,87,120,254,133,128,85,188,4,187,96,23,235,74,157,205,183, - 1,44,249,4,45,160,221,158,100,173,0,154,176,117,30,37,55,89,90,178, - 58,41,160,174,37,160,252,89,110,72,175,65,131,143,15,132,181,182,94,23, - 253,17,192,213,229,220,225,202,61,114,113,28,147,166,9,105,170,137,179,97, - 163,113,28,179,79,13,58,77,136,183,238,177,221,238,216,178,43,148,93,90, - 93,89,113,128,247,62,130,0,50,205,132,27,201,61,246,43,215,26,32,204, - 156,221,114,69,91,185,136,101,152,145,144,104,187,109,165,44,212,156,158,160, - 60,124,29,77,40,215,119,213,209,61,87,87,59,192,114,231,220,244,59,74, - 178,213,134,40,61,201,247,223,94,197,36,195,152,190,204,142,55,154,19,206, - 103,204,7,150,65,168,16,61,77,114,254,62,225,221,151,16,239,45,152,255, - 171,53,189,63,250,162,83,59,102,240,99,105,252,57,228,231,123,119,197,237, - 165,98,252,114,47,123,205,179,116,97,70,112,157,108,241,110,175,98,118,253, - 40,191,86,127,157,66,45,233,245,83,196,66,176,238,67,180,28,178,85,235, - 156,40,253,62,203,245,55,228,132,165,24,231,181,183,153,86,116,122,23,233, - 6,59,130,104,146,59,242,75,85,168,60,211,212,189,63,113,188,69,39,41, - 137,62,110,77,8,75,81,214,225,182,219,216,125,22,226,237,182,242,185,176, - 182,147,15,45,5,103,0,224,235,109,229,148,36,212,55,115,3,223,180,232, - 77,202,102,226,119,131,6,223,74,252,161,165,40,61,164,84,36,73,130,82, - 2,173,221,130,29,69,17,113,86,114,137,162,14,235,141,32,84,41,144,178, - 77,57,154,174,188,219,237,176,182,195,128,247,73,194,54,65,80,114,231,80, - 67,180,129,160,183,33,141,53,38,152,28,68,113,49,86,142,104,15,64,26, - 183,168,174,12,244,130,25,150,49,210,206,48,102,76,123,229,107,64,17,201, - 48,38,92,184,239,43,96,120,239,221,60,5,185,201,182,242,68,178,78,134, - 46,34,204,22,245,197,90,0,10,45,161,159,253,126,1,151,34,100,12,91, - 181,166,191,16,204,212,121,198,203,83,76,54,45,102,123,58,32,4,50,123, - 70,2,59,37,201,82,179,235,85,128,213,131,156,100,61,193,118,49,172,46, - 13,121,145,5,43,170,228,6,78,206,191,209,144,198,11,134,89,186,212,152, - 49,82,206,42,209,166,153,143,216,32,233,46,13,187,190,192,174,170,228,230, - 247,117,136,129,50,88,96,172,52,54,144,136,172,61,192,88,247,98,248,229, - 222,15,15,245,36,167,66,71,100,113,246,33,8,85,97,120,220,237,128,201, - 120,93,155,46,42,220,160,66,247,247,109,188,59,250,108,184,8,180,152,200, - 93,86,74,134,42,56,147,220,60,154,212,100,131,6,255,255,193,31,106,4, - 119,136,36,73,208,218,162,181,75,93,250,5,46,77,19,86,171,85,229,49, - 127,199,126,104,225,228,221,223,203,209,155,95,196,0,76,86,195,243,145,156, - 76,239,48,93,118,144,230,102,190,141,204,108,75,76,60,101,114,126,143,126, - 112,60,144,211,67,180,167,37,242,115,169,71,128,65,80,168,28,151,233,140, - 65,48,102,93,147,237,235,101,171,124,148,188,159,71,113,74,20,189,108,114, - 146,69,82,195,41,233,244,42,252,158,98,157,190,79,255,197,75,172,179,0, - 200,43,34,15,145,139,72,228,188,66,110,139,181,200,207,71,182,220,73,117, - 82,137,141,44,171,213,156,97,54,79,207,71,115,62,178,244,196,89,174,223, - 121,178,220,232,81,30,189,25,57,198,202,17,75,45,233,171,17,170,239,88, - 218,71,111,222,25,164,14,254,253,245,145,123,25,218,116,233,117,109,158,70, - 60,140,240,161,254,115,81,158,68,112,248,185,240,196,6,124,100,145,155,71, - 19,193,53,104,240,173,197,183,156,224,60,60,209,149,73,174,110,65,131,98, - 81,243,168,91,196,60,124,148,96,118,171,156,228,166,75,193,73,231,253,124, - 155,217,50,230,124,191,80,31,78,103,165,197,54,235,135,19,251,106,170,82, - 182,12,157,84,30,145,152,206,20,132,50,11,42,189,124,126,187,14,104,171, - 123,121,58,20,170,36,231,161,196,2,59,180,108,204,212,213,251,86,129,107, - 74,191,212,39,30,44,42,51,215,14,225,35,79,47,102,89,172,5,253,190, - 219,46,78,109,33,231,111,185,243,26,202,57,54,178,136,88,84,136,219,167, - 46,139,232,174,74,168,139,181,64,68,87,179,23,194,165,39,187,106,132,101, - 146,147,155,80,3,130,174,164,19,200,35,130,115,17,123,241,62,187,239,199, - 125,121,229,247,49,8,194,51,63,19,254,243,160,130,16,157,38,149,222,182, - 114,74,178,44,38,1,42,228,246,81,248,76,54,4,215,160,193,183,22,127, - 232,41,202,67,248,193,155,173,150,98,191,135,108,237,33,142,169,44,138,218, - 116,81,114,83,187,143,98,225,42,34,55,255,220,124,97,164,159,203,39,70, - 19,48,105,193,235,150,57,105,201,122,73,7,49,42,189,229,126,145,174,233, - 219,182,170,132,146,236,65,151,50,163,158,56,118,219,11,180,213,61,182,219, - 66,12,147,110,6,244,6,22,105,82,86,76,48,241,148,161,156,19,135,159, - 64,152,41,229,153,231,125,9,210,10,64,96,230,195,44,211,185,66,141,38, - 164,211,73,37,58,91,39,67,146,88,49,236,89,22,107,193,176,103,185,39, - 58,244,197,136,56,181,4,17,172,211,18,57,201,9,50,191,204,41,11,51, - 130,141,59,239,158,176,196,161,192,70,153,59,201,182,232,105,19,237,41,198, - 55,112,111,198,32,65,100,147,10,140,28,211,205,163,183,226,80,158,220,140, - 237,16,117,4,144,18,234,14,226,160,113,250,240,125,58,196,97,228,23,4, - 138,40,234,16,199,219,252,125,47,35,108,247,242,20,230,33,177,249,159,125, - 74,242,163,36,183,6,13,26,124,235,241,45,141,224,160,42,60,209,218,212, - 166,44,161,122,167,127,152,206,42,215,85,220,247,106,195,238,206,36,249,62, - 140,94,33,85,159,253,218,69,82,62,170,115,63,223,169,236,119,62,191,203, - 201,112,199,253,69,59,79,99,214,97,187,14,114,139,170,252,186,228,152,245, - 74,208,29,14,217,44,22,116,135,67,132,153,87,246,51,234,223,37,221,108, - 144,118,70,175,187,103,27,59,2,247,181,176,46,134,149,153,48,188,247,46, - 139,11,78,180,226,189,31,147,56,155,180,45,199,200,150,193,236,139,104,65, - 182,76,174,110,68,102,209,227,160,207,110,185,162,211,75,49,210,145,213,225, - 53,141,250,119,153,47,28,107,247,130,25,235,116,76,63,157,179,10,170,228, - 190,221,94,200,247,179,182,228,209,155,9,198,132,145,59,143,112,48,58,138, - 222,218,50,204,251,204,252,123,236,81,126,175,31,7,62,154,115,207,45,62, - 15,117,159,5,247,120,17,181,185,239,69,155,195,71,69,112,77,4,215,160, - 193,183,22,223,114,130,43,195,24,131,214,58,23,159,248,69,208,238,117,78, - 82,192,35,239,244,253,66,90,134,45,13,66,221,153,132,253,174,32,182,52, - 214,12,123,49,171,121,177,80,150,201,110,99,85,69,129,89,7,251,255,181, - 119,63,33,146,92,247,1,199,127,221,61,211,243,119,181,146,37,76,18,172, - 160,128,78,70,185,196,16,114,144,33,235,131,130,65,135,64,72,4,62,4, - 29,140,9,72,241,33,228,30,251,102,67,32,182,79,137,12,198,216,138,208, - 193,134,16,124,20,6,225,91,48,246,69,40,58,56,88,56,144,160,69,102, - 87,187,51,211,179,253,215,135,158,170,174,174,174,217,125,130,21,189,251,219, - 207,231,50,211,51,111,122,122,118,118,251,187,175,234,189,234,254,213,232,205, - 63,138,69,127,243,208,225,242,245,239,110,108,124,125,127,126,51,142,199,239, - 215,183,171,67,150,149,131,253,229,203,186,76,175,207,235,195,142,17,17,243, - 222,227,209,59,239,126,213,241,58,70,141,25,214,221,30,111,211,221,34,222, - 84,221,103,245,179,86,11,78,154,135,39,175,60,182,156,69,85,129,107,198, - 173,173,25,187,197,120,182,241,187,107,126,174,249,247,32,98,243,239,66,123, - 198,215,14,219,242,253,213,86,128,79,114,65,137,192,193,118,61,80,129,139, - 88,69,46,34,214,102,115,17,221,79,112,109,93,135,173,34,34,118,119,206, - 98,124,214,184,10,202,224,226,60,206,201,237,56,28,172,191,244,73,51,116, - 17,203,45,6,135,23,219,14,206,22,203,39,196,59,39,235,175,171,86,5, - 172,122,178,239,197,141,24,30,31,213,227,246,142,151,151,21,27,159,156,198, - 83,199,215,227,195,147,79,215,231,253,38,215,255,59,158,124,250,241,248,237, - 255,222,140,222,222,141,56,58,28,199,233,217,48,142,14,199,49,189,190,58, - 201,55,186,242,123,27,97,187,53,95,157,243,107,94,46,171,210,142,209,101, - 158,58,190,30,191,189,181,23,79,62,118,103,237,28,228,19,143,31,212,51, - 216,102,44,75,226,22,17,177,127,124,101,237,208,100,243,188,87,68,212,255, - 153,105,154,205,38,27,33,172,62,214,53,187,111,219,235,239,198,157,249,164, - 99,133,228,39,179,152,228,50,2,7,219,245,192,5,174,169,29,187,229,219, - 213,172,46,34,214,158,56,155,86,215,17,28,199,124,62,220,120,34,157,142, - 214,159,32,155,135,49,35,162,62,132,89,25,141,23,177,152,173,191,230,216, - 228,188,123,83,116,68,196,238,126,63,38,231,243,250,144,93,219,228,124,30, - 253,233,114,198,244,196,149,81,220,188,125,30,103,183,110,197,209,241,34,78, - 79,186,103,103,107,143,191,247,228,93,63,63,59,188,26,143,15,86,179,214, - 249,78,247,76,174,122,124,93,63,75,245,248,110,223,62,137,163,39,62,83, - 223,110,222,223,100,231,32,134,59,253,122,145,79,68,196,176,55,139,195,171, - 79,213,99,219,139,58,6,131,254,198,203,207,180,127,63,205,8,118,141,107, - 31,226,108,27,14,135,245,248,109,93,153,68,224,96,187,30,232,192,85,170, - 213,150,205,39,193,174,255,229,71,172,255,47,189,169,122,66,173,158,240,170, - 251,106,135,174,114,58,94,45,104,153,78,103,245,118,131,202,104,188,254,199, - 118,48,236,213,17,60,60,120,108,109,204,193,176,87,223,174,222,143,88,63, - 255,87,249,232,70,247,33,208,219,183,79,54,62,118,103,240,7,177,55,251, - 191,58,62,151,69,44,34,54,66,91,237,81,59,186,216,26,80,237,23,60, - 153,12,226,240,224,177,250,177,157,76,6,117,252,170,104,71,68,244,246,143, - 98,39,70,49,141,131,181,205,245,253,189,227,232,247,70,49,220,91,206,236, - 154,135,139,219,129,219,221,221,93,187,210,77,101,54,155,215,191,191,118,8, - 87,99,86,161,187,219,223,131,229,251,219,217,219,38,112,176,93,15,69,224, - 154,154,91,11,34,86,193,138,88,45,22,152,76,38,157,11,7,170,143,47, - 55,154,247,215,162,183,124,219,125,206,47,226,242,229,236,203,213,124,7,245, - 219,136,139,45,9,123,199,81,98,54,110,188,146,248,197,174,238,42,140,213, - 213,61,22,231,167,49,217,57,136,233,120,16,189,254,121,12,118,118,99,58, - 190,88,68,49,92,127,60,213,108,170,121,101,144,230,198,233,181,177,189,89, - 44,122,171,40,246,22,55,235,199,221,12,250,120,49,136,217,100,243,74,35, - 7,195,94,140,23,131,58,108,149,246,94,179,136,205,197,29,31,103,97,71, - 243,247,86,255,76,173,219,77,85,208,170,75,107,109,235,18,91,2,7,219, - 245,208,5,174,82,61,233,85,51,128,143,251,4,54,159,207,47,94,214,103, - 86,95,54,172,82,114,222,175,189,184,161,10,95,115,83,114,115,31,215,242, - 115,171,39,245,143,70,253,184,114,17,196,209,237,213,172,237,124,58,171,183, - 67,84,81,169,98,53,158,94,126,72,180,25,182,221,225,167,86,247,113,177, - 89,250,244,172,23,71,135,139,58,168,131,97,115,99,244,230,159,93,215,190, - 180,211,179,94,92,57,58,139,179,81,108,68,173,186,159,246,126,183,136,205, - 5,30,247,123,213,226,131,122,141,72,129,131,237,122,104,3,119,63,84,175, - 89,183,124,41,159,254,90,232,154,145,187,179,88,70,97,113,49,171,153,47, - 142,162,223,59,221,120,191,50,157,78,46,189,114,71,165,90,8,81,189,173, - 190,174,25,150,126,111,20,183,79,151,251,255,154,51,168,193,238,78,125,187, - 57,43,27,246,102,49,154,93,89,142,159,31,198,126,35,92,85,208,186,98, - 118,217,99,109,207,90,103,227,157,24,12,167,245,219,213,215,175,47,201,175, - 182,104,52,95,122,166,107,166,157,157,192,193,118,61,210,129,139,104,190,250, - 248,162,14,220,114,211,121,215,185,161,205,229,236,139,241,44,198,187,203,213, - 153,195,201,242,138,26,163,217,48,14,6,227,250,253,193,254,242,137,125,175, - 183,140,194,157,197,78,28,239,222,90,91,213,25,177,58,239,215,158,61,245, - 123,163,152,158,119,191,2,119,68,196,206,254,32,166,231,179,216,217,31,196, - 124,113,16,253,222,40,230,139,229,21,93,238,53,147,172,116,237,27,108,171, - 130,119,183,120,183,227,22,177,126,94,180,58,247,246,40,16,56,216,46,129, - 155,111,30,246,171,102,116,203,247,87,155,207,171,101,234,251,251,17,93,171, - 212,119,119,206,98,50,61,220,248,120,243,235,38,147,229,251,213,216,246,254, - 188,182,246,44,170,121,8,180,121,187,233,94,179,199,230,86,138,174,125,103, - 139,86,220,39,131,81,236,206,14,234,199,215,142,97,123,107,198,101,97,123, - 212,46,100,44,112,176,93,143,124,224,42,85,232,150,231,229,230,177,88,140, - 90,159,95,110,53,168,94,211,46,162,59,114,149,230,37,199,154,183,35,150, - 145,235,50,155,77,234,195,161,17,203,25,225,104,54,220,56,28,218,117,88, - 180,250,252,193,96,28,119,230,147,232,239,78,235,40,93,182,55,240,227,186, - 108,19,246,189,86,179,86,81,187,108,241,79,86,2,7,219,37,112,151,88, - 45,98,105,207,240,86,151,21,107,234,218,219,213,214,53,166,223,31,175,5, - 175,121,120,244,178,189,94,237,61,128,237,240,84,51,198,203,194,211,60,31, - 214,124,191,169,100,75,70,117,127,151,169,22,1,61,74,179,182,38,129,131, - 237,18,184,123,232,14,92,99,47,219,197,74,204,149,174,39,252,102,44,230, - 107,219,25,170,67,161,247,58,255,183,252,218,205,224,221,45,102,77,187,187, - 147,232,245,246,59,194,60,168,55,211,119,127,207,197,197,184,238,8,182,63, - 222,252,217,154,183,31,69,2,7,219,37,112,247,73,115,187,194,101,91,23, - 218,135,232,154,183,47,219,211,213,229,110,209,185,155,174,239,125,175,183,93, - 27,177,151,143,97,21,202,230,120,86,4,14,182,75,224,30,18,243,249,172, - 94,168,81,197,165,58,191,213,21,151,251,25,156,174,195,140,143,242,161,199, - 82,2,7,219,181,245,215,131,163,92,117,56,179,100,53,226,253,156,77,117, - 125,47,113,3,30,116,102,112,240,9,49,131,131,237,242,47,16,128,148,4, - 14,128,148,122,239,190,251,110,209,33,202,235,215,175,23,221,225,59,239,148, - 141,251,222,247,254,176,104,92,169,95,252,226,207,138,198,125,227,27,223,42, - 26,247,171,95,189,88,52,238,217,103,127,82,52,238,248,184,236,116,231,43, - 175,188,82,52,174,215,251,120,43,40,239,229,43,95,41,59,82,253,165,47, - 189,93,52,238,253,247,223,47,26,247,220,27,111,20,141,43,245,185,103,158, - 41,27,248,203,95,150,141,251,242,151,139,134,189,246,250,235,69,227,126,252, - 47,7,101,223,183,208,51,159,123,166,104,220,191,253,105,217,207,251,218,127, - 149,253,188,175,255,123,217,207,251,210,205,191,47,26,247,234,171,127,93,52, - 238,171,95,253,159,162,113,223,249,246,179,69,227,254,249,243,63,45,26,247, - 252,217,123,69,227,222,120,254,133,162,113,127,242,252,217,189,7,69,196,83, - 135,255,95,52,238,197,23,255,162,104,220,127,196,103,138,198,253,227,203,159, - 42,26,247,218,31,253,85,209,184,191,253,236,127,22,141,123,243,247,191,93, - 52,238,173,183,222,42,26,103,6,7,64,74,2,7,64,74,2,7,64,74, - 2,7,64,74,2,7,64,74,2,7,64,74,2,7,64,74,2,7,64,74, - 2,7,64,74,189,94,175,231,98,203,0,164,211,251,233,215,191,94,20,184, - 91,255,244,221,162,59,252,203,248,215,162,113,223,255,254,135,69,227,94,126, - 249,229,162,113,183,110,149,117,250,231,63,255,168,104,220,181,107,87,139,198, - 189,253,118,217,165,171,74,47,97,246,220,115,159,190,175,247,247,234,171,127, - 83,52,110,177,248,90,209,184,247,222,59,44,26,247,155,223,148,93,154,236, - 133,23,254,161,104,220,181,107,127,94,52,238,233,222,211,69,227,126,61,249, - 117,209,184,27,55,110,20,141,251,224,131,15,138,198,125,241,143,191,88,52, - 46,202,126,189,17,101,223,54,126,240,225,15,139,198,125,179,240,82,118,63, - 249,187,31,21,141,251,217,213,159,21,141,43,253,119,244,230,155,239,20,141, - 251,194,23,158,43,26,247,210,75,215,138,198,241,112,114,136,18,128,148,4, + 189,123,120,20,199,153,239,255,237,185,104,102,164,1,36,48,88,216,200,145, + 100,20,27,108,63,70,16,178,198,246,26,225,117,188,231,177,179,172,137,19, + 111,54,201,122,253,75,114,114,188,38,75,130,177,227,36,123,65,236,238,113, + 98,199,64,130,131,227,147,179,62,75,56,56,155,77,142,193,155,248,178,193, + 142,129,132,0,9,6,225,36,6,19,132,164,88,216,2,201,186,160,203,76, + 207,165,187,126,127,140,222,214,59,165,238,185,72,51,163,145,84,159,231,233, + 103,102,250,82,85,93,51,83,223,126,223,122,171,74,27,26,26,210,220,30, + 143,71,211,52,13,128,6,64,24,134,33,140,120,60,46,132,16,110,183,59, + 229,241,153,51,103,226,178,235,43,151,118,159,237,105,142,12,70,251,145,37, + 151,95,126,185,237,254,171,238,93,120,252,244,206,230,165,236,243,29,167,119, + 54,191,36,159,247,206,59,239,100,155,101,209,83,230,243,5,111,186,250,234, + 149,117,243,231,47,246,184,221,254,142,222,222,142,215,207,158,61,212,114,225, + 194,73,249,92,77,211,196,68,148,81,161,80,40,138,29,143,199,227,41,239, + 236,13,93,209,219,163,207,20,194,116,9,1,83,211,68,255,188,217,158,182, + 242,242,153,131,46,151,59,216,217,27,170,182,59,62,107,214,204,126,0,98, + 241,159,45,90,125,253,61,215,125,122,255,227,191,248,250,177,93,77,79,141, + 167,64,87,221,187,240,177,155,215,174,248,216,193,237,135,107,164,67,223,254, + 204,175,254,42,122,112,251,225,167,78,239,108,222,54,158,60,236,168,191,234, + 230,198,166,211,7,27,237,142,105,154,107,174,16,102,87,170,125,229,51,46, + 153,219,55,240,94,210,57,118,251,136,79,255,217,35,141,255,231,39,143,37, + 229,87,230,247,7,31,94,189,250,203,159,190,237,182,207,123,92,174,89,161, + 104,20,177,120,28,113,195,64,220,52,241,122,115,243,225,111,190,248,226,195, + 111,190,253,246,47,199,120,155,10,133,66,49,109,208,78,158,233,250,192,211, + 63,138,127,226,124,183,177,72,131,89,34,132,22,13,250,186,79,126,242,191, + 25,59,111,252,224,226,230,246,142,193,133,223,254,65,252,222,243,221,198,98, + 126,252,19,127,26,223,185,226,131,139,79,150,149,150,198,254,228,171,13,141, + 127,252,133,155,54,70,7,35,232,60,253,222,155,63,123,116,255,131,173,7, + 219,246,102,82,0,110,193,93,117,239,194,183,110,94,187,226,42,0,8,95, + 212,113,108,87,83,211,233,157,205,75,175,186,119,225,29,55,175,93,241,98, + 248,162,14,0,56,182,171,233,241,211,59,155,31,1,70,44,56,209,189,94, + 96,32,10,68,141,212,25,198,77,92,236,12,97,195,150,95,109,122,230,199, + 103,26,105,247,11,155,155,197,135,55,44,212,228,211,235,170,174,125,192,235, + 241,207,59,217,250,122,99,170,125,235,254,162,177,177,237,221,182,206,31,255, + 98,199,83,169,246,57,229,119,249,236,217,11,94,250,251,191,127,229,210,242, + 242,171,187,7,6,48,168,235,136,197,227,48,69,194,64,115,105,137,83,245, + 88,12,223,126,233,165,135,159,255,245,175,159,0,148,5,167,80,40,20,78, + 184,222,237,232,154,213,254,110,239,226,158,208,220,27,122,195,115,87,116,15, + 149,223,240,206,59,157,215,180,183,159,155,25,139,197,220,29,29,157,51,219, + 223,237,189,70,62,126,238,220,59,51,99,177,152,11,0,132,16,48,227,38, + 226,49,19,115,106,103,95,243,241,127,187,251,167,159,124,246,47,246,93,122, + 205,188,165,233,10,64,144,184,133,47,234,8,95,212,209,125,182,187,149,142, + 157,222,217,252,210,193,237,135,191,64,159,151,125,170,254,75,87,221,187,240, + 19,73,9,12,68,97,188,23,70,232,252,16,134,58,6,29,183,139,231,7, + 241,251,182,62,156,239,14,39,93,62,24,30,24,85,166,171,171,175,125,224, + 255,110,250,249,246,193,80,159,181,239,202,5,239,255,140,188,47,81,7,192, + 231,239,121,116,251,141,215,253,233,103,248,190,117,127,241,245,237,13,75,87, + 63,32,167,205,243,43,243,251,131,47,253,253,223,191,50,103,198,140,171,219, + 223,123,15,239,245,247,99,40,18,65,148,172,55,195,64,52,30,71,212,48, + 160,1,184,111,213,170,111,220,178,120,241,103,51,168,86,133,66,161,152,182, + 184,140,120,220,13,17,43,129,169,251,97,234,126,136,152,95,136,88,137,97, + 196,221,166,105,106,134,97,216,30,143,27,49,151,105,154,35,41,9,1,152, + 2,166,97,194,136,155,168,90,126,121,195,167,159,191,247,216,159,61,113,199, + 206,25,149,193,5,169,10,49,236,150,188,138,44,52,59,78,239,108,222,118, + 108,87,211,39,217,174,123,146,78,136,26,136,132,98,24,8,197,48,24,142, + 59,110,253,67,113,12,132,98,136,196,204,228,12,144,108,8,93,93,125,237, + 3,63,217,252,155,237,103,222,62,131,88,60,10,0,152,61,115,206,237,187, + 31,59,186,189,185,189,25,209,120,36,233,124,195,0,124,94,31,254,250,206, + 135,183,47,170,94,122,59,0,152,38,80,226,41,193,103,86,127,117,251,202, + 122,89,228,70,242,123,120,245,234,47,87,150,151,95,221,209,219,139,65,93, + 135,97,154,137,250,148,75,40,4,160,105,40,241,122,241,209,21,43,30,15, + 250,253,243,28,43,76,161,80,40,166,57,46,36,2,71,198,130,227,117,194, + 20,48,98,38,140,152,129,107,86,47,250,171,251,95,253,108,115,195,67,127, + 252,104,73,176,100,166,195,37,31,203,36,195,211,59,155,191,127,108,87,211, + 227,0,176,236,83,245,127,126,213,189,11,159,79,202,119,88,20,132,16,142, + 27,132,24,214,14,89,64,92,214,187,171,171,175,125,224,133,45,191,217,254, + 135,142,78,12,233,3,240,122,124,168,152,49,231,246,3,79,183,252,184,111, + 32,230,235,29,232,178,242,178,242,30,174,146,217,179,46,245,173,255,203,111, + 252,248,186,43,255,232,118,151,150,216,31,240,7,241,153,213,95,177,17,185, + 68,64,201,167,111,187,237,243,239,13,12,96,40,18,25,149,174,29,30,151, + 11,21,193,96,197,31,213,213,125,46,237,201,10,133,66,49,77,113,165,63, + 101,236,8,33,96,196,12,184,60,46,223,13,159,251,224,87,254,230,103,159, + 109,94,250,201,37,15,184,75,220,62,58,231,170,123,23,182,220,188,118,69, + 13,245,185,29,219,213,244,248,177,93,77,167,219,14,191,221,103,151,230,233, + 157,205,143,28,219,213,212,52,252,241,207,115,85,214,96,105,66,123,71,196, + 173,11,253,67,61,8,150,206,194,181,87,126,112,241,206,198,131,187,122,7, + 12,95,79,127,23,12,211,185,159,207,165,185,80,62,99,174,239,161,79,125, + 115,215,251,230,47,90,28,55,98,208,160,89,34,183,106,217,93,73,34,119, + 211,213,87,175,244,184,92,179,6,194,97,171,191,205,9,122,162,112,185,92, + 240,123,189,184,234,242,203,87,143,239,174,21,10,133,98,234,226,41,68,38, + 166,97,66,51,1,255,44,255,220,219,55,254,201,246,229,247,45,125,112,223, + 55,126,241,149,223,239,61,243,35,0,53,60,160,100,248,146,71,10,81,46, + 206,165,179,231,99,225,130,107,31,248,207,111,140,136,155,41,76,248,75,2, + 184,255,35,155,62,230,243,250,145,78,220,0,64,211,52,184,92,46,204,42, + 155,61,119,254,156,170,143,13,133,251,161,105,154,37,114,255,99,205,198,237, + 51,74,203,49,24,74,140,168,168,155,63,127,113,56,26,69,204,48,108,221, + 146,163,210,71,194,42,116,39,172,184,197,57,184,117,133,66,161,152,146,20, + 68,224,128,225,46,186,152,1,51,102,194,27,240,94,217,240,208,31,255,112, + 198,188,178,198,66,229,159,14,195,48,240,173,7,127,178,189,229,157,115,8, + 71,6,1,145,176,64,53,77,67,52,174,35,22,143,64,211,180,12,92,136, + 9,59,43,110,198,48,16,186,152,216,51,28,1,41,132,64,56,50,132,187, + 111,253,31,219,91,222,121,19,0,224,113,187,253,17,22,45,153,41,34,145, + 94,32,171,139,20,10,133,98,26,81,16,129,75,244,201,25,136,14,70,17, + 238,11,163,227,183,231,143,31,219,117,98,67,231,169,174,253,183,126,101,101, + 99,170,107,175,186,119,225,241,225,183,165,0,254,19,192,135,110,94,187,162, + 126,56,32,165,213,241,194,44,233,232,62,135,191,121,236,246,181,143,62,240, + 236,246,96,96,22,92,174,132,247,54,22,143,34,164,15,162,212,31,132,215, + 83,146,86,224,132,48,17,31,190,198,87,18,128,175,36,144,112,213,26,6, + 122,7,58,113,178,229,117,252,226,196,139,107,255,252,150,79,111,7,128,119, + 123,123,59,12,211,204,184,35,148,114,215,163,81,116,245,247,119,0,176,31, + 41,175,80,40,20,211,156,252,246,193,153,64,60,18,71,184,55,140,139,231, + 250,209,118,228,237,55,95,249,231,125,247,188,252,119,175,44,235,60,213,181, + 127,248,180,255,4,128,101,159,170,175,191,234,222,133,143,217,165,115,243,218, + 21,229,55,175,93,113,213,205,107,87,124,105,217,167,234,235,135,93,154,173, + 167,119,54,215,230,170,172,145,104,24,231,187,223,126,234,239,190,243,169,181, + 157,61,231,34,166,105,66,211,52,244,15,246,224,233,231,54,254,232,205,150, + 163,93,134,17,183,132,207,225,142,17,55,98,120,167,171,13,191,122,243,103, + 93,191,250,221,171,63,42,241,248,96,154,38,186,122,223,193,145,223,190,18, + 249,207,159,255,219,218,166,223,31,124,106,193,165,137,162,31,59,123,246,80, + 220,48,172,113,110,153,16,55,12,244,14,14,226,15,157,157,135,198,121,219, + 10,133,66,49,101,113,97,116,56,97,166,56,94,39,4,96,68,13,232,23, + 195,232,127,135,132,237,181,123,94,252,210,127,93,219,126,244,220,143,248,185, + 167,119,54,223,117,108,87,19,137,220,232,241,109,195,208,248,56,0,232,62, + 219,13,0,63,178,59,111,236,36,110,167,227,189,63,60,245,200,246,143,175, + 238,234,125,55,18,143,199,16,137,134,209,222,217,124,242,235,223,251,124,195, + 153,183,127,211,21,143,199,29,83,136,197,99,56,215,217,130,95,188,241,82, + 215,247,127,250,205,134,193,112,255,73,159,55,128,11,61,237,56,252,219,189, + 145,159,28,252,222,234,63,156,255,253,83,0,80,234,159,1,0,104,185,112, + 225,228,235,205,205,135,1,0,154,150,112,61,166,40,161,16,2,253,225,48, + 222,233,233,193,239,218,219,159,201,217,237,43,20,10,197,20,195,5,192,16, + 2,81,195,52,116,211,20,186,105,24,186,16,136,2,48,144,104,83,109,143, + 107,208,228,129,100,9,87,92,212,128,222,23,198,197,119,250,241,206,137,119, + 219,15,108,61,184,214,78,216,36,126,72,111,150,125,170,254,217,171,238,93, + 184,206,233,196,238,179,221,104,59,252,246,105,154,201,196,34,110,34,110,152, + 136,198,76,196,82,109,70,226,188,84,12,133,251,247,126,233,219,31,91,253, + 135,243,167,251,13,211,128,16,2,113,35,118,178,241,95,63,211,208,124,238, + 55,93,118,193,32,166,105,162,227,189,63,224,224,27,47,117,189,114,228,63, + 26,6,66,23,79,122,220,94,116,245,189,139,131,39,94,234,127,249,240,191, + 175,238,190,120,193,154,221,133,91,108,223,122,241,197,135,245,88,12,124,92, + 33,207,129,68,79,8,129,65,93,71,91,103,39,154,90,90,94,121,183,167, + 231,167,41,111,68,161,80,40,166,49,30,183,203,184,232,119,189,119,242,226, + 197,223,11,19,102,9,4,162,129,160,113,178,196,27,236,143,197,98,6,16, + 239,247,187,186,223,116,56,158,104,145,5,96,196,77,68,250,35,8,245,132, + 208,221,218,211,254,219,221,39,191,222,242,243,214,103,204,184,25,73,83,6, + 156,222,217,252,125,0,215,47,251,84,253,151,0,96,217,167,234,191,5,160, + 153,38,87,14,95,212,107,128,36,113,187,90,78,227,98,103,8,191,127,187, + 31,3,161,88,202,96,196,184,33,240,110,87,24,241,184,144,246,39,91,102, + 67,225,129,189,127,247,157,191,90,241,133,143,63,182,95,211,92,195,231,196, + 78,54,254,239,207,52,124,241,227,143,91,251,172,243,245,65,28,254,237,79, + 187,246,30,249,97,195,144,62,112,18,0,66,145,65,28,250,205,127,117,189, + 112,240,255,54,12,233,253,73,19,37,243,252,126,247,246,219,191,252,246,75, + 47,61,124,223,170,85,223,40,241,120,224,241,120,224,26,182,230,128,225,7, + 7,211,68,127,56,140,182,206,78,28,59,123,246,236,254,55,223,188,215,249, + 46,21,10,133,66,225,153,59,187,228,236,93,183,196,191,119,254,194,192,76, + 195,48,92,154,230,50,103,206,156,209,127,197,229,179,218,76,211,212,231,205, + 246,181,221,117,75,124,167,221,113,97,154,113,0,136,71,12,12,156,31,68, + 231,233,247,250,155,254,253,68,227,153,159,157,125,42,19,97,227,12,91,100, + 239,84,175,184,226,129,182,195,111,151,144,184,13,15,29,16,213,43,174,104, + 109,59,252,246,143,70,89,110,195,60,184,229,87,155,206,119,135,17,141,153, + 72,231,117,141,197,5,90,223,29,216,207,247,93,232,57,55,234,188,184,17, + 59,249,205,31,124,169,161,60,56,167,129,239,219,250,131,135,147,246,1,192, + 31,58,126,223,249,187,150,95,37,9,153,221,62,167,252,158,255,245,175,159, + 232,25,28,236,251,216,138,21,143,87,4,131,21,126,175,23,110,151,11,38, + 128,72,52,138,158,161,33,188,219,221,141,227,45,45,175,236,127,243,205,123, + 245,88,236,124,202,155,84,40,20,138,105,142,214,221,221,173,233,145,136,71, + 215,117,205,48,12,77,211,52,225,241,120,68,192,239,143,151,148,148,8,33, + 68,202,227,179,103,207,198,210,79,92,191,94,0,51,127,187,251,205,173,113, + 61,158,213,146,57,118,203,229,200,75,227,200,75,231,112,166,218,114,57,65, + 191,127,222,31,213,213,125,238,170,203,47,95,93,17,12,46,22,66,4,222, + 235,239,239,104,235,236,60,244,187,246,246,103,100,183,164,154,108,89,161,80, + 40,236,209,54,111,222,172,105,154,230,1,91,239,13,66,8,33,68,28,9, + 83,40,229,241,150,150,22,248,103,250,150,70,135,98,205,166,97,102,189,30, + 220,243,207,63,111,187,127,195,214,245,199,55,175,223,186,148,125,190,99,243, + 250,173,163,214,131,251,248,199,63,158,109,150,73,108,222,188,121,92,215,175, + 93,187,118,92,215,219,225,118,185,130,179,131,193,149,101,62,223,98,77,211, + 252,145,88,172,163,47,20,58,20,138,68,70,89,130,79,61,245,148,18,56, + 133,66,161,176,193,163,105,90,121,44,110,94,97,196,205,153,34,17,116,98, + 2,162,223,235,209,218,60,30,207,32,128,96,44,110,86,59,28,239,7,32, + 130,151,6,87,207,156,63,243,211,221,103,123,190,126,241,157,139,227,90,15, + 110,195,214,245,143,33,49,55,229,168,245,224,54,108,93,31,5,240,212,230, + 245,91,115,190,30,220,109,171,254,180,241,213,125,63,109,180,59,22,8,4, + 230,134,195,225,174,84,251,188,158,146,185,177,120,52,233,28,187,125,68,213, + 165,87,54,182,95,56,155,148,159,219,229,10,94,89,89,249,229,170,75,46, + 249,188,6,204,50,132,128,48,77,43,192,164,111,104,232,112,107,103,231,195, + 3,225,176,90,15,78,161,80,40,210,224,209,35,198,149,239,245,137,79,68, + 227,98,17,128,18,0,81,183,43,126,114,206,12,236,12,6,61,205,145,168, + 81,221,213,43,238,141,198,197,98,126,124,246,12,177,51,24,244,156,4,16, + 131,0,60,62,79,213,220,171,230,108,159,117,249,204,7,222,107,126,239,193, + 80,79,56,163,245,224,56,27,182,174,127,11,192,85,236,243,241,205,235,183, + 46,221,176,117,253,29,24,17,188,111,109,216,186,254,242,205,235,183,38,245, + 197,125,248,79,107,5,226,38,96,166,49,104,4,16,143,26,56,217,210,187, + 233,237,243,67,141,180,251,175,62,250,223,55,218,9,220,31,45,95,241,64, + 89,89,112,222,107,251,95,105,76,181,111,193,188,234,181,33,61,220,121,161, + 167,253,169,84,251,136,249,115,174,216,200,5,206,239,245,46,248,96,93,221, + 43,62,175,247,234,104,60,14,195,52,19,179,155,80,196,140,166,33,24,8, + 172,184,166,170,234,96,91,103,231,195,231,251,250,158,72,125,163,10,133,66, + 49,189,113,197,226,177,89,122,44,190,56,106,122,111,136,154,222,21,17,195, + 115,131,30,137,95,19,139,197,102,10,33,220,177,88,108,166,30,139,95,35, + 31,143,199,226,51,133,105,90,161,132,66,8,8,19,240,150,122,175,185,236, + 250,249,63,189,188,254,178,125,190,25,37,25,175,7,39,139,27,216,44,37, + 195,174,201,47,176,99,95,218,176,117,125,242,120,185,184,9,17,53,97,68, + 140,148,91,60,18,199,80,40,134,72,52,121,168,64,220,24,61,199,228,138, + 15,174,120,224,139,255,253,43,219,227,70,204,218,247,129,165,203,63,35,239, + 3,18,190,220,234,203,174,218,94,49,99,238,103,248,190,154,203,174,222,62, + 103,214,165,163,86,17,224,249,185,93,174,224,7,235,234,94,41,241,120,174, + 14,71,163,32,129,19,166,57,178,18,194,240,123,0,88,48,103,206,55,102, + 7,131,106,61,56,133,66,161,72,129,11,2,110,8,81,2,97,250,33,76, + 63,32,252,2,162,68,64,184,133,16,26,224,120,220,126,74,143,225,229,104, + 2,229,254,134,170,15,44,56,118,233,226,121,59,61,62,119,202,245,224,134, + 221,146,87,165,58,103,216,45,233,188,30,220,240,90,116,113,67,100,176,153, + 48,71,89,122,201,159,87,124,112,197,3,27,238,255,199,237,131,225,33,136, + 225,115,175,172,185,242,246,7,239,255,187,237,67,225,33,8,51,89,32,133, + 0,92,154,27,85,151,94,185,61,24,152,117,59,37,233,210,92,168,186,180, + 206,70,228,70,242,187,178,178,242,203,62,175,247,106,61,22,27,89,11,206, + 105,61,56,36,86,19,152,95,81,241,184,219,229,82,235,193,41,20,10,133, + 3,121,89,15,14,66,64,152,9,161,155,113,105,240,175,222,119,195,21,205, + 115,106,103,63,234,114,187,198,181,30,220,230,245,91,191,15,224,241,225,143, + 127,190,97,235,122,251,8,149,145,161,209,163,55,225,52,136,96,228,118,86, + 124,112,197,3,27,254,230,31,183,135,35,17,24,102,28,154,203,133,218,154, + 43,111,255,151,175,108,254,177,105,106,190,88,60,234,56,16,193,235,241,249, + 106,47,95,244,227,25,165,229,183,83,73,220,46,55,170,46,93,104,107,201, + 185,93,174,96,213,37,151,124,158,172,182,76,87,20,240,122,60,21,21,101, + 101,106,61,56,133,66,161,112,32,175,115,81,146,208,65,211,124,21,239,43, + 255,202,251,86,84,53,207,186,124,230,3,154,75,179,214,131,219,176,117,125, + 11,70,250,215,154,144,16,176,211,0,108,215,131,27,238,123,203,249,122,112, + 30,119,98,222,105,75,220,244,8,226,70,12,30,183,7,239,91,80,179,248, + 225,181,27,119,153,194,53,44,110,169,69,200,235,41,241,93,185,224,154,93, + 165,254,224,98,33,18,150,158,219,229,25,22,185,202,36,145,155,29,12,174, + 212,128,89,134,141,139,84,134,36,88,211,52,184,53,13,101,126,191,90,15, + 78,161,80,40,28,40,204,114,57,34,33,9,46,143,123,238,220,247,95,178, + 189,188,106,214,131,239,157,237,249,202,80,215,208,143,192,196,141,13,11,40, + 248,122,112,37,37,126,252,209,242,132,91,146,196,77,8,1,151,230,198,159, + 220,124,199,199,92,154,27,209,88,52,237,106,2,137,37,117,0,143,187,100, + 174,207,27,248,152,97,198,173,101,118,220,46,15,222,87,249,254,237,30,183, + 215,154,201,164,204,231,91,108,10,1,19,200,106,61,56,77,211,80,226,241, + 168,245,224,20,10,133,194,129,130,173,7,151,112,13,10,8,67,64,115,185, + 174,156,83,59,251,135,158,18,119,99,193,242,79,135,16,120,224,190,135,182, + 15,233,97,152,166,145,228,199,52,77,19,38,76,107,93,183,204,146,27,153, + 243,114,228,58,1,195,140,99,254,37,87,108,15,233,3,116,204,111,178,0, + 146,140,211,79,108,106,61,56,133,66,161,112,160,48,235,193,1,86,16,136, + 17,51,17,25,208,143,247,157,235,223,16,29,140,238,191,100,225,156,198,84, + 215,110,216,186,126,212,122,112,0,234,135,247,229,108,61,56,61,26,198,246, + 255,243,248,218,207,221,251,197,237,9,119,37,45,82,106,194,48,13,184,93, + 110,100,178,248,66,34,234,49,113,141,203,229,130,75,115,39,246,65,32,22, + 143,98,48,212,135,158,139,157,107,47,157,83,181,29,0,244,88,172,67,96, + 196,50,75,7,157,99,154,38,162,177,152,90,15,78,161,80,40,28,200,239, + 122,112,72,44,118,106,198,12,196,244,56,66,189,225,55,223,59,243,222,61, + 157,111,189,183,44,58,24,221,63,124,218,127,14,191,214,15,71,83,218,81, + 142,68,148,229,151,192,196,109,243,250,173,57,91,15,206,52,77,188,126,252, + 232,83,223,221,249,173,181,161,112,40,66,82,18,55,98,248,217,47,94,250, + 81,103,207,249,174,132,163,53,181,21,39,32,160,71,195,232,27,120,175,171, + 111,224,189,31,37,214,143,19,136,70,117,244,245,119,69,206,119,183,175,189, + 56,212,243,148,223,87,10,0,184,24,10,29,18,66,0,89,89,135,2,49, + 195,64,56,26,85,235,193,41,20,10,133,3,249,89,15,14,137,70,216,140, + 153,201,194,118,170,235,218,112,159,158,180,108,206,230,245,91,239,194,136,200, + 141,30,223,230,76,94,214,131,123,253,248,175,159,218,252,212,63,173,14,235, + 161,72,98,22,127,3,239,158,111,63,249,196,182,127,110,232,238,238,236,74, + 229,74,20,194,132,30,9,161,167,191,179,235,157,174,150,134,184,17,63,233, + 210,220,136,68,117,244,14,116,69,46,244,156,91,29,142,12,61,5,36,130, + 78,0,32,20,137,156,236,27,26,202,120,61,56,32,49,134,78,143,70,49, + 16,14,171,245,224,20,10,133,194,1,23,18,235,190,69,5,160,3,208,33, + 132,14,105,61,56,135,227,163,23,85,27,30,148,76,194,166,247,235,237,61, + 173,61,107,237,132,77,226,135,236,253,179,27,182,174,119,92,15,110,152,211, + 242,76,38,16,228,30,76,12,56,119,218,204,225,113,122,169,104,109,107,221, + 251,196,246,127,90,125,113,160,167,159,2,100,186,123,186,79,62,246,100,99, + 67,119,111,167,237,212,91,16,9,203,173,167,191,179,171,171,247,221,134,184, + 17,63,169,105,26,162,49,29,61,253,157,253,157,189,239,174,142,198,35,214, + 236,46,220,94,107,237,236,124,88,238,135,179,91,15,14,0,226,166,137,80, + 52,138,139,161,208,43,122,44,166,214,131,83,40,20,10,7,92,128,184,232, + 210,226,39,17,31,56,34,226,253,135,17,31,56,226,118,153,111,106,154,214, + 47,132,48,0,209,239,210,226,111,58,28,103,43,116,10,152,113,19,113,18, + 182,150,158,181,231,223,188,80,55,244,94,40,237,220,148,210,248,54,32,49, + 29,215,29,236,51,159,151,242,244,230,245,91,71,173,7,23,143,26,24,10, + 199,49,20,142,97,80,119,222,134,244,56,244,168,145,152,6,139,33,91,102, + 173,109,173,123,255,231,230,191,95,209,115,177,187,139,196,168,187,187,251,228, + 99,219,26,27,122,250,222,235,146,29,138,113,211,64,239,64,87,87,87,239, + 187,13,134,25,63,9,0,134,105,160,103,160,171,235,66,207,185,21,49,38, + 110,114,126,3,225,240,47,219,58,59,31,142,27,137,114,89,235,192,97,68, + 216,132,16,136,197,227,24,210,117,92,28,26,58,219,61,48,160,214,131,83, + 40,20,138,20,120,60,30,237,236,236,32,190,23,139,27,51,33,224,130,6, + 211,237,114,245,123,61,174,54,0,186,199,173,181,205,14,98,167,221,241,225, + 21,5,96,154,2,241,72,28,145,161,104,127,255,59,253,141,131,239,13,61, + 5,129,172,214,131,219,188,126,235,35,27,182,174,127,7,192,3,0,74,104, + 229,128,225,185,40,5,18,1,37,63,26,101,185,13,115,178,165,119,147,30, + 53,173,89,71,82,97,10,129,144,110,236,231,251,34,49,125,212,121,221,61, + 221,39,183,110,255,90,195,251,222,87,211,96,237,235,30,189,15,0,194,250, + 80,231,64,168,215,18,55,167,125,78,249,157,239,235,123,34,26,143,247,93, + 86,81,241,184,215,227,169,112,105,90,98,120,1,18,253,131,177,97,183,228, + 197,80,232,149,238,129,129,123,77,33,212,122,112,10,133,66,145,2,79,137, + 215,219,231,245,120,6,77,211,167,9,33,52,104,154,208,52,77,184,52,45, + 174,105,154,240,122,189,253,30,143,231,164,221,113,151,203,37,0,192,136,196, + 47,246,180,246,54,246,119,12,108,21,166,200,122,201,28,98,120,58,174,109, + 146,245,6,36,143,145,179,133,79,156,60,22,214,62,244,255,217,70,121,116, + 247,116,159,236,238,233,62,153,110,95,79,255,133,81,150,170,221,62,226,100, + 235,235,163,242,235,25,28,252,215,139,161,208,143,43,202,202,62,87,230,247, + 175,46,241,120,22,11,32,16,141,197,58,194,209,232,161,129,112,248,25,229, + 150,84,40,20,138,204,208,94,127,253,245,180,38,15,185,211,104,60,87,34, + 50,48,241,234,241,36,150,138,115,185,92,214,171,236,238,19,66,192,52,77, + 24,134,1,77,211,96,24,6,76,54,145,176,41,205,235,152,205,120,51,59, + 104,86,16,183,219,109,91,14,254,106,24,70,82,121,228,178,80,121,92,46, + 23,220,110,183,245,158,54,126,239,66,8,171,110,228,124,199,115,95,197,92, + 255,215,95,127,61,180,97,107,19,24,30,51,104,154,86,125,240,244,120,57, + 51,133,202,250,181,175,125,13,175,188,242,10,74,75,75,97,24,134,245,221, + 166,122,79,247,30,143,39,6,213,187,221,137,33,27,154,166,193,235,245,38, + 93,227,118,187,17,12,6,113,211,77,55,97,237,218,181,214,61,229,251,190, + 52,77,195,239,126,251,70,198,215,41,242,143,166,105,88,82,191,44,229,57, + 39,154,142,97,217,210,15,104,64,98,253,48,167,243,92,195,221,237,66,45, + 76,60,33,100,60,14,142,55,236,110,183,27,30,143,199,122,229,141,63,199, + 10,250,96,13,44,53,56,36,46,212,112,140,101,176,179,12,229,67,101,229, + 240,124,226,241,184,181,69,163,81,24,134,129,120,60,110,137,29,221,175,211, + 125,123,189,222,164,58,112,187,221,214,57,148,63,175,11,106,20,169,113,29, + 11,197,90,255,145,72,4,111,189,245,214,152,238,41,91,86,173,90,133,187, + 238,186,43,239,249,8,33,16,141,70,113,250,244,233,164,135,9,142,252,240, + 4,36,255,102,232,251,162,135,7,94,207,244,89,8,129,183,223,126,27,87, + 84,169,161,140,197,68,38,226,118,244,232,81,0,9,113,75,245,191,209,52, + 77,184,210,141,45,82,228,141,140,4,142,26,80,183,219,13,175,215,11,175, + 215,155,212,208,203,79,175,220,42,160,70,149,26,126,249,149,172,10,122,207, + 127,44,118,98,225,4,53,24,114,89,100,97,139,70,163,136,197,98,136,68, + 34,136,68,34,136,197,98,136,197,98,86,99,15,216,139,27,175,3,143,199, + 3,143,199,131,146,146,146,81,117,193,173,40,94,118,122,29,139,53,87,204, + 245,79,150,208,84,195,235,245,90,245,106,39,92,132,203,229,66,73,73,137, + 245,16,67,117,70,184,221,110,152,166,105,189,114,203,205,52,77,28,57,114, + 4,87,84,221,93,240,251,83,100,198,137,166,99,73,159,231,206,171,28,37, + 110,7,14,156,118,188,126,243,230,31,99,195,134,213,66,41,220,196,224,40, + 112,212,64,147,27,140,26,116,218,236,26,0,254,231,165,52,228,244,228,198, + 146,196,128,26,13,217,154,224,105,56,53,180,100,165,200,79,213,178,176,69, + 163,81,232,186,142,112,56,140,112,56,156,36,108,116,61,221,147,147,112,144, + 8,208,102,24,6,188,94,47,76,211,180,132,135,238,139,223,119,186,123,152, + 172,245,111,231,146,205,23,153,76,72,157,11,184,123,146,223,51,125,23,252, + 161,135,62,115,247,37,149,147,30,50,60,30,15,76,211,180,174,33,79,129, + 166,105,232,236,236,44,200,61,77,87,232,127,111,154,2,145,72,4,209,88, + 20,166,105,38,222,71,34,152,63,255,50,204,154,53,211,246,119,44,139,27, + 0,116,117,170,216,174,201,196,40,129,227,22,6,185,193,74,74,74,224,243, + 249,224,243,249,172,198,149,254,252,220,213,197,251,179,184,229,0,140,252,217, + 185,56,216,229,75,240,244,169,113,118,114,241,81,227,33,239,35,55,36,89, + 107,67,67,67,8,133,66,8,135,195,73,98,32,91,70,114,35,70,229,145, + 203,200,197,142,247,105,149,148,148,88,239,185,53,151,9,147,173,254,237,250, + 44,243,133,157,91,48,31,200,238,100,250,46,120,127,39,119,15,3,201,66, + 239,241,120,146,92,193,244,240,36,255,78,237,126,183,138,204,73,39,94,220, + 98,166,254,87,249,189,223,239,67,32,16,64,36,146,85,208,183,45,43,87, + 142,44,105,153,202,170,83,20,142,36,129,147,27,87,143,199,3,159,207,7, + 191,223,15,191,223,143,146,146,18,203,178,161,134,149,68,36,22,139,37,245, + 99,241,254,6,59,40,47,110,49,200,215,240,134,216,73,36,184,139,141,224, + 226,166,235,58,134,134,134,48,56,56,136,80,40,4,93,215,173,60,188,94, + 175,37,28,92,60,200,29,72,13,42,47,131,92,86,254,228,30,143,199,225, + 114,185,16,141,70,173,116,248,189,200,214,160,93,159,217,100,171,255,241,6, + 4,21,43,92,220,232,193,135,196,205,206,122,150,175,1,18,130,76,223,9, + 183,172,121,32,80,89,89,89,33,111,107,210,144,240,176,36,130,131,66,161, + 16,98,241,152,245,62,30,139,37,61,216,57,137,23,253,135,75,134,255,67, + 244,159,242,251,252,195,199,92,88,184,112,33,92,46,23,218,219,219,199,93, + 230,45,91,126,98,189,95,182,236,253,227,78,79,49,126,70,89,112,188,113, + 165,134,53,16,8,192,231,243,89,127,106,106,88,163,209,168,213,143,69,193, + 26,233,26,87,178,152,232,189,44,30,220,18,2,146,159,140,157,250,175,228, + 167,98,106,240,195,225,48,134,134,134,48,48,48,128,193,193,65,196,134,255, + 24,116,111,165,165,165,40,45,45,181,4,142,44,38,217,53,201,221,119,188, + 156,116,191,220,205,201,35,56,101,235,77,182,10,236,68,99,188,245,47,7, + 51,112,40,191,92,215,127,161,40,164,139,146,94,185,165,198,251,219,156,2, + 137,228,125,244,155,138,70,163,73,214,190,157,69,55,29,32,143,138,49,188, + 210,134,147,120,197,98,137,125,94,175,215,241,125,58,241,242,251,253,105,173, + 254,92,214,191,18,181,226,35,73,224,184,251,133,26,86,222,184,146,149,18, + 137,68,160,235,58,116,93,71,52,26,181,4,69,14,63,151,211,37,87,13, + 53,84,92,72,248,159,159,7,123,240,247,118,141,8,255,1,147,232,144,229, + 54,56,56,136,254,254,126,12,14,14,34,30,79,172,203,230,243,249,80,86, + 86,134,96,48,136,178,178,178,36,203,141,238,157,242,227,200,209,111,114,20, + 34,119,71,1,201,150,165,44,18,242,147,254,120,235,159,238,217,174,238,121, + 221,81,131,202,93,112,227,173,127,57,175,124,82,72,23,37,128,36,55,53, + 89,207,0,70,9,156,44,118,178,213,75,86,32,53,206,212,103,199,189,4, + 83,1,46,94,134,97,64,143,232,73,158,20,99,248,55,106,24,134,245,59, + 119,18,175,146,146,18,120,188,94,148,150,38,38,37,247,122,216,123,175,7, + 129,64,241,173,20,165,92,148,197,71,146,192,209,31,217,231,75,248,165,201, + 186,161,63,100,60,30,183,2,52,116,93,183,172,7,222,184,218,69,222,201, + 174,46,202,203,238,9,150,174,35,65,162,70,159,247,133,57,97,154,166,101, + 185,13,12,12,224,226,197,139,24,26,26,66,44,22,131,203,229,66,32,16, + 192,140,25,51,48,115,230,76,4,2,1,203,237,103,215,151,34,55,220,178, + 53,198,159,194,229,40,57,126,175,84,39,153,148,63,219,250,231,86,179,252, + 64,145,42,32,132,247,199,201,125,139,227,169,255,169,6,245,127,210,195,15, + 144,90,220,228,223,60,127,152,160,6,157,190,43,58,55,24,12,22,248,174, + 198,70,38,253,93,92,188,200,211,32,191,39,139,184,100,216,107,2,76,14, + 241,202,4,229,162,44,62,60,114,191,143,215,235,77,234,243,161,167,248,104, + 52,106,53,174,161,80,200,18,55,110,181,17,118,79,245,20,93,200,27,85, + 158,183,157,40,82,67,204,195,228,169,177,144,33,43,134,130,73,6,6,6, + 48,52,52,132,120,60,14,183,219,141,210,210,82,204,156,57,19,51,103,206, + 76,178,220,236,26,111,167,96,10,110,197,240,232,67,222,231,66,66,231,132, + 44,40,99,169,255,112,56,108,137,155,147,176,57,185,113,101,241,229,101,26, + 75,253,23,82,240,10,229,162,228,222,6,122,248,145,173,113,121,64,125,170, + 190,56,170,95,30,77,201,163,42,39,154,92,4,107,144,75,158,139,151,203, + 229,130,223,231,31,126,64,208,172,8,224,169,130,11,208,52,77,19,66,36, + 134,10,200,162,118,236,216,239,177,97,195,106,184,0,77,140,125,213,22,197, + 56,240,0,201,141,43,15,186,160,63,31,53,174,67,67,67,24,26,26,178, + 196,141,7,93,16,169,44,7,126,156,26,84,59,139,143,26,146,88,44,150, + 52,102,136,26,29,185,49,166,63,32,13,3,8,133,66,150,184,105,154,134, + 210,210,82,204,154,53,11,179,102,205,66,89,89,25,2,129,192,168,134,139, + 144,27,125,142,157,112,115,113,166,198,95,174,19,126,158,93,208,70,54,245, + 31,10,133,172,7,11,217,138,176,187,31,170,127,158,55,119,101,114,161,227, + 238,200,76,235,191,144,2,71,51,146,228,27,178,180,248,32,126,185,126,237, + 126,179,28,254,208,64,175,20,160,66,238,108,39,75,59,151,56,5,107,100, + 43,94,185,232,239,154,138,144,200,245,247,247,227,248,241,119,173,253,92,220, + 38,176,120,211,30,75,224,228,112,116,122,66,229,193,26,67,67,67,208,117, + 221,106,248,128,228,70,209,9,238,222,179,11,84,176,179,66,120,163,204,251, + 133,104,28,17,89,132,84,6,178,222,72,220,200,45,233,247,251,81,94,94, + 142,153,51,103,34,24,12,38,137,27,165,103,87,6,14,111,228,233,184,93, + 240,136,108,221,201,86,18,191,63,249,88,38,245,207,197,141,167,69,215,59, + 53,190,220,218,144,173,71,89,236,40,221,76,235,191,144,2,215,219,219,91, + 176,188,168,78,185,133,110,119,175,178,149,198,127,19,118,144,53,76,245,61, + 86,139,102,188,193,26,92,212,148,120,141,15,23,160,205,156,57,211,18,57, + 37,110,197,131,135,254,200,52,14,140,207,200,33,139,6,13,142,182,107,184, + 9,121,191,60,224,217,169,177,176,179,224,168,19,154,63,185,107,90,162,195, + 158,91,128,212,247,70,101,141,68,34,16,66,192,231,243,97,198,140,25,8, + 6,131,150,184,241,49,100,188,188,114,57,120,63,21,63,102,183,159,62,203, + 46,87,46,18,60,79,238,194,204,180,254,67,161,144,229,150,228,22,5,109, + 118,22,6,47,11,15,83,231,162,198,239,137,31,203,180,254,11,41,112,29, + 29,29,5,201,135,238,139,63,68,201,174,68,217,139,64,245,47,123,0,100, + 139,93,254,127,216,9,71,161,130,53,148,120,229,14,46,114,13,13,87,43, + 113,43,18,60,220,61,198,59,212,101,113,139,68,34,163,34,5,1,251,208, + 113,59,11,40,85,95,131,157,216,113,145,163,63,55,29,227,13,59,183,222, + 40,248,194,48,12,148,148,148,160,180,180,212,18,56,26,6,192,211,183,179, + 194,156,92,174,242,125,203,238,70,187,123,146,55,121,56,3,229,153,174,254, + 201,114,163,122,228,214,5,255,44,231,195,239,147,91,13,220,50,147,239,133, + 127,175,153,212,127,33,5,46,28,14,23,36,31,238,82,36,82,221,167,252, + 80,225,244,123,224,231,242,188,236,136,199,147,35,116,201,106,55,134,223,79, + 229,96,141,201,10,137,156,18,183,177,208,108,187,0,0,32,0,73,68,65, + 84,226,193,67,13,21,185,38,120,52,32,133,163,243,49,86,78,127,94,59, + 177,0,18,13,57,205,236,96,103,189,241,63,60,9,22,111,68,169,225,22, + 98,100,86,120,222,184,242,113,111,212,55,168,105,137,14,237,96,48,136,210, + 210,82,235,41,85,110,144,229,242,202,174,70,167,167,111,142,28,180,65,101, + 146,3,19,236,172,87,30,104,144,170,254,201,106,166,107,233,94,168,110,248, + 28,152,118,253,112,84,175,188,156,114,208,12,31,176,206,247,165,171,255,66, + 10,92,33,135,9,164,122,32,75,213,7,105,247,155,146,143,243,107,236,230, + 242,116,185,92,40,43,27,25,159,105,24,134,21,20,21,143,199,173,7,33, + 26,91,7,192,242,90,208,239,38,85,160,147,34,55,216,173,16,160,1,80, + 1,37,197,131,135,26,87,62,243,6,69,237,209,88,43,138,80,76,247,100, + 106,135,108,77,200,215,202,125,24,188,97,225,34,71,127,94,18,76,46,6, + 124,58,46,33,4,188,195,46,25,218,232,105,87,206,43,213,147,180,108,157, + 217,89,173,169,206,147,173,61,62,134,138,187,1,211,213,63,221,147,157,240, + 243,215,116,110,74,185,95,144,187,45,121,127,42,159,28,152,187,192,156,234, + 223,201,2,153,204,200,214,122,186,115,101,215,163,211,195,144,221,181,229,229, + 229,163,246,243,168,85,217,90,230,191,19,250,77,211,126,217,29,237,118,187, + 45,177,211,52,45,73,248,104,186,58,133,98,42,227,225,211,82,113,139,136, + 4,131,6,114,167,123,34,148,255,224,4,183,104,100,156,220,54,124,31,255, + 131,147,200,70,163,81,171,145,229,253,111,20,89,72,238,73,234,115,163,134, + 66,46,171,93,89,100,55,30,191,7,39,17,116,250,44,71,136,210,123,30, + 137,152,174,254,121,221,243,186,144,197,77,222,120,126,92,116,249,125,112,113, + 147,197,222,46,77,187,250,47,36,133,106,144,169,126,82,185,214,229,250,178, + 251,253,58,149,151,255,78,200,165,104,119,14,133,239,59,65,194,70,129,42, + 244,160,68,239,129,145,161,43,252,251,242,120,60,152,49,99,134,245,222,73, + 4,105,229,141,169,248,16,163,152,30,120,0,36,69,21,82,3,203,133,141, + 132,131,55,254,50,78,127,120,238,230,162,243,100,11,195,9,106,196,249,140, + 237,212,159,68,101,35,129,163,49,97,52,11,136,223,239,183,21,183,84,79, + 215,114,128,0,189,231,226,46,187,46,249,171,156,22,119,7,202,179,86,112, + 119,169,83,253,243,201,156,229,112,245,84,66,103,215,127,36,11,183,92,15, + 124,150,19,122,229,141,163,83,253,23,210,10,40,164,139,82,30,176,239,36, + 118,178,139,90,142,202,181,123,8,146,131,122,198,83,206,116,34,8,36,234, + 141,250,227,92,46,23,124,62,159,85,86,190,166,161,44,130,84,7,20,57, + 75,223,53,15,60,82,34,168,40,102,60,124,60,24,48,50,27,8,109,114, + 212,160,44,74,78,130,71,216,53,74,118,253,96,78,199,229,134,155,26,127, + 154,177,159,47,86,42,132,176,66,237,105,80,169,93,244,91,166,101,231,231, + 200,13,145,44,116,118,127,112,30,185,200,45,82,158,110,170,250,231,227,165, + 228,186,200,68,228,228,254,68,39,151,164,124,175,178,192,165,170,255,169,216, + 215,195,31,78,228,125,178,85,204,45,127,0,163,30,6,249,49,234,199,76, + 55,103,104,174,49,12,3,131,131,131,41,207,113,18,65,242,136,240,7,39, + 138,162,229,110,111,250,93,171,126,65,69,49,97,141,131,3,146,231,114,228, + 253,110,118,125,78,118,253,88,28,46,12,169,250,225,100,236,92,61,92,0, + 168,1,225,65,47,212,80,240,254,44,46,28,178,200,201,86,140,220,55,39, + 159,43,7,104,216,53,124,78,117,192,225,19,48,203,174,68,96,116,253,115, + 235,200,46,80,133,92,156,118,34,39,215,181,147,80,115,55,42,213,21,31, + 68,46,71,75,202,245,95,72,10,221,103,196,45,55,110,137,103,122,157,221, + 255,198,110,61,193,98,32,19,17,36,225,35,143,12,69,111,146,8,2,233, + 251,5,53,77,83,34,168,40,24,30,254,4,74,13,172,44,110,252,156,116, + 214,151,188,95,22,55,217,61,153,42,61,126,14,143,230,227,110,73,121,16, + 178,44,112,84,110,158,166,147,139,81,190,79,59,43,45,19,203,141,35,63, + 165,83,30,114,84,167,92,255,78,226,38,91,110,169,92,150,252,126,157,26, + 14,254,36,206,235,139,139,112,170,250,79,247,192,146,75,10,229,162,228,98, + 46,63,28,217,89,189,244,202,191,75,187,223,69,98,58,172,17,203,141,92, + 140,147,5,211,52,147,134,106,12,12,12,140,58,39,93,191,32,121,45,50, + 21,65,185,95,80,5,199,40,178,193,35,55,234,188,129,181,179,208,100,151, + 140,29,116,157,60,51,191,83,255,155,252,94,22,24,185,145,225,227,130,56, + 36,112,92,220,120,121,236,92,75,114,185,121,25,184,107,143,159,147,206,106, + 147,45,67,158,174,220,55,150,174,254,101,43,207,206,5,201,69,78,30,66, + 0,36,187,74,237,202,202,221,146,60,31,254,224,224,84,255,83,181,239,133, + 220,137,116,239,60,98,52,30,143,59,6,216,216,89,109,148,150,252,155,42, + 148,139,178,144,144,104,143,39,56,134,139,32,245,13,210,49,21,28,163,200, + 6,15,255,131,241,213,160,9,217,250,177,123,111,119,142,108,185,217,185,228, + 100,225,147,211,160,167,58,222,240,242,149,170,105,174,73,222,119,196,215,116, + 227,105,203,79,218,78,247,37,91,117,178,27,84,190,95,58,135,210,225,86, + 175,44,132,220,221,74,226,149,170,254,249,121,188,78,249,125,217,9,29,119, + 85,202,245,200,203,111,119,45,47,23,47,171,83,253,23,146,66,71,81,114, + 129,147,31,2,200,122,149,173,94,249,161,134,234,73,182,220,104,163,89,71, + 166,19,99,17,193,124,5,199,40,166,54,30,0,73,141,170,108,173,56,185, + 160,228,190,43,142,108,97,240,198,86,118,51,241,6,65,14,192,144,45,10, + 167,39,50,222,208,112,183,159,44,100,188,129,151,197,69,78,219,238,105,219, + 201,181,73,216,45,15,226,228,194,226,229,75,85,255,118,145,123,78,22,49, + 223,79,66,199,27,222,84,27,79,91,78,43,85,253,23,210,69,89,168,153, + 57,120,240,4,31,255,73,13,171,236,166,230,200,223,51,23,55,46,122,180, + 69,34,145,130,220,211,100,35,19,17,4,198,31,28,19,12,150,33,20,10, + 21,226,150,20,19,128,229,103,201,164,63,137,255,48,200,125,192,23,246,36, + 232,51,239,103,146,93,150,178,37,37,139,27,79,11,176,95,77,219,174,124, + 153,194,45,67,39,113,227,214,10,119,85,202,79,241,180,143,144,151,177,145, + 235,36,85,158,169,72,229,218,181,195,169,33,150,211,225,105,217,149,27,112, + 174,255,66,186,129,174,188,242,202,130,228,195,163,76,129,228,7,18,195,48, + 146,214,135,179,115,49,242,135,22,217,98,227,245,103,247,59,81,100,199,120, + 131,99,18,115,215,78,158,126,80,69,118,120,128,228,177,57,78,253,2,244, + 20,36,15,12,118,178,32,248,198,231,73,228,233,241,87,121,191,140,236,38, + 228,215,103,50,235,59,165,97,119,76,182,242,120,99,206,95,169,126,156,44, + 43,126,92,70,118,3,218,221,27,93,239,84,255,114,217,157,26,71,234,151, + 72,101,101,240,116,237,112,42,163,92,255,133,100,213,170,85,5,201,39,22, + 139,89,79,251,116,191,177,88,44,105,9,25,57,200,135,224,214,154,157,184, + 201,30,1,37,112,249,39,147,224,24,59,230,206,171,68,87,231,249,164,125, + 71,143,30,205,105,217,20,249,197,67,79,146,118,13,47,239,139,225,226,38, + 207,196,1,140,22,44,167,49,89,233,176,19,33,249,105,152,247,111,241,62, + 39,59,1,144,93,132,114,163,194,27,32,250,76,121,218,89,113,188,76,252, + 124,158,158,252,158,202,200,235,138,54,10,216,176,171,127,217,229,200,163,204, + 236,234,141,202,73,125,110,220,42,147,27,91,39,241,227,121,203,46,84,187, + 250,255,218,215,190,102,123,125,62,184,243,206,59,147,190,243,76,145,191,63, + 217,69,204,93,232,188,126,14,30,60,136,223,252,230,55,0,70,2,33,104, + 134,28,90,109,157,22,165,5,146,93,143,212,247,70,97,240,180,166,31,205, + 237,74,179,4,245,245,245,97,85,195,45,185,172,38,69,14,56,209,116,76, + 137,217,20,192,35,55,232,118,33,237,220,165,40,11,153,83,255,141,252,116, + 203,27,76,126,141,83,163,46,63,245,242,241,97,242,204,249,36,180,188,241, + 181,179,164,236,196,199,201,85,40,139,66,58,203,133,231,45,11,19,189,242, + 126,49,158,151,93,253,203,229,162,240,116,217,50,147,133,77,46,15,255,44, + 91,135,118,229,176,59,63,85,253,111,218,180,201,182,62,242,65,33,243,42, + 36,141,27,255,97,162,139,160,96,100,34,110,203,151,47,47,80,105,20,227, + 193,35,132,72,138,134,227,79,183,78,214,130,93,67,206,175,145,3,74,156, + 250,215,248,181,242,83,181,108,61,240,153,61,40,109,222,121,76,209,83,100, + 189,240,134,159,71,191,217,137,28,127,111,39,110,78,215,240,244,156,132,143, + 196,151,207,55,41,91,82,78,245,111,135,124,95,220,170,227,34,108,39,120, + 169,92,100,78,86,29,89,248,78,245,175,24,63,203,62,240,193,137,46,130, + 66,49,37,241,200,131,165,121,131,201,221,146,178,56,217,245,185,1,201,195, + 3,232,149,220,64,124,63,165,233,180,143,202,66,174,30,10,235,181,235,255, + 160,48,97,187,190,14,238,250,147,251,166,120,158,178,53,36,31,115,186,78, + 254,44,91,111,60,148,153,92,169,220,186,76,87,255,118,214,154,221,198,197, + 141,7,254,56,89,124,78,238,74,46,124,124,208,191,83,253,43,20,10,69, + 177,226,161,70,141,198,148,1,163,195,211,237,92,149,252,152,147,37,103,231, + 198,180,179,252,120,218,60,82,147,139,27,173,22,0,32,73,48,52,109,100, + 193,80,222,255,36,71,176,201,150,162,147,123,46,149,219,206,9,249,122,89, + 228,236,102,86,161,50,166,170,127,186,7,46,82,92,180,249,253,114,120,191, + 167,92,78,187,190,56,190,241,50,112,113,115,170,127,133,66,161,40,86,60, + 212,144,1,201,99,157,100,43,194,174,177,79,39,124,178,229,147,202,237,198, + 175,225,110,180,88,44,102,173,139,22,143,199,147,6,118,242,126,45,143,199, + 99,185,250,228,113,101,114,196,163,157,43,142,62,203,46,72,249,126,83,213, + 131,188,207,237,118,91,147,62,83,104,57,15,19,231,150,18,48,186,254,249, + 171,157,91,210,206,61,73,231,58,9,156,108,245,241,186,166,250,226,97,236, + 233,234,95,161,80,40,138,21,15,53,104,188,49,228,161,240,212,71,228,100, + 157,17,118,193,36,118,110,73,39,49,32,184,235,142,34,207,66,161,144,53, + 245,142,199,227,65,73,73,73,146,203,143,44,56,190,170,0,183,138,228,8, + 69,39,87,163,108,9,165,90,207,203,238,62,184,176,80,57,105,85,102,62, + 110,138,196,131,71,220,57,213,63,157,79,11,145,202,125,120,60,178,85,30, + 194,32,79,87,38,167,47,91,116,188,111,142,34,0,211,213,191,66,161,80, + 20,43,30,185,161,3,156,45,25,39,151,157,93,99,47,7,118,216,165,145, + 202,194,160,69,76,41,180,58,22,139,193,229,114,37,45,135,35,247,195,149, + 148,148,32,26,141,90,253,80,118,46,74,202,215,206,53,41,247,87,209,64, + 118,126,142,211,253,210,126,178,42,105,154,33,159,207,151,180,56,43,9,47, + 205,112,145,174,254,229,125,118,67,5,120,191,27,159,110,203,78,160,101,97, + 148,199,109,145,248,210,130,171,233,234,95,161,80,40,138,21,15,48,18,232, + 192,167,118,226,214,12,23,43,217,218,112,234,143,227,112,113,115,234,143,163, + 207,92,220,66,161,16,6,6,6,16,14,135,97,154,166,173,184,1,9,235, + 133,6,230,242,178,243,49,126,220,154,148,5,196,78,76,228,99,252,90,39, + 100,177,245,249,124,240,251,253,214,196,177,36,110,124,37,132,76,234,159,151, + 133,187,41,121,89,156,166,40,179,179,142,237,250,226,184,53,73,125,110,153, + 214,191,66,161,80,20,35,214,76,38,242,171,93,195,15,164,159,32,153,222, + 115,87,153,140,93,159,29,183,110,116,93,71,40,20,66,127,127,191,229,30, + 243,120,60,240,251,253,8,4,2,240,249,124,214,106,221,84,14,234,27,34, + 129,228,105,218,5,80,200,247,101,39,92,178,200,240,178,243,235,120,127,37, + 95,81,188,180,180,52,105,8,3,143,70,228,2,151,73,253,211,123,121,192, + 189,60,110,209,206,53,44,91,166,252,222,228,113,110,220,45,156,73,253,43, + 20,10,69,177,146,52,23,37,31,71,198,45,4,59,43,45,213,211,59,185, + 247,100,209,176,115,83,114,1,34,113,27,26,26,66,127,127,63,6,7,7, + 17,137,68,160,105,154,213,184,250,253,126,219,213,2,52,77,75,178,226,120, + 95,30,143,254,147,199,127,201,229,161,52,185,80,200,110,74,110,5,242,49, + 127,92,4,104,166,11,42,19,5,108,68,163,81,219,229,126,50,169,127,62, + 20,128,220,146,242,252,160,36,128,178,248,201,121,201,245,67,150,91,56,28, + 206,170,254,21,10,133,162,88,177,86,19,176,11,196,144,27,89,46,108,220, + 162,32,232,152,93,52,38,79,151,55,216,148,15,5,53,12,13,13,97,96, + 96,0,253,253,253,208,117,29,66,136,81,162,193,135,8,80,30,212,176,147, + 59,144,79,100,43,91,160,114,216,189,108,225,240,243,237,196,77,78,139,250, + 220,124,62,159,85,206,64,32,96,45,225,65,1,51,52,61,147,188,26,118, + 54,245,207,203,73,150,171,236,126,117,185,92,163,2,131,236,172,68,30,49, + 25,141,70,173,135,139,108,235,95,161,80,40,138,17,15,144,236,50,148,195, + 205,249,218,74,212,152,243,87,39,156,92,148,178,245,70,1,23,212,231,115, + 241,226,69,12,12,12,96,104,104,200,154,185,189,180,180,20,101,101,101,240, + 251,253,150,203,207,206,61,42,151,141,139,23,31,160,204,203,34,187,28,101, + 241,227,240,60,249,16,5,10,40,33,183,36,185,241,72,104,169,79,145,196, + 77,94,71,45,219,250,39,11,89,182,72,249,56,59,42,163,92,247,92,224, + 184,85,57,158,250,87,40,20,138,98,196,118,89,98,222,175,4,140,132,182, + 243,126,38,187,70,151,55,210,242,44,28,0,146,196,134,210,140,199,227,86, + 159,207,192,192,0,6,7,7,173,160,6,175,215,139,25,51,102,32,24,12, + 162,180,180,212,10,216,176,19,78,46,18,100,93,200,171,146,203,65,25,124, + 60,153,124,76,118,15,242,64,27,0,73,51,148,144,229,70,125,111,180,58, + 49,69,35,242,73,118,51,89,105,56,211,250,167,122,166,207,228,178,228,129, + 40,118,105,243,186,143,197,98,57,169,127,133,66,161,40,54,146,4,142,135, + 160,219,53,178,116,156,91,47,78,171,6,56,5,104,144,123,142,55,174,67, + 67,67,8,135,195,86,159,15,0,120,189,94,4,131,65,171,129,13,4,2, + 73,235,112,145,235,144,220,128,148,126,42,235,133,94,233,26,62,54,77,238, + 155,35,119,167,92,126,126,223,124,156,27,189,231,226,70,110,63,26,40,157, + 78,220,198,83,255,124,69,5,39,203,89,211,70,86,47,200,85,253,43,20, + 10,69,177,226,145,67,248,229,6,152,91,11,124,134,16,62,207,162,44,112, + 78,79,248,220,37,201,151,15,73,44,58,152,112,225,145,112,148,150,150,34, + 24,12,34,24,12,38,133,218,219,69,68,242,190,38,187,178,19,188,108,242, + 48,3,74,75,182,230,228,107,249,220,151,84,46,26,248,76,81,156,228,250, + 163,251,211,117,61,105,220,27,79,147,152,172,245,175,80,40,20,197,138,101, + 162,112,171,65,14,73,231,141,44,183,192,232,58,106,92,229,21,188,9,238, + 18,227,115,27,210,43,53,254,60,10,177,172,172,12,101,101,101,150,85,68, + 226,65,229,146,93,160,118,1,21,118,129,49,124,159,108,117,202,65,30,60, + 77,186,55,114,75,82,152,60,15,184,224,150,17,185,38,121,212,164,147,184, + 77,246,250,87,40,20,138,98,36,201,7,39,91,20,180,143,55,236,66,36, + 22,111,4,96,45,159,34,247,87,201,81,123,114,159,15,189,114,183,27,13, + 138,166,104,61,191,223,159,52,222,74,46,15,207,207,41,204,95,46,147,157, + 43,85,142,68,148,7,76,203,2,194,167,7,227,253,143,124,28,25,223,236, + 196,77,174,227,201,94,255,10,133,66,81,140,216,6,153,216,89,60,180,159, + 26,91,26,76,205,251,116,168,177,149,167,127,34,1,144,103,207,160,201,136, + 169,31,139,26,88,154,160,88,94,224,147,151,77,46,175,93,8,191,157,59, + 141,230,117,228,231,113,161,3,146,87,35,231,227,220,100,235,136,91,84,177, + 88,204,178,220,72,68,100,1,146,203,230,196,100,171,127,133,66,161,40,70, + 108,5,14,72,30,191,70,13,45,89,46,252,156,88,44,102,53,254,114,63, + 147,220,48,210,181,212,112,82,120,189,188,81,35,206,27,83,59,215,91,58, + 236,132,143,195,27,123,46,134,114,62,148,142,60,102,142,175,151,198,173,35, + 218,239,36,110,153,150,125,178,215,191,66,161,80,76,36,142,2,199,145,27, + 125,234,147,137,199,227,214,44,254,52,253,20,119,125,241,169,168,232,90,30, + 168,65,86,2,239,207,146,199,215,113,23,97,186,50,18,78,125,114,180,223, + 110,238,71,122,79,86,28,159,115,83,14,218,32,17,225,98,198,173,40,187, + 64,21,39,119,106,38,76,134,250,87,40,20,138,98,35,35,129,3,70,79, + 95,69,239,237,92,98,114,3,203,211,224,253,90,114,120,187,147,251,49,219, + 198,53,149,229,198,173,42,217,98,227,174,202,84,249,202,174,63,254,217,41, + 2,147,174,27,43,147,169,254,21,10,133,162,24,208,132,16,226,248,241,227, + 104,109,109,69,52,26,69,89,89,217,168,245,190,156,130,31,156,72,119,14, + 143,230,27,26,26,66,73,73,9,106,106,106,176,116,233,82,116,116,116,160, + 163,163,3,47,190,248,34,226,241,184,53,112,90,158,146,42,151,229,145,23, + 247,244,120,60,184,243,206,59,49,127,254,124,0,64,71,71,71,81,212,207, + 252,249,243,113,248,240,97,199,116,115,77,71,71,7,174,190,250,234,164,185, + 45,101,177,38,161,229,238,91,217,181,10,240,73,162,5,132,72,158,40,186, + 185,185,25,243,230,205,43,216,125,125,228,35,31,41,88,94,138,194,160,38, + 31,80,216,225,121,227,141,55,240,214,91,111,225,218,107,175,197,165,151,94, + 138,210,210,82,0,201,17,121,156,76,198,64,165,59,135,26,71,211,52,17, + 14,135,113,254,252,121,188,249,230,155,150,96,60,255,252,243,168,169,169,193, + 236,217,179,225,243,249,10,90,158,104,52,138,238,238,110,60,255,252,243,184, + 251,238,187,1,160,232,234,231,150,91,110,65,69,69,197,40,33,201,228,149, + 112,178,110,1,96,112,112,16,63,251,217,207,48,52,52,132,222,222,94,0, + 201,13,8,31,112,206,175,19,66,36,173,172,206,173,76,128,198,244,197,97, + 24,72,186,86,215,245,130,222,87,95,95,159,99,221,43,20,138,169,131,103, + 112,112,16,129,64,0,243,231,207,71,105,105,169,99,128,133,93,163,67,199, + 101,210,157,67,174,60,151,203,133,96,48,136,203,46,187,12,45,45,45,24, + 28,28,196,137,19,39,224,243,249,48,103,206,28,248,253,254,81,215,231,179, + 60,110,183,27,129,64,0,151,92,114,9,58,58,58,112,240,224,65,44,89, + 178,164,168,234,7,0,6,6,6,108,135,51,216,165,39,151,141,31,151,131, + 81,168,127,114,104,104,8,0,208,211,211,147,52,121,53,45,0,43,223,171, + 97,24,214,16,6,62,109,27,0,43,248,101,100,16,188,6,143,103,36,154, + 213,52,77,116,118,118,226,138,43,174,40,216,125,145,160,42,138,151,112,56, + 12,32,249,187,162,246,32,16,8,76,72,153,20,147,15,79,44,22,67,101, + 101,37,2,129,192,168,96,6,96,244,216,42,126,220,174,175,43,221,57,252, + 56,53,64,129,64,0,149,149,149,136,68,34,48,12,99,148,229,86,200,242, + 8,33,224,243,249,48,123,246,108,196,98,49,252,254,247,191,199,213,87,95, + 93,20,245,243,214,91,111,97,214,172,89,232,238,238,70,36,18,73,234,63, + 163,235,228,201,154,233,28,234,163,163,198,126,196,221,107,90,22,149,166,105, + 136,68,34,86,163,194,7,120,243,33,20,178,213,68,209,153,118,66,77,199, + 105,69,115,143,71,75,74,79,211,52,203,42,46,212,125,81,67,169,40,62, + 116,93,71,107,107,43,158,123,238,56,14,29,234,192,169,83,231,209,215,7, + 148,151,3,139,22,85,226,198,27,231,227,238,187,151,162,166,166,70,125,143, + 138,180,120,46,92,184,128,171,174,186,106,212,172,245,132,220,152,217,237,27, + 203,57,220,13,103,154,38,2,129,0,222,122,235,45,116,116,116,160,174,174, + 46,201,13,54,222,188,50,61,135,202,67,34,247,246,219,111,99,198,140,25, + 8,4,2,69,81,63,4,9,15,69,65,198,227,241,81,19,48,115,81,224, + 238,68,77,211,172,249,50,1,32,30,23,240,249,96,165,83,82,82,98,9, + 129,207,231,179,93,212,148,151,149,79,234,44,91,91,114,63,157,93,63,9, + 5,186,20,242,190,202,203,203,71,149,67,49,241,232,186,142,151,94,58,142, + 111,127,251,48,128,114,44,93,122,35,238,188,187,2,229,229,126,244,245,233, + 104,109,237,197,107,175,181,226,208,161,215,240,249,207,175,192,71,62,114,163, + 18,57,69,74,60,161,80,8,94,175,23,253,253,253,73,211,78,201,150,74, + 46,33,75,41,225,178,50,172,112,119,194,237,118,99,104,104,104,84,132,95, + 33,202,67,131,183,121,195,94,108,245,67,110,67,106,224,105,134,21,46,36, + 220,74,178,115,29,210,126,159,111,196,210,33,151,33,89,100,100,121,1,169, + 93,173,242,164,212,252,184,156,47,207,159,92,158,100,173,23,234,190,84,31, + 92,241,161,235,58,158,125,246,53,60,243,108,43,106,22,45,194,29,119,46, + 66,69,185,31,126,63,160,3,168,208,129,154,69,149,168,175,159,143,221,187, + 79,225,95,158,56,140,142,142,243,248,228,39,111,85,34,167,112,196,3,36, + 187,108,120,255,16,127,82,230,199,229,125,50,153,156,195,207,147,203,64,13, + 158,124,110,190,203,195,225,101,40,182,250,1,128,146,146,18,75,244,236,150, + 176,145,27,124,59,107,152,112,185,70,172,49,57,93,59,11,78,78,87,70, + 118,183,82,218,114,185,168,76,188,236,133,184,47,213,7,87,92,132,195,97, + 156,58,213,138,103,158,59,9,255,252,197,152,191,120,62,252,229,126,192,15, + 232,1,0,8,0,129,48,16,6,252,243,203,81,89,95,137,14,61,140,103, + 158,59,137,69,139,42,177,104,81,205,68,223,130,162,72,73,57,14,46,85, + 227,149,237,117,185,64,149,39,249,122,185,241,119,74,55,93,8,53,9,182, + 203,229,74,234,199,226,243,95,202,2,66,231,167,75,147,222,243,60,120,26, + 118,195,63,242,125,95,234,137,191,184,8,135,195,120,233,165,83,232,13,212, + 32,224,7,58,0,156,215,117,148,195,143,196,55,69,1,39,195,15,39,21, + 1,244,150,7,128,112,13,94,122,233,148,18,56,133,35,89,11,92,46,176, + 123,218,206,4,85,158,4,242,192,108,59,11,146,55,254,118,125,99,118,86, + 22,159,124,25,64,82,96,9,79,219,46,63,158,151,252,153,250,205,156,44, + 62,190,62,95,33,238,139,250,224,94,122,233,37,28,58,116,8,77,77,77, + 74,244,10,132,174,235,168,175,175,199,141,55,222,136,59,238,184,3,0,112, + 247,221,119,227,80,107,13,176,232,86,192,239,71,71,111,24,199,91,129,249, + 229,126,248,3,9,145,211,1,232,97,29,189,58,208,218,17,6,252,126,244, + 85,0,207,188,116,24,167,78,237,158,208,123,82,20,47,30,0,214,124,134, + 114,240,68,190,26,112,59,120,67,25,143,199,147,130,57,38,98,246,122,94, + 158,98,171,31,62,221,22,144,188,80,42,127,207,175,229,253,134,242,138,235, + 0,44,11,135,7,141,164,18,28,59,120,154,252,26,202,147,187,59,185,171, + 151,175,228,80,136,251,234,235,235,195,107,175,189,134,103,159,125,22,21,21, + 21,42,34,175,128,232,186,142,243,231,207,227,153,103,158,129,174,235,184,245, + 214,91,81,89,89,9,189,183,6,229,229,126,84,84,36,250,221,18,231,14, + 95,20,0,244,240,136,5,23,240,3,21,21,126,232,0,250,202,107,80,89, + 25,158,168,219,81,20,57,30,96,164,33,203,71,64,71,166,214,145,157,120, + 100,211,184,230,179,60,197,86,63,244,153,71,22,18,118,34,146,202,2,163, + 247,20,198,47,223,119,170,217,90,236,220,148,78,223,151,220,151,71,215,209, + 61,20,242,190,116,93,199,169,83,167,80,83,83,131,138,138,10,0,42,178, + 178,80,244,245,245,33,28,14,163,188,188,28,167,78,157,194,141,55,222,136, + 138,138,10,148,215,212,96,126,133,31,243,203,43,80,94,225,71,133,63,33, + 116,254,192,136,224,1,64,133,223,15,88,54,93,47,80,83,131,138,138,142, + 9,186,27,69,177,147,36,112,64,97,173,36,39,228,6,111,162,41,182,250, + 209,180,145,181,233,0,123,203,201,201,29,72,231,216,89,67,178,5,197,191, + 7,57,15,110,61,201,249,241,99,212,127,231,212,95,38,63,196,20,226,190, + 252,126,63,58,58,58,48,127,254,124,84,86,86,2,128,37,116,138,252,82, + 81,81,129,222,222,94,232,186,142,142,142,86,248,253,126,148,151,151,163,162, + 55,140,249,229,53,168,156,159,16,183,242,128,31,129,242,0,252,72,124,95, + 186,174,67,47,15,32,220,23,30,222,7,0,21,208,123,59,212,195,137,194, + 145,164,21,189,243,209,120,219,165,153,137,213,162,202,147,217,117,118,194,155, + 74,0,248,123,167,113,120,178,123,209,46,77,121,63,31,136,45,215,21,23, + 59,254,30,192,40,75,173,16,247,85,94,94,142,27,111,188,17,225,112,24, + 129,64,64,53,144,5,196,239,247,195,239,247,163,183,183,23,53,53,55,162, + 188,188,60,241,29,160,111,216,114,43,71,121,69,0,21,229,128,31,137,62, + 56,32,97,201,233,97,29,254,74,0,125,1,160,55,12,189,162,15,229,173, + 125,106,102,19,133,35,41,23,60,205,23,242,152,51,90,48,212,137,66,148, + 7,24,9,70,16,66,88,243,41,78,84,121,82,213,79,42,183,32,239,219, + 162,125,92,132,228,213,8,120,158,166,57,250,90,222,247,200,251,66,229,149, + 10,184,181,197,7,100,147,43,81,238,67,227,239,121,31,92,33,238,171,175, + 175,15,53,53,53,56,121,242,164,213,224,170,70,178,48,208,20,92,129,64, + 0,53,53,53,232,235,235,67,101,101,37,230,183,182,162,162,156,196,109,216, + 130,243,39,134,10,144,67,50,224,247,35,172,235,195,159,134,3,79,2,189, + 168,172,84,81,148,10,123,60,128,115,131,45,143,243,202,85,195,206,211,147, + 67,184,39,170,60,178,203,45,19,203,97,162,234,135,159,151,174,15,204,206, + 186,177,179,70,71,242,26,217,39,47,27,148,174,78,100,241,226,130,232,148, + 39,229,83,200,251,210,117,221,10,44,209,117,29,189,189,189,202,69,89,32, + 194,225,176,21,216,83,81,81,1,93,215,19,159,203,91,209,123,190,9,21, + 53,183,90,226,230,47,79,136,155,159,130,76,252,0,250,70,58,228,90,79, + 29,66,77,185,114,47,43,156,153,144,97,2,114,250,118,13,218,68,150,7, + 200,108,249,141,137,170,31,59,43,40,93,26,244,94,94,149,156,159,227,114, + 141,142,214,148,5,206,206,141,9,164,31,46,64,51,146,240,227,244,89,14, + 100,201,247,125,81,196,100,77,141,122,242,47,52,118,117,94,95,95,15,0, + 120,237,208,41,116,156,154,143,249,183,174,128,223,15,148,7,128,192,112,76, + 73,192,15,132,117,160,15,0,116,63,78,29,111,66,69,239,41,220,122,227, + 82,235,122,133,66,102,66,5,142,242,200,52,31,85,158,228,125,118,1,23, + 233,246,243,169,175,100,104,63,15,50,225,83,132,145,144,208,121,92,88,236, + 34,48,229,89,71,184,149,69,195,6,146,39,72,46,204,125,169,62,183,226, + 130,30,56,116,93,199,161,147,135,208,218,20,198,138,91,111,69,160,60,17, + 76,226,199,176,245,54,60,108,224,240,225,215,160,119,52,225,198,165,53,168, + 175,175,183,214,109,84,40,100,38,108,28,156,252,180,205,153,136,113,112,169, + 202,83,108,245,51,222,252,157,174,147,243,148,3,64,104,31,239,243,226,238, + 199,84,110,68,185,220,220,141,41,91,167,249,190,47,53,23,101,241,65,125, + 114,189,189,189,56,117,252,37,236,62,121,24,53,75,23,97,81,125,61,22, + 213,212,160,181,181,21,167,154,154,208,122,252,20,160,247,98,81,77,13,106, + 106,106,16,8,4,212,212,107,10,71,212,56,184,12,202,83,108,245,67,101, + 178,115,237,113,43,70,14,204,112,178,110,228,60,140,225,14,43,154,11,82, + 182,156,120,58,52,206,140,63,0,200,67,6,236,230,138,228,2,199,39,107, + 46,196,125,169,6,177,56,169,172,172,196,210,165,75,81,81,81,129,214,214, + 86,180,190,246,26,14,61,251,44,116,93,135,223,239,199,252,249,243,49,127, + 254,124,212,44,78,44,151,67,67,60,212,247,169,112,66,141,131,203,128,98, + 171,31,138,176,4,48,202,178,204,244,122,249,26,114,33,242,9,142,105,249, + 26,249,28,46,240,166,105,90,110,76,121,24,0,185,34,233,24,193,175,167, + 60,11,121,95,106,214,146,226,132,162,89,43,43,43,81,83,83,131,112,56, + 140,190,190,62,75,224,104,72,1,173,95,169,190,71,69,58,212,56,184,73, + 90,30,114,237,113,241,149,27,120,217,210,225,215,82,222,92,180,200,53,76, + 240,137,144,129,228,169,179,236,44,58,158,191,221,42,0,118,86,151,108,225, + 21,226,190,84,31,92,241,67,253,106,118,43,122,43,97,83,100,138,26,7, + 135,201,55,14,142,247,93,201,107,163,209,123,126,174,28,160,33,11,7,63, + 135,223,55,173,38,96,87,62,89,112,156,32,161,114,58,71,211,52,196,98, + 49,196,227,241,130,221,151,234,131,155,156,144,216,41,151,164,34,83,178,26, + 7,103,135,28,54,46,227,20,104,64,175,227,25,7,151,203,242,228,98,28, + 92,46,203,67,175,78,245,35,55,224,78,227,228,156,172,32,187,115,229,113, + 111,178,5,151,206,138,74,247,89,134,210,160,85,183,11,117,95,170,129,84, + 40,166,7,227,30,38,48,30,107,70,110,200,115,145,87,46,202,3,228,110, + 28,92,62,234,71,211,18,171,104,123,189,222,113,91,147,92,128,41,224,131, + 172,54,190,162,58,207,155,187,19,13,195,176,237,247,226,34,101,39,242,180, + 95,14,42,41,196,125,41,23,151,66,49,61,80,227,224,108,242,152,12,229, + 33,119,106,186,190,46,110,233,240,52,121,58,64,114,159,24,69,27,210,52, + 86,60,109,217,98,34,49,226,3,173,237,4,141,250,217,132,0,104,55,79, + 43,20,10,21,236,190,84,31,156,66,49,61,24,229,162,180,235,219,144,223, + 203,215,240,115,82,53,64,156,116,238,43,187,115,39,170,60,197,86,63,134, + 97,96,104,104,104,84,240,132,156,87,42,228,40,71,74,39,18,137,32,26, + 141,2,72,8,28,69,31,242,243,184,136,81,90,242,48,1,158,135,92,22, + 158,47,63,191,80,247,165,250,224,20,138,233,129,99,20,37,117,246,219,53, + 204,214,96,95,77,3,88,99,79,175,252,184,201,210,179,246,49,247,20,239, + 135,225,216,149,71,22,22,126,94,162,124,26,52,45,185,33,180,59,78,251, + 71,246,37,91,29,118,46,211,177,212,143,166,185,146,202,35,215,143,166,185, + 0,140,52,196,180,79,8,51,101,253,156,56,113,34,195,175,119,124,148,148, + 148,192,235,245,58,134,223,83,249,228,129,249,178,136,243,250,145,69,143,247, + 179,21,234,190,84,31,156,66,49,61,72,18,56,30,158,205,7,53,219,117, + 246,243,6,215,238,28,58,238,182,185,198,197,162,22,157,66,190,185,208,216, + 5,31,216,89,5,114,121,228,125,195,239,70,237,75,184,205,146,67,203,237, + 202,147,143,250,225,53,52,18,57,56,178,24,168,92,158,143,126,244,163,80, + 140,143,158,158,158,137,46,130,66,161,40,0,150,139,146,58,251,121,3,238, + 52,3,69,182,145,115,118,251,248,19,189,93,32,3,89,45,92,216,242,93, + 30,234,251,145,231,85,44,182,250,81,140,143,217,179,103,79,116,17,20,10, + 69,1,72,18,56,77,211,224,245,122,45,97,225,86,7,119,55,145,101,33, + 52,13,176,153,151,144,31,119,219,236,211,134,45,37,183,219,141,104,52,106, + 27,6,79,159,169,15,200,201,82,74,182,188,4,76,115,244,76,40,252,56, + 224,26,181,79,136,145,207,177,88,204,118,126,196,177,212,143,92,30,185,126, + 52,77,64,211,220,163,246,81,121,156,234,71,161,80,40,20,233,177,166,234, + 242,120,60,8,4,2,163,166,103,34,236,130,35,156,2,41,248,123,167,96, + 12,32,49,169,178,219,237,182,181,152,220,110,55,124,62,31,60,30,207,168, + 254,185,124,149,135,132,68,182,166,138,173,126,20,10,133,66,145,30,23,0, + 116,118,118,194,231,243,33,16,8,216,54,222,192,232,32,11,187,6,215,238, + 120,170,107,60,30,15,124,62,31,74,74,74,112,225,194,5,107,127,95,95, + 31,188,94,47,124,62,159,173,184,229,171,60,110,183,219,18,176,222,222,94, + 0,192,188,121,243,138,174,126,20,10,133,66,145,30,215,37,151,92,130,147, + 39,79,78,152,133,64,238,191,83,167,78,225,146,75,46,193,172,89,179,208, + 214,214,54,225,229,249,195,31,254,128,89,179,102,193,52,205,162,169,31,133, + 66,161,80,100,142,171,172,172,12,29,29,29,216,181,107,23,206,156,57,83, + 240,2,156,57,115,6,187,118,237,66,71,71,7,202,202,202,224,247,251,209, + 221,221,141,189,123,247,226,220,185,115,5,47,207,185,115,231,176,119,239,94, + 116,119,119,195,239,247,163,152,234,231,125,239,123,95,193,243,87,40,20,138, + 201,138,118,234,212,41,113,230,204,25,252,246,183,191,69,75,75,11,122,123, + 123,17,137,68,50,30,132,61,230,140,53,13,62,159,15,21,21,21,168,173, + 173,197,117,215,93,135,186,186,58,0,192,243,207,63,143,150,150,22,188,251, + 238,187,24,24,24,64,44,22,43,72,121,188,94,47,102,204,152,129,203,46, + 187,12,181,181,181,184,235,174,187,0,36,68,166,88,234,103,241,226,197,121, + 205,87,161,80,40,166,10,154,16,66,156,63,127,30,93,93,93,232,238,238, + 182,102,146,40,68,3,238,241,120,80,86,86,134,57,115,230,96,238,220,185, + 168,172,172,132,174,235,232,235,235,67,87,87,23,246,237,219,135,112,56,12, + 195,48,10,82,30,183,219,141,64,32,128,85,171,86,97,238,220,185,214,148, + 78,84,158,137,174,159,242,242,114,148,150,150,230,53,95,133,66,161,152,42, + 104,2,200,111,75,173,80,40,20,14,184,84,116,176,34,143,168,193,85,10, + 133,66,161,152,146,40,129,83,40,20,10,197,148,68,9,156,66,161,80,40, + 166,36,74,224,20,10,133,66,49,37,81,2,167,80,40,20,138,41,73,202, + 21,189,21,163,201,36,230,75,133,165,42,20,10,197,196,51,53,4,142,143, + 73,43,64,216,113,170,49,112,106,82,100,133,66,161,40,14,198,36,112,114, + 19,46,164,125,5,181,96,164,25,248,69,98,245,210,252,101,7,251,245,219, + 64,251,243,150,115,145,34,215,67,161,5,126,162,243,159,134,56,213,240,180, + 251,237,43,138,158,113,15,244,166,31,251,132,252,184,109,150,156,73,236,206, + 175,200,1,137,251,30,181,144,105,94,115,44,66,28,150,4,42,152,200,20, + 48,255,9,253,157,103,65,62,203,105,165,237,224,193,176,150,125,202,34,77, + 53,208,91,145,79,38,111,144,137,131,184,21,44,123,36,47,121,83,236,13, + 95,206,225,235,216,177,77,211,180,209,86,213,20,87,208,94,252,0,0,32, + 0,73,68,65,84,201,95,8,145,81,31,236,68,33,63,116,229,35,237,84, + 233,91,139,8,231,165,4,10,69,246,76,94,129,27,102,34,45,8,203,93, + 89,144,220,138,8,122,184,192,136,123,154,91,14,121,23,57,41,255,164,67, + 121,206,191,88,27,240,66,136,91,210,190,225,245,15,229,117,16,129,226,173, + 35,197,244,99,114,10,28,179,222,242,61,233,113,218,162,20,52,51,145,190, + 225,206,228,156,113,150,33,19,139,57,111,34,83,224,252,185,120,79,38,242, + 89,110,254,112,49,237,30,238,20,147,138,201,41,112,140,66,247,189,77,24, + 66,192,157,161,47,214,157,80,255,252,22,7,163,27,81,250,92,136,70,143, + 231,47,111,185,202,159,247,57,113,87,120,177,89,40,220,194,146,31,252,198, + 91,206,116,125,205,78,150,99,177,213,145,98,122,50,249,4,142,89,111,211, + 134,44,196,141,40,132,200,77,7,248,239,172,24,69,206,78,220,136,92,255, + 71,210,137,155,157,187,82,161,152,72,38,245,56,184,105,97,189,217,137,91, + 134,13,151,91,211,52,35,209,42,231,188,88,220,82,146,35,247,10,241,45, + 164,178,212,166,224,175,160,232,112,178,236,84,221,43,138,137,201,37,112,211, + 205,122,179,17,183,177,88,114,57,21,185,12,35,87,243,246,192,49,209,249, + 43,212,16,25,197,164,97,114,9,28,99,90,88,111,154,6,67,8,193,69, + 205,200,64,221,71,157,159,203,186,97,226,226,100,185,229,245,251,152,232,252, + 167,57,74,220,20,147,137,201,215,7,135,105,54,29,214,176,200,201,251,28, + 55,70,62,197,45,241,113,36,144,161,208,226,86,168,252,121,126,220,123,80, + 44,13,59,31,143,41,91,182,185,254,159,200,81,203,153,6,156,40,20,19, + 197,164,181,224,136,105,241,180,110,99,201,165,163,32,226,102,231,46,46,164, + 184,229,57,127,43,82,147,9,8,80,60,226,70,240,233,227,70,205,234,147, + 195,180,57,153,4,156,20,83,29,41,166,39,147,90,224,138,65,220,10,21, + 22,111,107,201,57,80,40,113,163,114,229,157,9,204,191,144,129,51,185,164, + 16,191,73,94,39,202,114,83,20,35,147,86,224,138,70,220,216,172,26,249, + 207,48,131,251,205,117,157,76,192,60,159,69,149,191,68,177,90,38,78,150, + 86,190,210,78,183,162,70,49,214,145,98,250,49,41,251,224,38,186,145,3, + 146,93,50,197,50,38,42,231,76,180,184,76,116,254,18,197,222,112,243,254, + 184,124,165,157,42,125,58,94,204,117,164,152,94,140,105,53,1,249,39,46, + 143,127,201,235,15,188,200,196,45,105,255,84,252,115,243,161,25,19,81,239, + 19,157,191,98,20,78,223,194,88,126,251,106,53,1,69,62,25,247,114,57, + 211,141,116,145,98,83,85,228,38,84,92,38,58,127,69,222,80,2,167,200, + 39,147,182,15,110,34,153,86,195,20,128,137,23,151,137,206,95,161,80,76, + 74,148,192,101,201,148,179,206,20,10,133,98,138,50,41,131,76,20,10,133, + 66,161,72,135,18,56,133,66,161,80,76,73,148,192,41,20,10,133,98,74, + 162,4,78,161,80,40,20,83,18,37,112,10,133,66,161,152,146,104,133,84, + 56,163,128,243,213,185,85,104,185,98,2,16,154,166,2,109,21,138,34,65, + 89,112,10,133,66,161,152,146,40,129,83,40,20,10,197,148,100,218,14,244, + 190,108,193,130,180,174,164,119,207,157,83,126,78,133,66,161,152,164,76,91, + 129,3,128,246,246,118,199,99,85,85,85,5,44,137,98,60,152,210,4,51, + 174,201,183,124,155,66,161,200,3,25,187,40,77,64,208,246,199,43,87,10, + 249,115,62,11,153,15,222,61,119,78,115,18,177,170,170,42,101,189,77,18, + 76,64,52,55,55,227,197,23,95,68,115,115,51,158,120,226,137,81,130,151, + 43,246,29,56,48,233,126,231,10,197,116,102,76,81,148,38,32,86,174,92, + 137,95,28,56,144,149,8,140,53,138,178,170,170,42,233,194,246,246,246,180, + 249,102,26,69,121,217,130,5,130,91,114,83,81,220,166,170,133,67,247,117, + 242,228,73,148,148,148,96,255,254,253,104,104,104,192,214,173,91,177,125,251, + 246,156,223,231,117,215,95,47,126,251,198,27,41,211,84,81,148,10,69,241, + 80,212,65,38,123,246,236,105,172,170,170,18,103,206,156,65,123,123,59,218, + 219,219,241,147,31,63,143,170,170,42,177,103,207,158,198,92,228,193,45,185, + 169,40,110,196,153,51,103,172,45,95,22,14,89,244,255,176,113,99,222,27, + 121,178,220,122,123,123,177,120,241,98,116,118,118,162,161,161,1,223,249,206, + 119,176,126,253,122,220,113,199,29,227,186,207,117,95,252,226,168,107,23,44, + 88,96,187,95,161,80,20,41,174,49,108,72,88,112,34,219,235,132,16,89, + 109,11,22,44,16,196,238,221,187,197,238,221,187,173,207,11,22,44,16,187, + 119,239,110,116,186,54,219,178,45,88,176,32,171,251,121,224,111,91,178,190, + 255,137,216,0,136,51,103,206,36,109,0,242,82,118,36,4,69,108,220,184, + 49,239,117,3,64,180,180,180,136,230,230,102,209,219,219,43,0,136,127,253, + 215,127,21,205,205,205,226,214,91,111,21,205,205,205,227,186,79,167,107,3, + 129,64,202,52,53,77,19,106,83,155,218,138,99,27,254,47,23,31,100,185, + 1,192,158,61,123,176,102,205,26,172,89,179,198,58,126,230,204,25,172,91, + 183,110,99,174,242,203,196,114,187,255,111,91,4,109,185,202,183,16,212,213, + 213,37,189,223,182,109,219,4,150,38,119,152,166,137,206,206,78,116,119,119, + 227,208,161,67,248,236,103,63,139,15,125,232,67,248,238,119,191,139,15,125, + 232,67,99,78,247,131,55,220,32,156,62,127,245,171,95,29,117,92,161,80, + 20,39,69,43,112,0,224,247,251,45,113,179,59,6,36,220,152,185,200,203, + 73,184,114,33,106,153,184,237,242,225,218,51,1,65,22,109,93,93,93,146, + 208,229,34,237,76,239,43,95,110,203,133,11,23,98,222,188,121,120,227,141, + 55,48,111,222,60,220,113,199,29,104,109,109,197,194,133,11,209,218,218,154, + 85,90,95,254,234,87,5,109,71,142,28,73,58,22,8,4,240,229,175,126, + 85,0,192,198,127,248,7,77,62,174,80,40,138,147,162,31,38,96,39,110, + 185,230,254,191,109,17,219,183,213,12,127,74,47,100,79,63,89,155,113,63, + 93,54,253,64,155,54,109,194,198,141,27,197,63,111,218,148,211,126,192,230, + 230,102,156,57,115,38,167,214,155,11,208,76,64,164,42,51,221,251,198,141, + 27,145,235,123,34,40,176,228,59,223,249,14,182,109,219,134,83,167,78,89, + 226,230,202,34,200,228,209,71,31,117,60,118,96,223,62,109,223,190,125,197, + 235,238,80,40,20,182,20,181,192,233,186,110,89,106,118,199,210,145,107,87, + 98,54,194,6,100,39,110,68,174,68,142,172,55,59,190,184,110,93,78,196, + 70,22,185,77,155,54,37,229,15,228,71,220,40,192,100,225,194,133,248,236, + 103,63,139,127,249,151,127,65,95,95,31,214,173,91,55,38,113,83,40,20, + 83,147,162,30,38,80,85,85,37,156,6,99,87,85,85,97,219,182,109,155, + 0,96,205,154,53,141,242,113,183,166,229,68,224,178,21,53,98,188,145,138, + 227,21,6,18,184,230,230,102,0,201,125,111,185,18,56,158,151,221,254,124, + 139,155,19,99,17,55,222,175,70,46,72,74,103,211,63,255,179,120,241,197, + 23,241,235,35,71,52,42,131,83,30,66,83,195,4,20,138,98,161,104,45, + 56,26,251,86,85,85,133,51,103,206,88,150,156,174,235,212,88,59,138,91, + 46,24,171,176,17,100,221,208,231,116,141,125,54,231,166,163,16,214,219,68, + 96,39,110,185,178,212,72,188,134,73,170,188,71,31,125,20,145,112,120,210, + 214,155,66,49,109,25,107,8,117,62,135,9,44,88,176,64,208,182,123,247, + 238,70,254,153,246,165,26,34,48,150,97,2,249,12,103,71,6,161,243,153, + 158,151,105,158,66,136,164,97,1,219,182,109,19,219,182,109,203,121,248,62, + 47,55,189,231,91,174,134,12,32,33,110,73,105,231,235,59,251,98,98,172, + 155,224,159,233,253,157,119,222,41,248,103,121,155,232,176,104,181,169,77,109, + 35,219,112,219,81,60,240,89,75,200,74,107,111,111,215,182,109,219,182,137, + 54,32,127,150,91,174,113,101,97,97,228,210,165,167,217,204,228,146,47,215, + 164,92,238,141,27,55,90,247,189,105,211,38,140,55,130,50,159,150,155,29, + 219,190,249,77,237,250,235,175,79,250,12,0,143,63,241,132,56,119,238,156, + 245,89,161,80,20,57,99,125,154,206,135,5,151,173,149,150,75,11,46,219, + 129,222,197,188,65,178,162,242,97,189,193,198,66,203,116,95,182,249,20,202, + 114,227,219,129,3,7,70,229,51,103,206,28,97,183,159,111,19,253,196,170, + 54,181,169,109,100,27,110,67,38,30,59,203,173,80,86,26,205,71,153,201, + 18,58,147,141,124,5,150,184,18,1,74,90,58,139,51,211,243,82,81,40, + 203,141,179,106,229,202,81,249,124,244,163,31,181,221,175,80,40,138,147,162, + 16,184,98,16,55,32,177,124,206,84,18,185,124,137,91,161,40,182,73,162, + 255,247,255,250,95,147,178,30,21,138,233,74,198,2,199,151,199,89,185,114, + 37,14,28,56,96,237,27,239,114,57,36,106,19,41,110,196,84,17,185,201, + 46,110,28,178,2,39,186,28,10,133,98,114,49,166,113,112,99,37,213,56, + 56,154,114,43,87,226,150,110,185,28,59,113,227,76,246,149,5,190,185,109, + 155,152,204,226,150,106,172,89,49,35,52,53,14,78,161,40,22,138,70,224, + 114,77,38,2,151,46,141,201,44,112,147,153,201,42,110,128,18,56,133,162, + 152,152,182,2,167,80,228,3,37,112,10,69,241,80,20,65,38,10,133,66, + 161,80,228,154,162,157,170,75,49,189,80,150,143,66,161,200,53,202,130,83, + 40,20,10,197,148,68,115,154,148,87,161,80,253,152,138,169,72,33,99,1, + 198,130,203,229,42,238,2,78,34,148,139,82,161,80,40,24,154,228,46,175, + 174,174,94,213,218,218,186,127,172,233,61,244,208,67,73,233,61,247,220,115, + 227,74,79,145,57,202,69,169,80,40,20,12,33,132,229,186,24,175,184,1, + 192,19,79,60,97,165,167,196,173,176,40,129,83,40,20,138,20,212,212,212, + 84,23,115,122,10,103,178,238,131,227,243,70,2,137,165,108,114,90,162,105, + 64,33,235,112,60,121,77,215,62,184,234,218,218,164,58,107,107,105,153,158, + 21,49,69,113,234,131,91,181,106,85,245,254,253,251,119,0,88,41,29,58, + 80,93,93,221,152,173,229,181,107,215,174,234,19,39,78,216,166,247,220,115, + 207,57,166,167,250,224,114,71,198,22,220,158,61,123,26,171,170,170,196,153, + 51,103,208,222,222,142,246,246,118,252,228,199,207,163,170,170,74,208,52,91, + 138,212,20,178,14,229,188,182,109,219,182,41,151,121,253,99,99,163,227,159, + 80,158,36,57,91,170,107,107,69,117,109,173,240,148,148,88,27,237,147,197, + 39,23,240,180,41,253,179,103,91,112,246,108,139,227,241,241,144,105,253,140, + 183,30,211,165,145,139,244,167,2,171,86,173,170,214,52,109,255,254,253,251, + 91,111,185,165,113,229,241,227,199,49,48,48,0,33,4,142,31,63,142,251, + 238,187,111,101,91,91,219,62,77,211,246,215,212,212,52,164,75,111,215,174, + 93,213,15,61,244,208,254,19,39,78,180,154,166,185,114,217,178,101,184,237, + 182,219,112,219,109,183,97,217,178,101,88,178,100,201,202,187,239,190,123,223, + 67,15,61,148,81,122,138,113,144,205,42,219,196,238,221,187,197,238,221,187, + 173,207,180,126,219,88,215,110,203,102,157,184,225,114,228,37,159,124,231,85, + 200,58,164,188,18,43,162,239,16,11,22,236,200,58,175,84,235,158,53,54, + 54,10,254,74,91,109,66,0,108,143,101,186,213,214,214,138,215,95,127,221, + 118,171,173,173,21,181,181,181,57,91,19,174,182,182,86,252,252,231,215,136, + 223,157,56,34,246,237,75,172,55,39,196,200,218,115,244,126,223,62,136,223, + 157,56,34,126,254,243,107,198,157,63,213,207,210,165,71,146,210,145,63,99, + 156,107,223,45,93,122,36,229,250,121,227,77,127,178,110,242,239,28,192,254, + 134,134,6,113,252,248,113,177,96,193,14,49,48,48,32,142,31,63,46,142, + 31,63,46,132,16,214,231,134,134,6,1,96,127,186,255,205,134,13,27,246, + 63,249,228,147,226,251,223,255,190,104,104,104,16,47,191,252,242,168,237,251, + 223,255,190,120,242,201,39,197,134,13,27,70,165,55,209,107,168,77,165,109, + 248,119,158,26,178,4,0,96,207,158,61,88,179,102,13,214,172,89,99,29, + 63,115,230,12,214,173,91,183,49,147,180,178,193,198,10,41,152,197,147,107, + 235,170,144,117,72,121,237,217,179,103,211,154,53,107,70,165,153,143,239,43, + 149,69,151,75,90,90,90,240,195,31,254,112,148,27,113,60,204,158,249,12, + 254,223,243,255,133,85,171,128,223,157,56,130,55,223,56,130,223,157,56,146, + 244,126,213,42,224,255,61,255,95,152,61,243,153,156,228,185,36,33,62,105, + 95,199,146,230,88,174,31,75,126,83,129,85,171,86,85,3,88,185,101,203, + 22,212,215,215,3,0,22,45,122,14,109,109,109,104,107,107,67,83,83,19, + 130,193,32,234,234,234,176,101,203,22,0,88,153,202,234,218,181,107,87,53, + 128,149,115,230,204,65,69,69,5,0,224,177,199,30,27,117,94,69,69,5, + 230,204,153,147,54,61,197,248,200,120,152,128,223,239,183,26,102,187,99,64, + 66,36,114,185,212,205,186,117,235,54,182,183,183,99,207,158,61,88,183,174, + 31,0,208,222,190,12,237,237,237,168,170,170,218,8,228,110,245,1,202,11, + 72,8,208,112,218,57,205,171,144,117,248,242,203,47,111,90,183,174,127,227, + 186,117,223,179,246,85,85,37,222,183,183,255,117,214,121,201,2,246,79,141, + 141,218,63,54,54,10,254,74,46,175,198,198,70,252,83,99,99,202,107,179, + 189,159,23,94,120,1,31,254,240,135,1,0,31,248,192,0,106,107,255,13, + 213,181,16,231,206,153,214,57,11,22,36,158,215,218,90,178,91,148,180,171, + 247,6,0,137,242,94,187,228,134,108,139,54,102,78,28,191,65,227,194,34, + 127,206,6,46,140,39,142,223,160,81,122,200,192,13,41,95,203,211,24,11, + 252,225,227,246,219,111,199,119,159,126,58,103,125,152,159,187,255,126,177,119, + 239,94,235,243,120,251,71,247,239,223,191,227,190,251,238,67,125,125,61,154, + 154,154,176,105,211,21,56,114,228,2,214,172,89,131,193,193,65,4,131,65, + 108,217,114,2,43,86,84,226,186,235,234,112,223,125,247,97,199,142,29,141, + 53,53,53,182,125,104,39,78,156,216,177,100,201,18,75,220,110,186,233,38, + 252,242,151,191,76,58,231,224,193,131,184,226,138,43,112,197,21,87,96,201, + 146,37,0,224,152,158,98,124,100,100,193,17,118,13,115,190,96,86,136,109, + 190,249,176,120,128,252,91,87,133,170,67,59,203,205,142,76,45,212,127,106, + 108,212,248,102,119,78,109,109,45,6,6,6,108,197,47,221,181,78,188,240, + 194,11,73,159,95,127,253,117,0,192,217,179,183,224,236,217,91,16,137,52, + 88,219,217,179,183,100,147,180,197,220,138,35,88,185,178,17,191,59,113,4, + 251,246,193,241,245,163,119,253,183,97,49,44,78,198,35,74,227,185,150,160, + 62,202,219,111,191,29,109,45,45,90,91,75,139,182,119,239,94,84,215,214, + 138,207,221,127,255,184,44,196,207,221,127,191,168,174,173,21,123,247,238,181, + 210,190,253,246,219,145,131,126,209,149,235,214,173,195,224,224,32,218,218,218, + 112,207,61,203,241,242,203,17,84,85,125,15,193,96,16,85,85,223,195,214, + 173,111,224,186,235,130,8,6,131,88,183,110,29,48,58,104,36,41,61,183, + 219,109,125,184,249,230,155,1,140,88,113,143,61,246,24,126,249,203,95,226, + 138,43,174,0,0,12,159,155,42,61,197,56,200,88,224,116,93,31,211,177, + 241,240,242,203,47,99,221,186,126,203,242,0,18,86,72,85,213,247,146,44, + 158,92,229,85,85,245,61,43,63,190,229,42,175,66,214,161,174,235,104,111, + 255,107,203,90,3,96,125,230,121,181,183,183,99,221,186,117,27,199,115,111, + 220,122,235,234,234,26,71,169,19,214,222,192,192,192,40,97,35,156,246,19, + 45,45,102,202,227,118,116,245,222,128,185,21,71,146,94,87,173,218,135,107, + 151,132,109,95,207,157,203,141,155,114,178,195,133,133,11,27,183,216,184,208, + 141,85,228,200,106,163,180,104,255,119,159,126,58,73,232,236,202,149,9,117, + 117,117,160,7,220,96,48,136,245,235,175,7,48,226,241,56,117,234,110,4, + 131,65,12,14,14,90,110,76,192,57,220,159,172,55,226,166,155,110,2,48, + 34,114,143,60,242,136,237,185,106,248,64,238,201,72,224,218,219,219,181,186, + 186,58,199,227,117,117,117,214,106,220,185,164,144,22,99,190,243,42,100,29, + 102,155,215,88,45,84,59,107,204,53,188,142,219,88,220,144,116,221,140,25, + 51,240,225,15,127,216,114,75,202,175,118,108,218,52,82,117,38,246,137,234, + 218,3,162,186,246,64,70,13,157,44,110,115,43,142,0,0,132,104,176,221, + 0,192,83,178,111,90,246,89,201,112,171,45,149,43,146,68,110,44,144,184, + 57,29,255,238,211,79,143,203,154,163,62,182,234,234,106,12,14,14,226,193, + 7,151,88,199,72,220,232,188,193,193,193,172,203,79,86,28,144,44,110,138, + 252,147,81,31,28,141,165,170,170,170,194,153,51,103,44,139,70,215,245,164, + 198,50,151,253,111,148,62,89,32,114,255,81,190,44,30,167,99,227,165,144, + 117,40,231,197,235,140,231,69,125,116,99,233,147,227,144,245,214,210,210,50, + 234,137,105,172,66,7,192,81,204,56,155,54,109,194,198,141,35,218,76,2, + 4,0,87,94,249,243,140,242,177,179,224,128,125,142,231,71,163,192,169,83, + 149,184,254,250,125,34,30,93,149,242,254,236,250,212,142,31,207,220,205,41, + 95,63,22,87,162,83,191,94,54,229,112,162,165,165,5,181,181,181,57,237, + 103,27,11,223,125,250,105,173,186,182,86,80,121,178,161,169,169,9,245,245, + 245,168,171,171,179,68,172,189,253,175,173,62,56,98,112,112,208,178,244,82, + 209,219,219,59,202,138,115,18,182,222,222,222,172,202,170,200,142,180,2,199, + 7,10,111,219,182,109,83,93,93,93,210,147,126,190,196,173,189,189,93,171, + 170,170,18,20,248,33,147,107,139,39,159,121,21,178,14,51,205,107,221,186, + 254,113,245,41,202,214,81,75,203,74,212,214,30,64,91,75,238,187,19,236, + 132,78,22,54,190,127,132,85,25,165,111,111,193,133,83,230,185,104,209,121, + 148,148,36,234,33,85,80,139,131,32,101,108,101,228,162,111,44,69,26,227, + 182,66,73,76,170,107,107,197,68,14,136,39,203,45,91,113,3,112,96,219, + 182,109,43,159,124,242,73,75,220,248,43,39,24,12,98,219,182,109,0,112, + 32,85,122,134,97,100,252,39,48,12,35,93,122,138,113,144,82,224,228,198, + 18,72,136,129,220,95,147,107,113,227,121,167,179,66,242,97,241,228,210,186, + 42,100,29,102,145,215,70,238,145,205,214,66,229,141,58,189,167,113,85,99, + 43,121,102,112,161,219,184,113,163,37,56,242,43,177,115,103,110,44,184,92, + 88,137,83,145,98,154,225,101,172,101,169,174,174,110,220,177,99,199,190,117, + 235,214,37,89,112,178,184,1,9,75,111,199,142,29,168,174,174,110,4,208, + 103,151,222,115,207,61,215,8,96,223,178,101,203,70,89,113,50,189,189,189, + 56,113,226,4,93,99,155,158,98,124,56,10,156,93,99,73,141,112,62,4, + 45,85,222,197,96,241,228,74,220,242,85,135,233,242,202,183,53,76,22,93, + 58,139,38,83,238,185,231,30,156,59,119,206,250,188,96,193,2,235,125,109, + 237,191,1,128,173,5,55,22,102,204,120,29,93,189,31,24,101,193,229,210, + 74,44,36,227,25,211,150,175,241,112,172,159,46,235,107,111,191,253,118,236, + 221,187,55,47,22,98,107,107,235,126,77,211,14,60,248,224,131,43,183,108, + 217,50,74,228,232,181,169,169,9,15,62,248,32,48,98,109,245,193,70,148, + 90,91,91,247,63,244,208,67,7,186,187,187,87,2,163,3,78,136,222,222, + 94,116,119,119,167,77,79,49,62,108,5,46,85,99,153,111,138,212,226,201, + 58,175,66,214,97,186,188,10,213,255,39,91,117,99,79,103,116,67,214,214, + 210,98,189,175,174,77,182,20,199,35,116,109,45,45,218,61,247,220,35,128, + 90,0,159,192,200,235,51,57,181,18,83,33,139,202,88,68,134,143,125,203, + 102,28,155,221,56,188,92,184,69,9,114,29,142,103,60,220,119,159,126,90, + 27,142,164,20,64,238,45,199,234,234,234,198,253,251,247,55,46,93,186,116, + 229,125,247,221,135,117,235,214,161,190,190,222,234,115,219,182,109,27,118,236, + 216,1,12,207,73,137,97,33,106,109,109,117,180,226,238,190,251,238,198,182, + 182,182,149,75,150,44,129,219,237,182,132,174,183,183,23,134,97,224,196,137, + 19,192,240,156,148,233,210,83,140,157,81,147,45,23,155,184,77,148,40,20, + 107,218,217,230,37,31,151,163,37,83,149,47,213,100,203,100,177,217,137,90, + 174,172,184,84,121,103,50,230,237,202,43,127,158,245,160,111,167,60,156,4, + 110,44,121,152,137,41,178,172,107,100,81,161,207,242,121,99,33,85,26,38, + 32,150,46,61,146,147,126,190,201,132,211,100,203,53,53,53,13,109,109,109, + 141,112,152,108,121,248,61,89,90,125,233,4,169,166,166,166,225,238,187,239, + 182,77,111,88,216,108,211,83,147,45,231,142,81,22,28,53,130,114,195,87, + 85,245,61,209,222,254,215,25,255,17,178,63,191,120,68,97,188,56,213,225, + 232,114,36,215,81,182,117,150,46,175,124,90,168,249,20,176,76,242,190,242, + 202,132,192,242,153,76,56,52,171,73,174,200,149,59,212,14,89,96,10,41, + 56,211,77,220,82,49,60,147,72,131,195,212,89,220,133,152,86,220,242,145, + 158,34,123,108,151,203,161,6,48,185,177,252,158,0,128,76,26,224,108,206, + 77,156,63,117,196,141,176,171,195,228,114,140,174,163,108,235,45,85,94,185, + 184,207,108,151,203,145,173,186,201,76,33,172,68,197,196,224,100,193,113,28, + 6,93,143,89,136,178,73,79,89,112,185,35,227,245,224,168,241,205,134,76, + 27,234,61,123,246,52,102,98,241,228,130,66,230,37,147,207,58,76,206,39, + 55,34,62,93,215,131,3,146,135,65,164,179,18,149,192,77,46,132,166,41, + 1,153,38,100,45,112,249,176,224,128,244,22,79,46,41,100,94,78,228,210, + 130,75,78,55,119,22,234,116,22,56,197,212,69,9,220,244,33,43,129,203, + 103,31,220,116,36,23,125,112,50,185,180,80,149,192,41,166,34,74,224,166, + 15,25,11,156,98,242,144,43,11,85,9,156,98,42,162,4,110,250,160,4, + 78,225,136,234,236,86,40,20,147,153,220,198,82,43,20,10,133,66,81,36, + 40,129,83,40,20,10,197,148,196,243,31,255,241,31,19,93,6,69,145,162, + 9,161,58,225,20,83,142,76,198,193,101,131,114,229,23,47,202,130,83,40, + 20,10,134,166,105,130,111,14,51,145,40,38,1,74,224,20,10,133,130,33, + 152,231,162,186,186,122,213,240,148,91,138,73,136,18,56,133,66,161,72,129, + 195,52,91,138,73,64,218,21,189,101,142,30,61,154,228,111,94,190,124,185, + 234,167,201,146,66,214,161,250,190,178,103,195,195,15,39,213,217,230,111,124, + 67,213,217,52,96,213,170,85,213,251,247,239,223,1,54,251,127,91,91,219, + 62,0,7,106,106,106,26,149,37,55,249,208,126,240,131,31,100,116,226,209, + 163,71,27,1,108,188,237,182,219,172,125,149,151,206,197,174,103,255,29,0, + 54,45,95,190,188,49,15,229,155,82,20,178,14,41,47,0,88,190,124,57, + 142,30,61,186,137,62,103,154,215,39,62,254,113,199,99,91,191,245,45,177, + 254,11,95,176,109,248,255,102,237,90,241,157,237,219,199,44,10,36,48,124, + 165,113,90,195,14,200,189,224,200,130,6,0,183,222,26,2,0,188,246,90, + 233,168,243,199,155,127,166,245,51,222,122,76,151,70,46,210,159,140,200,65, + 38,92,216,110,185,165,17,223,252,230,106,107,225,211,166,166,166,81,235,193, + 201,66,167,130,76,138,151,108,92,148,86,195,252,234,171,175,226,213,87,95, + 197,249,11,93,24,222,183,113,184,65,205,11,71,143,30,21,124,203,87,62, + 5,200,171,144,117,184,113,249,242,229,0,176,233,233,167,159,198,177,99,199, + 54,46,95,190,28,195,251,114,150,215,214,111,125,43,169,142,184,88,200,199, + 178,97,217,178,101,184,233,166,155,172,109,217,178,101,88,182,108,217,168,60, + 198,203,134,135,31,22,75,150,184,177,252,3,75,113,253,245,33,132,66,33, + 220,122,107,8,47,188,0,188,240,66,66,232,66,161,16,174,191,62,132,229, + 31,88,138,37,75,220,57,203,255,203,95,253,119,145,234,115,174,211,87,216, + 179,127,255,254,29,13,13,13,43,143,31,63,142,150,150,106,212,213,213,225, + 204,153,51,104,106,106,66,125,125,61,158,124,242,73,28,63,126,28,13,13, + 13,43,135,215,139,83,76,18,50,18,184,163,71,143,10,222,48,223,118,219, + 109,224,86,8,53,208,185,46,220,209,163,71,27,41,111,218,62,245,201,191, + 36,17,106,156,76,121,21,178,14,73,152,143,30,61,186,105,249,242,229,78, + 105,230,244,251,26,143,152,101,67,40,20,194,178,101,203,114,42,114,94,207, + 245,232,56,223,137,195,135,129,149,183,220,140,129,254,155,177,242,150,155,147, + 222,31,62,12,116,156,239,132,215,115,125,78,242,36,241,73,247,58,150,52, + 199,114,253,116,21,195,85,171,86,85,3,88,185,101,203,22,212,215,215,3, + 0,22,45,122,14,109,109,109,104,107,107,67,83,83,19,130,193,32,234,234, + 234,176,101,203,22,0,88,169,162,42,39,15,89,245,193,81,195,236,196,209, + 163,71,27,115,236,170,180,44,158,199,30,123,12,0,240,200,35,143,224,182, + 219,110,195,171,175,190,186,241,232,209,163,200,97,126,73,214,21,0,75,132, + 114,153,87,1,235,112,211,177,99,199,54,30,59,118,204,218,241,244,211,79, + 3,0,238,191,255,126,28,61,122,52,171,188,100,1,91,255,133,47,104,228, + 166,164,215,191,89,187,86,0,192,251,223,255,254,180,215,102,123,51,23,46, + 92,192,165,151,94,10,0,248,197,47,226,40,45,189,30,27,30,222,37,152, + 23,19,228,197,220,252,141,79,101,149,126,52,118,16,64,162,204,7,126,126, + 48,219,162,141,153,175,63,250,151,26,23,22,249,115,54,112,97,252,250,163, + 127,169,81,122,244,157,100,115,45,79,99,44,240,135,143,101,203,150,225,19, + 31,255,120,206,220,160,223,255,193,15,4,255,77,143,215,93,188,127,255,254, + 29,247,221,119,31,234,235,235,209,212,212,132,77,155,174,192,145,35,23,176, + 102,205,26,12,14,14,34,24,12,98,203,150,19,88,177,162,18,215,93,87, + 135,251,238,187,15,59,118,236,248,255,217,59,243,248,168,202,123,255,191,207, + 108,153,108,144,132,213,8,178,138,43,168,40,22,149,34,162,109,221,80,91, + 105,203,109,109,181,74,235,130,215,106,91,219,218,159,5,180,94,109,235,189, + 245,90,75,173,75,43,183,181,214,93,44,40,86,145,77,220,216,17,5,138, + 108,33,16,18,8,89,39,147,217,159,223,31,103,206,228,204,100,246,153,4, + 72,190,239,215,107,94,147,57,231,60,203,57,51,121,62,231,187,60,231,153, + 43,49,185,99,131,140,4,46,217,192,156,111,98,45,158,120,125,89,178,100, + 201,28,96,110,190,219,138,61,207,124,182,213,93,215,112,194,132,9,81,226, + 150,136,176,181,151,50,38,151,142,40,21,21,21,17,8,4,226,138,95,218, + 29,143,193,44,108,0,95,252,226,23,121,239,189,0,83,167,246,139,123,252, + 210,165,135,51,110,195,97,159,68,191,126,171,184,112,242,36,124,254,85,56, + 236,137,222,7,134,197,176,115,92,238,104,32,23,129,204,165,172,129,33,108, + 102,81,251,241,221,119,171,31,223,125,183,202,85,232,12,97,91,183,110,93, + 68,212,158,123,254,121,101,180,153,131,208,93,120,199,29,119,224,114,185,216, + 179,103,15,223,248,198,151,152,51,231,21,134,14,253,63,170,171,175,103,232, + 208,255,3,224,7,63,24,77,73,73,9,119,220,113,7,243,231,207,191,48, + 69,157,194,81,66,198,89,148,221,141,97,185,197,126,254,217,207,126,6,228, + 215,106,52,234,142,21,134,174,104,171,171,89,179,102,13,183,220,114,11,16, + 109,185,25,251,12,194,9,40,57,89,168,102,235,205,231,243,229,212,239,71, + 30,125,84,237,217,179,167,147,176,25,212,213,213,1,241,197,13,192,237,206, + 188,205,120,98,246,225,135,231,1,65,160,243,187,69,38,215,0,186,120,25, + 194,146,72,196,204,251,159,123,254,121,149,141,200,25,226,22,43,98,70,93, + 134,208,153,219,202,68,240,140,152,27,64,73,73,9,119,221,117,6,143,60, + 178,41,34,110,91,183,94,75,73,73,9,46,151,43,226,198,4,125,250,192, + 238,221,187,247,100,122,62,66,247,145,214,191,234,132,9,19,180,120,86,148, + 65,120,223,125,121,234,83,143,164,59,175,97,154,83,1,98,219,202,56,38, + 23,207,50,51,178,242,178,181,218,238,250,225,15,53,155,205,198,160,65,131, + 34,34,23,251,30,143,237,219,183,71,254,190,117,214,179,234,199,119,235,175, + 116,218,140,103,177,1,92,121,101,191,184,47,128,89,255,153,94,221,61,157, + 116,45,180,255,121,248,97,45,29,143,66,60,226,137,155,153,111,205,152,161, + 25,113,217,108,98,179,70,140,109,248,240,225,184,92,46,126,244,163,51,35, + 251,12,113,51,142,115,185,92,217,156,130,112,132,72,203,130,51,146,22,226, + 185,239,204,3,115,87,88,55,134,245,20,107,185,117,5,93,89,119,119,94, + 67,83,146,9,16,215,114,187,15,192,136,209,101,19,147,51,99,88,111,238, + 56,230,83,46,238,201,68,98,102,102,251,246,237,81,49,63,67,128,32,125, + 119,101,60,11,78,183,216,226,19,10,193,148,41,5,192,179,106,222,99,201, + 227,125,241,220,126,205,205,233,199,249,98,203,103,19,27,75,228,122,204,164, + 31,137,112,187,221,20,21,21,229,53,206,150,13,223,154,49,67,251,241,221, + 119,43,163,63,153,96,100,75,26,83,3,92,46,23,213,213,215,71,98,112, + 6,46,151,43,98,233,9,199,6,41,5,46,38,85,254,190,112,44,202,76, + 151,136,91,216,226,81,137,98,86,249,182,120,186,178,173,238,188,134,177,109, + 161,79,9,232,212,214,186,117,235,114,202,162,140,181,142,220,238,15,41,42, + 58,15,152,151,75,181,113,137,39,116,177,194,102,222,222,65,98,87,166,153, + 248,22,92,48,105,155,203,151,123,177,88,244,235,144,44,169,37,158,32,165, + 147,248,145,172,124,166,36,170,35,147,126,36,194,16,147,76,221,130,249,198, + 176,220,50,21,55,96,197,239,127,255,251,11,31,123,236,177,136,184,153,223, + 205,148,148,148,240,251,223,255,30,96,69,94,58,45,116,57,73,5,46,206, + 96,201,132,9,19,180,216,180,249,174,176,220,98,45,30,179,117,213,85,22, + 79,87,88,87,221,121,13,51,104,203,152,35,103,148,203,168,29,243,160,30, + 253,247,121,93,234,182,51,11,221,152,49,99,34,130,19,251,110,176,111,95, + 126,44,184,124,88,137,61,145,163,233,9,47,217,246,101,248,240,225,115,231, + 207,159,191,236,142,59,238,136,178,224,98,197,13,116,75,111,254,252,249,12, + 31,62,124,46,208,148,99,151,133,110,32,161,192,37,24,44,231,154,223,187, + 138,35,105,241,228,179,173,238,188,134,169,218,90,179,102,141,50,139,90,28, + 114,178,134,13,139,46,149,69,147,46,235,214,173,75,248,36,147,162,34,125, + 46,90,60,11,46,27,108,182,47,226,243,191,215,201,130,203,167,149,216,157, + 228,146,13,217,85,243,225,140,56,93,54,24,241,181,174,16,212,221,187,119, + 47,215,52,109,197,143,126,244,163,11,127,247,187,223,117,18,57,227,125,195, + 134,13,252,232,71,63,130,14,235,173,9,17,185,163,158,184,2,151,108,176, + 236,106,142,82,139,39,227,182,186,243,26,166,106,43,54,38,103,8,93,108, + 76,46,215,254,197,179,234,178,171,39,249,64,22,235,30,205,69,232,254,231, + 225,135,53,221,189,85,4,172,167,227,253,140,188,90,137,201,200,199,19,77, + 204,115,223,50,153,199,22,111,30,94,62,220,162,6,241,166,14,100,202,183, + 102,204,208,242,52,37,32,46,195,135,15,159,187,124,249,242,185,227,199,143, + 191,240,134,27,110,224,142,59,238,224,172,179,206,138,196,220,98,31,213,69, + 88,216,118,239,222,45,2,119,148,211,73,224,142,66,113,155,219,21,125,232, + 202,182,142,70,113,51,237,143,27,147,203,164,127,255,243,240,117,154,33,50, + 249,176,214,242,69,182,66,23,111,192,52,206,47,95,86,98,44,137,4,201, + 252,57,219,24,89,166,2,101,62,62,159,226,6,249,19,163,174,76,98,9, + 79,216,158,50,98,196,136,41,243,231,207,159,27,103,158,155,33,108,208,97, + 185,137,184,29,3,196,179,224,140,135,242,70,13,124,97,23,87,218,63,178, + 108,142,143,233,195,17,19,133,60,16,247,26,198,235,135,249,26,101,122,205, + 82,181,213,149,22,234,145,20,54,189,237,103,195,15,100,142,127,140,201,163, + 153,23,186,74,232,160,179,168,228,91,100,50,105,187,55,99,22,186,56,187, + 205,162,214,36,214,219,177,65,220,213,4,140,1,48,222,96,153,206,0,156, + 201,177,230,227,195,28,235,226,102,180,51,55,89,221,241,174,81,166,215,45, + 89,91,249,56,207,100,171,9,196,227,104,180,234,178,229,199,119,63,171,18, + 61,45,197,204,210,165,135,123,196,249,246,38,98,87,19,136,71,130,53,224, + 226,10,155,172,38,112,244,146,201,114,57,25,127,137,25,8,220,92,210,176, + 120,242,65,119,182,21,167,237,46,187,134,73,218,201,250,60,51,21,184,158, + 132,57,206,151,202,74,20,129,59,182,80,154,38,130,212,75,200,248,81,93, + 153,88,112,25,212,57,215,148,0,49,55,211,62,29,173,109,197,105,59,169, + 181,150,173,5,103,230,72,198,80,123,18,34,90,130,112,236,147,145,192,165, + 59,240,134,227,60,25,139,92,38,199,231,194,209,48,224,39,186,70,121,88, + 113,59,173,248,159,32,8,66,79,39,109,23,165,112,236,144,42,254,151,46, + 189,217,69,41,244,92,196,69,217,123,56,234,87,19,16,50,39,95,86,155, + 12,4,130,32,28,203,200,194,31,130,32,8,66,143,68,4,78,16,4,65, + 232,145,104,162,112,130,112,108,33,174,99,65,72,15,209,55,65,16,4,161, + 71,34,73,38,66,175,37,4,121,181,132,44,16,53,197,163,171,235,23,4, + 33,57,81,46,202,238,252,135,148,182,114,111,171,187,200,247,57,153,201,199, + 249,165,234,95,46,109,204,251,253,124,5,48,235,142,27,186,228,123,200,166, + 126,113,81,10,66,122,68,89,112,233,14,4,198,63,101,42,102,221,113,67, + 194,125,221,217,214,227,191,159,159,78,21,121,25,196,186,179,173,116,184,226, + 202,105,10,224,141,69,11,179,110,207,2,90,8,148,249,220,110,189,227,134, + 168,239,48,215,253,185,162,18,60,95,80,211,142,248,253,129,32,8,71,136, + 156,98,112,143,254,229,236,184,239,153,50,230,204,205,42,222,123,87,144,175, + 62,231,139,174,62,247,133,139,22,178,112,209,194,124,86,121,68,8,129,50, + 94,93,81,127,58,223,67,38,223,85,87,252,134,187,242,255,66,16,122,34, + 89,197,224,204,162,16,79,48,126,120,227,186,180,235,74,52,104,116,252,51, + 167,95,87,42,18,137,219,145,16,57,243,96,21,239,220,183,111,28,155,87, + 215,93,8,212,209,224,238,204,133,119,151,182,3,112,241,212,194,188,158,75, + 242,223,224,186,148,199,196,126,87,249,254,30,99,127,43,255,222,40,9,190, + 229,0,0,32,0,73,68,65,84,52,46,215,42,5,161,87,144,117,146,201, + 5,19,138,227,110,127,127,77,219,17,173,235,104,106,43,21,93,217,23,67, + 220,12,33,48,172,159,92,133,33,213,13,76,174,251,187,27,67,60,98,191, + 139,63,63,53,146,155,190,191,43,242,249,130,9,197,157,182,129,254,93,197, + 10,153,81,87,178,239,49,222,119,145,236,251,49,247,239,223,155,82,157,149, + 32,8,144,194,69,153,200,37,148,104,96,54,246,173,221,60,57,173,198,191, + 247,253,93,202,168,235,207,79,141,228,207,79,141,76,187,157,76,89,187,121, + 114,202,126,199,210,149,46,177,120,3,170,113,254,23,76,40,230,123,223,223, + 149,83,187,241,6,202,124,136,219,5,19,138,19,90,188,185,238,79,151,119, + 151,182,231,45,241,229,130,9,197,113,191,139,68,196,251,141,38,250,93,37, + 250,30,147,245,61,211,255,55,65,16,18,147,84,224,204,119,255,93,221,17, + 227,206,56,217,224,210,157,196,90,64,93,137,113,206,177,214,65,174,84,86, + 86,70,68,186,178,178,50,231,250,140,129,54,217,128,158,203,254,88,98,227, + 110,23,79,45,204,172,195,89,144,236,187,200,199,111,52,217,239,170,59,255, + 223,4,161,55,144,50,201,164,55,138,92,79,16,55,128,218,154,26,45,222, + 223,199,2,33,80,239,46,109,39,246,101,136,92,62,173,56,131,116,190,139, + 92,126,163,233,252,174,68,228,4,33,127,164,21,131,51,210,196,187,35,81, + 225,166,239,239,138,184,235,186,98,208,79,69,79,17,55,128,31,252,231,45, + 234,79,143,253,41,242,247,147,143,253,233,152,16,57,67,220,226,97,136,92, + 162,253,233,18,235,58,52,11,86,212,223,73,234,48,255,70,141,250,158,121, + 106,100,167,107,252,189,239,239,82,230,58,205,226,101,184,243,227,9,90,174, + 110,106,65,232,237,68,4,46,217,63,188,153,116,239,44,83,197,225,204,237, + 37,106,235,207,79,141,132,52,7,255,239,125,127,151,138,55,184,164,211,23, + 131,216,172,67,243,190,88,17,74,52,144,173,221,156,86,83,9,7,84,115, + 91,201,206,41,29,12,113,51,254,238,105,207,101,11,139,93,86,34,96,92, + 87,227,119,104,220,88,25,127,27,156,51,118,37,16,253,27,138,119,92,178, + 239,233,153,167,70,106,22,226,223,60,157,51,118,165,46,140,49,115,6,227, + 245,81,16,132,204,136,8,92,236,63,104,236,96,24,243,207,153,242,31,238, + 156,177,43,121,38,201,254,103,158,26,169,153,7,23,51,230,1,196,24,96, + 82,145,108,226,244,57,99,87,166,37,114,134,165,106,252,29,211,223,148,229, + 159,121,106,164,150,238,196,116,18,12,168,177,245,165,85,87,28,174,184,114, + 154,90,184,104,97,148,203,235,138,43,167,169,76,39,124,167,18,217,100,251, + 141,125,177,22,76,38,245,119,39,233,120,15,114,177,186,211,241,132,116,167, + 7,65,16,122,58,105,221,212,247,36,183,93,42,122,74,204,209,44,110,160, + 159,87,54,19,190,205,55,34,177,152,5,44,89,217,84,2,152,113,167,186, + 144,100,223,73,62,126,155,201,126,95,34,110,130,144,95,82,10,92,111,18, + 55,131,99,93,228,198,159,125,78,194,126,39,219,151,136,68,34,100,108,79, + 229,158,203,102,95,58,92,60,181,48,231,223,229,251,107,218,58,205,87,75, + 39,201,36,89,249,216,253,177,164,147,100,98,230,153,167,70,106,71,98,158, + 166,32,28,235,36,77,50,233,141,226,102,112,44,39,214,172,93,183,54,97, + 26,250,218,117,107,213,209,30,139,179,128,118,241,212,194,184,137,38,249,72, + 48,49,179,125,227,88,109,204,153,155,85,172,128,156,124,230,102,222,95,211, + 198,57,99,245,207,239,175,105,139,108,139,87,135,249,115,58,98,148,205,60, + 69,17,57,65,200,140,148,243,224,226,253,211,165,186,99,77,55,110,102,190, + 51,189,233,251,187,226,222,29,231,139,115,198,174,204,234,78,187,171,196,45, + 158,213,96,156,255,251,107,218,178,182,110,198,159,119,78,82,65,182,128,54, + 254,188,204,173,184,238,38,44,114,196,190,76,143,235,202,219,141,151,33,80, + 137,222,211,61,38,222,177,249,120,84,87,170,246,4,65,136,79,214,143,234, + 202,167,248,116,231,157,233,209,116,23,220,21,125,89,251,225,218,148,126,231, + 116,142,137,199,251,107,218,184,96,66,113,194,126,231,186,63,150,216,213,8, + 242,105,185,197,146,169,112,37,58,38,246,216,174,232,163,32,8,233,145,149, + 183,202,120,150,96,188,247,76,159,51,104,190,203,205,100,0,201,6,115,255, + 18,189,119,23,201,206,57,219,243,30,127,118,114,235,205,192,2,90,54,177, + 184,31,222,184,142,247,215,180,37,188,86,185,238,79,151,124,90,111,130,32, + 244,92,178,182,224,242,45,16,93,45,110,102,142,180,184,25,228,251,156,215, + 175,91,155,118,249,76,142,53,147,234,90,229,186,191,59,73,39,137,232,214, + 142,117,6,83,30,155,205,138,222,185,212,47,8,66,114,162,4,46,221,172, + 65,211,63,101,82,146,153,135,221,217,86,186,117,144,102,159,146,13,52,221, + 217,86,111,195,120,76,87,190,174,73,87,95,91,249,238,4,225,200,146,213, + 138,222,249,64,218,18,50,65,174,171,32,8,153,162,29,237,41,227,194,145, + 167,43,231,3,230,67,184,82,245,175,167,137,163,210,180,163,62,11,86,16, + 142,6,68,224,132,94,135,8,132,32,244,14,68,223,4,65,16,132,30,137, + 8,156,32,8,130,208,35,17,23,165,32,28,99,136,139,85,16,210,67,244, + 77,16,4,65,232,145,100,61,209,91,16,142,117,238,254,217,207,242,106,9, + 61,252,155,223,68,101,107,206,189,255,254,188,214,63,119,246,236,30,149,13, + 42,8,93,77,148,139,242,151,115,230,228,245,31,242,87,247,221,151,240,31, + 82,218,202,189,173,238,34,223,231,100,38,31,231,151,170,127,185,180,241,254, + 170,181,10,224,130,73,231,116,201,247,176,250,227,141,10,224,220,47,156,153, + 118,253,226,162,20,132,244,200,42,6,247,209,71,27,210,250,7,155,56,241, + 172,156,7,133,124,180,117,172,245,55,159,252,237,239,127,87,0,223,249,246, + 183,115,106,239,151,115,230,168,43,46,187,38,242,249,141,197,11,162,132,35, + 215,253,185,246,109,238,220,185,113,247,205,157,59,87,4,78,16,122,41,57, + 197,224,62,222,112,92,220,247,76,121,244,241,90,21,239,189,43,200,87,159, + 243,69,87,159,251,246,237,219,217,190,125,123,62,171,60,34,252,114,206,28, + 101,188,186,162,254,223,254,239,1,21,239,61,211,99,12,30,123,162,46,239, + 253,236,138,58,5,161,39,147,149,192,125,188,225,184,132,66,145,169,96,36, + 26,224,31,125,188,86,229,123,176,79,214,231,238,22,58,243,249,117,149,200, + 153,197,160,43,221,140,221,197,119,175,255,127,124,247,250,255,151,247,115,73, + 36,92,102,1,75,231,24,3,67,136,242,37,72,143,61,81,167,242,93,167, + 32,244,6,178,182,224,134,86,58,226,190,142,116,93,71,83,91,71,178,47, + 134,8,252,234,190,251,52,195,69,151,15,97,72,117,35,144,235,254,238,198, + 16,168,97,67,28,81,175,67,7,254,151,97,67,58,190,11,243,54,243,203, + 92,135,193,208,74,59,67,43,237,73,219,141,151,128,146,44,41,197,168,51, + 85,189,130,32,116,144,84,224,18,185,132,146,13,194,67,43,29,212,212,13, + 75,171,241,87,95,111,80,70,93,27,214,63,202,134,245,143,166,221,78,166, + 212,212,13,75,217,239,88,186,210,37,22,219,158,249,252,135,86,58,120,245, + 245,134,156,218,141,23,119,202,53,230,245,241,134,227,24,90,233,72,40,82, + 185,238,79,151,124,90,113,102,161,50,88,187,230,183,9,143,143,221,23,175, + 188,193,208,74,59,11,22,118,254,30,147,9,89,188,125,34,106,130,144,29, + 73,5,46,159,119,254,169,56,107,252,15,1,58,137,220,145,194,108,1,117, + 117,91,198,57,27,215,32,95,148,150,150,70,68,186,180,180,52,231,250,12, + 81,78,116,163,144,235,254,88,98,227,110,127,253,191,255,202,172,195,89,96, + 8,216,57,19,126,218,105,159,177,45,153,0,166,194,16,176,120,41,255,198, + 182,124,79,47,16,132,222,74,74,23,101,111,20,185,158,32,110,0,63,253, + 201,79,180,120,127,31,11,252,114,206,28,101,196,220,204,47,67,228,186,34, + 22,151,76,220,12,114,17,185,100,226,22,57,70,68,78,16,242,70,90,19, + 189,127,117,223,125,154,113,39,221,213,131,254,89,227,127,24,113,215,117,197, + 160,159,138,158,34,110,0,175,191,177,80,173,93,189,54,242,247,213,87,76, + 59,38,68,206,16,183,120,24,34,151,104,127,186,188,240,242,225,40,1,49, + 11,86,212,223,73,234,88,187,230,183,17,193,51,234,251,230,244,126,157,174, + 241,130,133,13,106,227,134,63,68,62,155,197,171,230,224,9,157,182,153,203, + 165,58,15,65,16,18,19,17,184,216,152,79,34,43,42,221,187,230,84,113, + 56,115,123,137,218,218,176,254,81,72,115,240,127,245,245,6,245,181,171,43, + 226,14,224,233,198,4,147,101,29,198,138,80,188,182,94,125,189,65,213,212, + 165,213,84,212,57,199,158,191,209,86,178,115,74,7,67,220,98,255,238,41, + 132,69,46,43,17,48,132,200,16,166,115,38,252,52,174,5,55,100,240,110, + 0,246,213,142,136,108,139,119,92,60,97,51,184,102,90,69,148,85,102,182, + 224,86,127,124,149,2,184,198,180,205,56,206,40,39,66,39,8,217,17,17, + 184,84,3,169,217,178,121,245,245,31,166,252,135,171,28,84,149,116,255,215, + 174,174,208,12,145,139,21,15,179,101,147,170,30,131,100,19,167,43,7,85, + 165,37,114,134,165,106,252,29,189,247,190,148,229,191,118,117,133,150,238,68, + 111,194,150,42,36,182,224,114,17,183,191,253,253,239,106,251,246,237,81,46, + 230,191,253,253,239,42,211,9,223,169,68,54,217,126,99,223,171,175,55,168, + 68,55,49,185,138,120,62,49,68,206,108,153,197,146,142,27,51,17,115,103, + 207,214,230,222,127,191,154,123,255,253,42,145,155,50,29,55,166,32,8,233, + 145,214,52,129,158,228,182,75,69,79,137,57,154,197,13,244,243,202,102,194, + 183,249,70,36,22,179,128,37,43,155,74,0,51,238,84,23,146,44,198,150, + 139,184,25,36,139,177,137,184,9,66,126,73,41,112,189,73,220,12,142,117, + 145,123,252,79,79,36,236,119,178,125,137,72,36,66,198,246,100,34,149,237, + 190,116,248,235,255,253,87,206,191,203,170,125,62,170,246,249,162,182,165,147, + 100,146,172,188,153,234,26,127,167,109,233,36,153,152,185,102,90,133,22,175, + 30,65,16,146,147,114,30,28,244,46,113,51,56,150,69,174,230,64,77,194, + 121,112,53,7,106,242,210,70,87,242,171,251,238,211,18,77,9,200,71,130, + 137,153,159,222,121,156,6,29,66,101,188,6,28,119,103,148,112,153,183,153, + 95,230,58,12,170,107,252,145,87,34,146,77,19,72,68,170,58,5,65,136, + 38,229,60,184,120,3,101,117,77,178,59,86,95,218,113,179,175,93,93,161, + 25,117,157,53,254,135,157,196,45,89,59,153,82,57,168,42,101,191,99,73, + 116,254,249,32,182,61,243,249,87,215,248,178,182,110,30,127,234,137,164,153, + 174,191,186,239,62,237,241,167,50,183,226,186,27,67,228,98,95,134,184,229, + 195,122,51,48,4,42,209,123,186,199,24,252,231,205,131,52,227,221,248,59, + 87,204,117,230,163,62,65,232,13,100,189,30,92,62,197,39,159,117,29,77, + 109,165,162,43,250,82,179,47,181,133,150,206,49,241,168,174,241,49,180,210, + 145,176,223,185,238,143,37,118,53,130,124,90,110,177,164,35,92,233,28,99, + 208,21,66,36,226,38,8,153,145,213,179,40,191,112,214,129,132,239,198,223, + 233,242,195,91,7,107,63,188,117,176,102,252,29,239,61,95,152,251,151,232, + 189,187,72,118,206,217,158,247,227,127,74,110,189,25,252,234,190,251,180,108, + 98,113,95,56,235,0,213,53,190,132,215,42,215,253,233,146,79,235,77,16, + 132,158,75,214,22,92,190,5,162,171,197,205,204,145,22,55,131,124,159,243, + 173,183,220,156,118,249,76,142,53,147,234,90,229,186,191,59,73,103,69,239, + 5,11,95,74,251,216,108,86,244,126,243,95,255,76,251,88,201,174,20,132, + 204,136,18,184,116,19,42,222,88,188,32,231,134,187,179,173,116,235,72,183, + 79,201,172,135,238,108,171,183,97,36,158,228,235,154,196,10,82,190,17,65, + 18,132,35,75,148,192,117,231,96,42,109,9,153,32,215,85,16,132,76,209, + 114,90,210,91,232,21,116,229,84,137,124,8,87,170,254,245,52,113,84,154, + 118,212,103,193,10,194,209,128,8,156,208,235,16,129,16,132,222,129,232,155, + 32,8,130,208,35,17,129,19,4,65,16,122,36,89,79,19,16,132,163,17, + 113,63,10,130,96,32,22,156,32,8,130,208,35,17,129,19,4,65,16,122, + 36,41,93,148,33,211,138,201,22,72,154,110,157,201,177,169,202,230,179,174, + 124,29,155,170,172,244,57,63,199,166,42,155,75,93,130,32,244,30,210,178, + 224,150,46,109,98,233,210,166,168,129,38,150,16,40,227,184,76,73,84,54, + 157,118,1,130,74,169,160,82,81,199,164,219,103,165,20,49,69,211,238,115, + 188,178,233,246,57,30,71,251,117,142,135,113,13,178,233,115,188,239,45,221, + 178,233,180,43,8,66,239,70,92,148,130,32,8,66,143,36,35,129,75,116, + 151,111,220,101,103,67,58,101,147,89,23,169,44,128,100,125,206,198,114,75, + 183,108,182,22,81,178,178,71,242,58,167,34,145,53,149,78,187,137,190,195, + 116,202,138,21,39,8,66,34,226,10,92,8,148,241,2,152,58,181,44,237, + 10,141,99,99,235,200,180,108,166,237,106,154,70,182,125,214,52,45,235,62, + 155,203,102,218,238,177,120,157,99,219,51,206,63,155,62,103,91,54,211,118, + 5,65,232,157,116,122,84,87,162,187,230,169,83,203,34,113,144,169,83,203, + 34,193,125,243,241,230,99,98,203,198,75,6,72,183,108,188,118,161,227,206, + 95,211,180,140,202,154,45,176,100,101,19,245,57,157,178,137,250,28,175,30, + 51,230,58,147,93,231,68,101,211,185,206,153,180,155,168,158,216,243,53,95, + 147,76,127,27,70,89,171,73,181,50,45,107,180,43,243,224,4,65,48,136, + 210,183,100,46,161,165,75,155,146,222,233,39,26,132,140,178,201,44,140,84, + 101,147,181,155,72,100,242,81,54,89,159,115,105,55,153,139,83,41,149,242, + 58,39,43,155,234,58,103,219,110,170,223,70,50,139,42,213,247,219,85,101, + 5,65,232,221,100,149,100,98,12,254,93,29,19,74,212,46,164,142,189,37, + 42,219,213,177,183,68,237,102,211,222,209,112,157,51,197,16,217,108,218,53, + 190,211,108,202,74,44,78,16,132,88,36,139,82,16,4,65,232,145,136,192, + 9,130,32,8,61,146,172,4,206,72,66,176,128,150,73,6,94,76,195,25, + 151,53,39,63,88,51,12,190,152,251,156,109,220,38,155,178,137,18,54,50, + 41,123,36,175,115,166,24,201,30,217,180,107,124,167,217,148,77,148,96,35, + 8,66,239,197,18,243,33,225,192,146,44,216,15,201,19,43,82,13,152,169, + 202,38,107,55,89,114,68,174,101,147,245,57,151,118,147,9,101,178,228,21, + 72,158,88,145,106,144,79,85,54,85,159,147,157,111,178,216,100,170,239,183, + 171,202,10,130,208,187,137,187,162,119,188,96,125,178,20,242,216,148,238,88, + 146,13,186,169,202,166,74,93,55,79,21,200,180,207,230,20,243,76,251,156, + 172,108,170,62,155,235,201,180,207,71,234,58,39,235,115,188,41,2,233,182, + 27,111,138,64,166,101,205,237,202,52,1,65,16,12,226,186,40,13,23,147, + 49,104,100,146,209,102,28,27,91,71,166,101,51,109,87,41,69,182,125,54, + 6,202,108,250,108,46,155,105,187,199,226,117,142,109,47,19,11,42,182,207, + 217,150,205,180,93,65,16,122,39,25,197,224,18,221,221,119,117,140,40,153, + 85,145,42,22,151,172,207,93,25,139,203,71,236,45,94,187,71,234,58,167, + 34,145,123,52,157,118,19,125,135,233,148,149,216,155,32,8,137,144,44,74, + 65,16,4,161,71,18,55,6,103,230,88,92,243,75,250,156,126,217,158,214, + 103,137,193,9,130,96,144,82,224,4,225,88,66,4,78,16,4,3,209,55, + 65,16,4,161,71,34,2,39,8,130,32,244,72,108,0,51,239,95,175,124, + 158,86,0,28,206,82,158,158,61,62,42,174,97,236,143,221,151,104,123,60, + 242,81,71,170,186,99,251,111,222,110,179,21,242,151,251,207,237,242,108,187, + 124,181,105,212,19,91,71,162,237,249,170,35,213,111,33,114,220,236,213,202, + 231,115,227,112,20,81,82,62,132,255,189,171,50,175,215,86,92,141,130,32, + 228,138,246,131,251,215,171,141,171,230,83,191,111,11,0,253,135,156,202,153, + 147,110,136,12,108,215,222,246,146,250,247,198,133,184,93,245,84,12,30,205, + 184,137,215,241,151,251,207,213,98,183,155,203,196,146,143,58,226,113,227,236, + 213,234,80,205,22,118,111,89,138,171,169,38,170,255,0,230,243,42,41,171, + 100,196,169,83,25,80,121,106,218,194,16,10,4,83,246,193,98,179,70,132, + 96,102,204,181,204,164,205,216,246,55,174,154,79,67,237,14,138,74,250,115, + 210,153,211,120,229,143,95,215,110,156,189,90,125,242,209,179,157,182,231,171, + 142,216,254,199,254,22,12,190,251,243,229,106,251,39,111,210,112,112,7,197, + 197,253,56,126,212,4,42,6,142,161,98,208,152,78,66,103,8,97,200,231, + 75,125,45,29,14,28,142,34,158,190,255,92,89,215,77,16,132,156,177,249, + 60,173,212,239,219,194,242,183,254,66,109,109,45,51,110,248,5,30,151,62, + 169,246,218,219,94,82,159,126,244,15,170,118,188,207,234,15,222,229,170,111, + 220,73,115,125,21,211,102,206,239,180,221,40,19,75,62,234,136,197,16,182, + 213,75,254,64,227,161,93,28,174,251,156,109,159,174,137,234,191,197,102,141, + 156,87,75,75,11,231,158,127,49,141,135,118,81,62,96,36,211,102,206,87, + 137,68,199,60,200,251,253,158,148,125,177,219,157,244,31,114,106,68,20,179, + 105,51,22,115,61,39,159,62,1,191,199,197,180,153,243,85,115,125,85,167, + 237,215,222,246,146,138,39,114,217,212,225,113,53,37,252,45,0,220,249,72, + 141,106,168,219,78,205,174,213,236,219,241,62,239,191,251,60,167,157,113,30, + 135,14,108,97,192,113,167,114,252,168,9,124,247,231,203,149,33,116,51,103, + 175,86,255,222,244,79,234,246,111,193,231,107,75,121,45,29,142,98,6,29, + 127,42,51,103,175,86,79,253,234,11,41,143,23,4,65,72,134,45,20,8, + 226,247,123,104,105,105,161,169,169,9,191,223,67,187,235,112,148,0,25,226, + 225,106,58,64,213,142,247,104,168,221,65,205,158,117,108,251,116,13,123,247, + 238,77,40,4,102,113,203,182,14,51,137,132,173,165,165,133,218,218,218,72, + 255,1,140,243,50,88,190,100,33,69,69,69,41,69,199,44,12,201,104,105, + 105,1,192,237,118,71,9,65,54,109,198,98,238,251,242,37,11,153,114,201, + 52,252,1,15,21,131,71,227,106,58,16,181,221,184,206,177,34,151,105,29, + 211,102,206,87,237,174,195,157,126,11,6,119,62,82,163,170,63,127,143,93, + 159,45,161,118,239,38,154,15,87,225,243,249,248,104,213,219,4,2,1,38, + 77,185,188,147,208,53,214,239,166,122,247,26,86,188,241,180,126,109,147,88, + 113,94,175,151,182,182,54,190,115,235,67,140,56,229,146,164,215,94,16,4, + 33,29,108,230,15,129,64,0,111,91,99,39,1,50,196,163,181,169,134,127, + 175,95,136,207,221,196,191,183,109,162,182,182,54,50,208,199,18,79,220,50, + 173,195,32,145,176,1,145,193,184,161,161,1,151,203,133,221,238,236,84,222, + 237,118,211,212,212,132,207,231,75,41,58,102,97,104,105,105,193,237,118,39, + 28,152,221,110,55,129,64,32,114,188,197,102,197,110,119,70,250,100,148,205, + 86,232,140,235,242,246,155,175,240,165,47,79,227,80,205,86,124,238,166,168, + 237,95,190,252,218,200,245,142,103,201,165,91,135,33,126,222,182,70,64,255, + 45,152,169,254,252,61,54,175,126,129,154,93,171,249,108,211,135,248,124,62, + 188,94,47,77,77,186,176,191,181,232,69,236,118,59,23,127,229,171,17,161, + 43,41,27,68,192,227,2,160,177,177,17,175,215,139,223,239,143,123,174,134, + 192,249,124,109,105,185,51,5,65,16,82,97,139,221,16,43,64,198,96,237, + 241,120,240,122,154,241,122,154,217,179,103,15,45,45,45,212,215,215,199,21, + 149,88,113,203,166,14,72,79,216,90,90,90,112,185,92,4,2,1,102,222, + 114,23,163,79,255,10,14,103,9,190,240,192,10,29,150,131,219,237,78,41, + 58,181,123,214,18,240,186,35,199,27,3,120,60,2,129,0,46,87,71,59, + 14,103,41,101,3,71,113,238,249,23,179,224,229,191,17,8,4,104,105,105, + 193,102,179,101,36,116,134,80,26,125,119,187,221,188,243,246,66,38,79,158, + 28,117,78,110,183,59,161,200,101,90,135,89,252,98,153,57,123,181,90,183, + 226,41,106,118,173,102,195,154,21,180,182,182,210,214,214,134,203,229,194,239, + 247,71,221,0,60,247,215,63,81,92,92,204,117,55,254,140,210,182,33,180, + 53,31,140,136,161,249,90,153,49,234,112,187,221,9,175,181,32,8,66,166, + 68,9,156,205,102,235,36,64,53,53,53,184,92,46,166,79,159,14,192,39, + 159,124,18,177,198,154,154,154,162,68,5,226,139,91,166,117,100,42,108,55, + 205,156,69,89,255,17,140,62,253,43,156,116,230,52,254,114,255,185,218,117, + 63,93,154,48,73,33,145,208,29,218,247,41,193,128,151,214,112,194,74,50, + 151,26,232,2,103,182,116,158,158,61,94,187,246,182,151,84,192,215,206,245, + 51,127,78,83,253,110,94,121,249,239,25,11,157,89,40,223,126,243,149,72, + 159,87,174,92,201,228,201,147,25,55,110,28,43,87,174,140,108,143,39,114, + 153,214,17,43,126,102,124,62,55,141,141,123,217,176,102,69,196,82,54,11, + 155,33,76,129,64,128,239,205,188,149,2,103,41,0,30,119,35,174,214,131, + 0,17,203,45,145,5,103,148,23,4,65,200,23,81,2,87,84,84,4,232, + 2,148,72,152,128,136,48,221,52,115,22,199,143,62,47,34,42,51,239,95, + 175,214,46,125,34,165,184,165,170,99,227,170,249,28,216,189,190,147,176,25, + 22,149,203,229,194,227,241,112,211,204,89,148,150,85,50,252,228,139,24,51, + 254,170,140,179,21,205,66,247,246,155,175,224,112,56,152,56,113,98,164,189, + 108,48,50,21,15,213,108,97,251,250,127,114,195,204,187,105,109,170,225,245, + 5,47,36,108,115,202,37,211,104,60,180,139,1,199,159,198,204,251,215,43, + 67,40,91,26,170,249,210,151,167,241,206,219,11,35,229,222,122,235,45,46, + 189,244,82,38,79,158,204,202,149,43,35,219,23,188,252,55,174,153,254,29, + 236,206,18,110,156,189,58,171,58,12,241,139,197,112,25,54,52,52,80,87, + 87,199,85,87,93,13,192,63,255,249,58,62,159,15,155,205,198,244,233,95, + 7,160,164,236,56,74,251,86,210,218,92,195,123,203,94,231,244,211,199,102, + 117,29,5,65,16,114,37,106,162,183,49,248,25,66,18,8,4,34,194,244, + 209,71,31,1,68,182,207,152,49,3,71,81,25,149,67,206,140,164,153,251, + 60,173,180,52,84,71,196,205,136,81,101,90,71,67,237,14,22,191,246,39, + 86,127,240,110,84,2,137,185,79,215,93,119,29,142,162,50,134,140,153,196, + 152,241,87,177,240,233,27,180,108,230,156,25,214,85,67,67,3,245,245,245, + 188,245,214,91,17,17,206,150,191,220,127,174,182,240,233,27,180,49,227,175, + 98,200,152,73,56,138,202,184,244,210,75,185,244,210,75,35,55,17,70,155, + 181,181,181,188,252,252,51,252,121,222,108,90,26,170,49,230,160,189,242,199, + 175,107,149,195,207,196,81,84,198,228,201,147,41,42,42,138,184,68,223,122, + 235,45,128,78,219,159,127,246,41,92,77,53,4,2,237,89,213,209,210,210, + 194,202,149,43,35,215,57,22,191,223,207,181,223,248,54,37,101,199,97,119, + 150,80,81,81,193,244,233,95,143,136,219,170,85,239,225,245,180,210,218,92, + 131,55,124,30,160,199,215,4,65,16,186,155,40,129,11,4,2,92,122,233, + 165,145,4,9,155,205,198,162,69,139,0,152,56,113,98,228,78,223,216,238, + 115,55,81,179,111,35,215,222,246,146,2,61,6,213,167,98,40,39,159,62, + 33,98,165,100,83,71,197,224,209,92,246,213,91,56,247,252,139,169,169,169, + 137,184,36,3,129,0,54,155,141,183,222,122,139,149,43,87,226,115,55,177, + 111,251,42,182,175,255,39,211,102,206,87,55,206,94,157,246,220,169,64,32, + 128,199,227,193,227,241,224,114,185,112,185,92,52,53,53,113,233,165,151,50, + 110,220,184,156,226,65,55,206,94,173,166,205,156,175,182,175,255,39,251,182, + 175,194,231,110,98,207,158,61,17,225,52,68,198,120,93,59,253,219,220,52, + 235,126,250,84,12,197,17,118,239,93,123,219,75,170,102,207,198,72,89,163, + 28,192,165,151,94,10,116,88,195,198,121,204,184,238,251,148,148,85,98,179, + 21,102,85,135,203,229,98,242,228,201,145,27,19,3,139,195,17,249,187,192, + 89,74,105,223,74,10,156,165,76,154,244,69,0,54,110,220,192,198,141,27, + 176,219,237,248,61,46,92,77,7,216,178,121,61,109,109,109,81,109,10,130, + 32,116,39,113,31,213,101,12,126,64,68,80,64,23,40,195,2,177,217,108, + 188,190,224,5,106,246,172,227,223,27,23,70,220,98,163,78,189,132,97,163, + 47,136,164,159,103,83,199,184,137,215,49,254,194,153,140,62,253,43,92,63, + 243,231,92,125,205,55,129,206,49,175,21,203,255,197,210,183,95,160,106,199, + 251,172,95,241,52,171,151,252,33,34,148,137,48,11,155,241,50,226,120,63, + 254,249,127,211,127,240,41,20,56,251,70,250,152,41,215,222,246,146,90,189, + 228,15,172,95,241,52,85,59,222,103,237,71,139,163,146,117,26,26,26,34, + 22,146,209,230,137,103,78,99,252,133,51,25,63,249,166,200,132,241,157,91, + 150,232,215,37,92,182,165,165,5,143,199,19,229,234,117,187,221,145,237,51, + 111,185,139,97,163,47,136,114,245,102,90,199,140,25,51,0,221,85,109,179, + 117,120,175,29,142,34,6,15,57,131,25,55,220,141,221,94,24,177,208,170, + 170,246,240,249,231,219,1,34,73,36,171,86,189,199,199,31,127,68,93,93, + 29,141,141,141,89,93,67,65,16,132,124,208,41,139,178,192,217,23,71,81, + 25,87,95,243,205,72,220,38,16,8,176,104,209,34,174,188,242,202,168,184, + 77,32,16,224,229,231,159,225,246,159,252,46,146,181,248,202,31,191,174,25, + 34,243,229,203,175,229,237,55,95,201,184,14,195,213,104,126,82,201,77,183, + 220,155,52,105,3,136,136,234,141,179,87,43,115,22,165,129,33,102,102,161, + 52,18,84,78,60,115,26,35,78,157,74,123,203,65,54,127,244,124,202,11, + 23,207,42,137,196,32,183,191,199,230,245,43,128,228,73,49,70,155,241,230, + 226,53,29,220,25,113,245,238,221,187,151,166,166,38,174,187,238,58,160,67, + 152,234,235,235,35,73,58,195,70,95,192,233,19,255,35,202,213,155,73,29, + 55,205,156,69,105,197,48,124,238,38,28,38,139,13,224,233,251,207,213,190, + 251,243,229,170,164,164,63,219,54,190,206,162,151,31,199,102,179,69,82,255, + 141,236,200,182,182,182,136,213,230,243,249,34,174,75,131,100,9,38,130,32, + 8,249,166,147,192,149,150,85,50,100,204,36,90,26,170,35,2,101,220,225, + 27,226,103,36,45,24,219,99,39,105,199,19,185,76,235,128,204,132,14,96, + 193,203,127,227,150,59,127,27,53,69,192,72,22,49,91,107,208,89,216,12, + 145,185,238,167,75,213,214,13,255,4,58,230,185,37,114,177,197,110,55,68, + 101,243,250,21,89,9,155,129,121,242,189,225,162,53,11,16,16,149,129,26, + 43,110,217,212,113,252,232,243,232,83,49,148,125,219,87,117,178,224,0,254, + 250,235,41,218,119,127,190,92,185,92,245,92,57,253,86,26,106,119,176,240, + 245,231,59,101,83,26,215,235,182,219,239,166,124,192,200,72,22,165,215,235, + 77,154,149,154,42,99,85,16,4,33,83,34,163,152,49,56,21,20,151,51, + 116,244,121,192,121,216,109,78,190,124,249,181,145,57,93,177,226,103,108,143, + 71,172,200,101,83,135,65,42,161,51,91,102,241,132,210,16,25,72,44,108, + 198,177,198,252,49,227,122,24,226,148,12,99,190,89,60,81,201,68,216,98, + 113,187,221,17,247,163,89,128,220,110,55,46,151,43,161,184,101,83,199,152, + 241,87,1,112,104,255,103,157,98,112,6,127,253,245,20,109,230,236,213,170, + 255,224,209,236,223,185,134,235,110,252,25,205,135,171,120,254,185,63,227,243, + 249,8,4,2,252,224,150,187,232,219,111,24,39,157,165,215,87,187,119,83, + 100,18,119,162,122,13,140,125,150,24,11,82,16,4,33,27,108,198,128,110, + 220,65,219,237,78,250,86,156,192,179,191,157,26,17,168,107,166,127,135,231, + 159,125,138,130,226,114,70,157,122,9,62,95,27,118,155,51,178,61,222,36, + 109,136,22,185,108,235,48,147,72,232,154,155,246,243,236,252,199,9,4,2, + 145,122,140,243,50,38,152,167,43,50,14,103,41,253,135,156,202,140,27,126, + 145,209,179,40,157,37,101,248,60,173,17,113,244,120,60,92,127,195,205,89, + 9,155,249,59,153,113,221,247,35,2,228,112,20,115,104,255,103,248,124,62, + 174,187,225,214,164,226,150,77,29,215,253,116,169,138,253,45,196,242,244,253, + 231,106,119,62,82,163,42,6,142,225,248,81,19,216,191,115,13,55,255,231, + 253,52,31,174,226,175,243,31,167,111,191,97,156,54,97,58,149,35,207,37, + 228,243,81,80,92,206,119,110,125,40,237,103,81,14,29,49,1,135,35,187, + 248,167,32,8,130,25,89,77,32,14,153,172,38,0,224,44,41,235,85,171, + 9,24,24,15,95,110,56,184,157,253,59,215,208,214,118,152,138,129,163,25, + 51,238,114,254,250,235,41,122,157,178,154,128,32,8,71,8,205,66,234,53, + 192,110,156,189,90,5,2,237,157,246,37,218,30,143,124,212,145,172,110,159, + 199,21,181,116,13,68,11,149,195,89,210,173,235,193,229,218,230,209,190,30, + 156,153,59,31,169,81,174,198,125,24,235,195,61,157,135,235,44,2,39,8, + 66,174,104,191,251,221,239,148,199,147,216,21,231,116,198,119,29,78,159,126, + 13,47,191,188,128,108,203,2,12,29,58,34,131,174,118,80,93,189,251,152, + 43,171,1,63,251,249,207,35,159,127,243,235,95,147,206,8,254,192,3,15, + 100,213,30,192,189,247,222,155,116,255,174,93,187,24,53,114,100,154,253,74, + 166,89,157,75,228,227,78,34,19,133,123,232,161,135,210,58,238,158,123,238, + 137,250,108,213,180,46,187,233,169,61,120,80,109,217,178,133,45,91,182,176, + 113,227,70,0,158,126,242,73,89,24,86,16,186,9,27,192,53,215,92,147, + 81,161,83,78,57,133,234,234,221,228,90,22,96,235,214,173,0,104,154,134, + 197,210,121,90,158,82,250,255,111,40,20,2,224,173,183,222,138,8,100,62, + 202,166,75,174,101,185,235,46,70,142,28,217,105,223,174,93,187,146,150,253, + 214,183,190,197,115,207,61,7,16,121,140,88,50,46,185,228,146,72,189,169, + 234,126,238,185,231,224,222,123,227,246,171,131,116,198,99,227,152,142,177,118, + 103,138,182,71,141,28,73,109,93,93,242,106,7,13,74,163,237,14,98,197, + 43,150,21,43,86,240,208,67,15,165,60,46,91,86,175,93,171,222,120,227, + 13,214,174,93,203,134,13,27,168,172,172,100,240,224,193,140,25,51,134,9, + 19,38,116,73,155,130,32,36,38,238,68,239,238,70,211,180,136,72,197,190, + 172,86,43,22,139,133,68,55,218,185,148,237,110,70,142,28,25,121,101,194, + 183,190,245,45,64,127,212,89,121,121,121,194,151,89,220,242,211,175,76,175, + 91,244,241,35,71,142,100,201,146,37,9,63,3,12,26,52,136,77,155,54, + 37,252,156,111,238,185,231,158,184,214,222,234,39,206,86,230,215,231,59,119, + 170,198,230,230,140,172,163,55,222,120,131,253,251,247,115,217,101,151,241,236, + 179,207,82,83,83,67,205,190,125,218,242,165,75,181,135,127,243,27,237,148, + 83,82,63,151,115,233,242,229,106,233,242,229,98,149,9,66,30,232,52,15, + 174,187,49,4,202,106,181,118,154,123,5,186,21,166,148,138,88,97,249,42, + 123,36,200,84,216,204,24,150,220,226,197,139,185,236,178,203,58,237,63,251, + 236,179,129,204,197,45,113,191,178,189,41,208,48,44,185,93,187,118,69,68, + 55,222,103,128,186,186,58,206,56,227,140,132,159,243,137,185,237,217,179,103, + 71,38,158,175,126,226,108,117,238,205,235,162,78,120,245,19,223,80,141,103, + 63,65,99,115,179,42,239,219,55,173,139,113,214,89,103,113,223,156,57,89, + 223,77,125,182,117,171,154,53,107,22,83,167,78,205,182,10,65,16,76,28, + 21,2,103,88,92,195,135,15,143,123,76,85,85,21,193,96,176,147,80,229, + 82,214,204,41,167,156,18,119,123,58,174,200,76,202,230,34,112,144,88,228, + 114,17,183,124,244,171,187,208,52,45,226,118,206,6,67,208,86,172,88,17, + 17,59,67,220,130,234,137,168,138,173,218,205,218,234,39,110,86,159,175,211, + 143,137,236,88,7,229,63,123,145,254,253,251,147,174,240,165,203,202,149,43, + 89,185,114,37,253,250,245,203,72,88,5,65,136,79,39,129,51,158,25,25, + 139,249,249,148,137,200,182,172,97,137,61,242,200,35,113,247,79,159,62,61, + 165,139,50,155,178,6,137,202,166,115,206,153,148,141,18,160,44,69,37,86, + 228,114,21,183,248,253,202,117,92,213,128,157,140,28,57,146,39,159,124,50, + 34,38,177,159,65,119,73,190,253,246,219,17,171,45,246,115,167,154,115,20, + 185,120,196,138,155,177,205,170,221,220,233,66,60,254,3,212,225,23,94,224, + 155,223,252,102,94,251,240,217,214,173,234,198,27,111,4,224,181,215,94,235, + 100,233,10,130,144,57,157,4,238,174,187,238,138,123,96,58,214,76,54,101, + 13,241,209,52,141,255,248,143,255,136,123,140,241,132,139,88,161,202,165,172, + 153,116,132,44,31,101,243,33,112,208,33,114,249,16,183,124,246,43,94,189, + 93,225,162,236,10,145,99,29,172,91,247,100,212,166,40,203,45,138,87,104, + 92,242,10,159,239,220,169,78,28,53,42,103,43,171,246,224,65,53,107,214, + 44,214,172,89,19,217,246,155,223,252,134,165,203,151,171,169,83,166,136,21, + 39,8,89,210,73,224,50,205,16,204,87,217,222,64,172,16,237,218,181,43, + 146,33,153,45,185,76,35,48,247,35,223,140,74,67,40,7,167,202,146,76, + 114,83,146,87,145,91,183,142,117,235,214,17,27,135,139,71,112,237,19,202, + 122,206,205,218,227,63,64,29,62,252,66,94,154,255,232,163,143,24,57,114, + 36,103,156,113,6,155,54,109,162,162,162,130,65,131,6,177,106,213,42,170, + 170,171,213,176,161,67,163,250,85,85,93,173,0,98,183,11,130,16,205,17, + 143,193,153,25,60,120,112,220,237,251,246,237,235,210,178,221,21,131,187,249, + 7,63,136,250,60,106,228,72,72,49,87,45,25,191,132,156,202,27,196,246, + 75,203,104,6,90,124,180,56,211,54,50,37,85,47,242,109,201,197,115,85, + 118,98,221,58,130,234,9,245,228,205,55,71,214,216,203,133,198,230,102,85, + 95,95,207,53,87,93,165,221,255,192,3,202,200,32,189,231,158,123,152,56, + 113,98,167,197,98,107,15,30,84,175,189,246,26,39,157,116,82,206,109,11, + 66,79,231,168,136,193,25,36,138,103,125,253,235,95,143,187,189,171,203,230, + 59,6,247,143,231,59,150,225,249,143,25,51,210,146,145,5,11,22,164,113, + 84,162,230,253,233,0,0,32,0,73,68,65,84,124,82,205,81,60,120,240, + 32,131,6,14,140,211,175,220,13,3,75,94,166,122,39,103,238,220,185,93, + 222,70,62,88,186,124,185,90,177,98,5,91,183,110,238,180,207,156,72,82, + 81,81,1,232,15,200,126,255,253,247,185,230,170,171,162,46,98,237,193,131, + 234,222,123,239,165,188,188,60,178,118,159,32,8,137,57,226,49,56,51,169, + 226,104,93,85,182,187,98,112,3,7,14,236,180,237,224,193,131,73,203,156, + 127,254,249,124,240,193,7,0,157,238,230,227,97,36,63,28,60,120,48,101, + 221,31,124,240,1,92,115,77,220,126,29,13,196,10,152,249,243,220,185,115, + 153,51,103,78,247,118,8,88,199,58,206,230,236,78,219,171,170,171,213,134, + 13,27,58,109,159,115,223,125,202,136,59,78,158,60,57,105,221,67,134,12, + 97,240,224,193,212,214,214,242,210,75,47,241,248,19,79,168,175,126,245,171, + 120,189,94,54,108,216,192,213,87,95,77,83,83,19,143,63,254,120,222,51, + 56,5,161,39,34,49,184,110,228,208,161,67,89,149,51,68,174,160,160,32, + 97,2,134,82,42,146,238,159,74,216,242,213,175,174,38,86,192,12,129,235, + 82,113,91,183,46,197,126,48,235,219,103,91,183,170,43,174,184,130,17,35, + 70,196,21,176,167,158,122,42,242,247,157,119,222,201,242,165,75,19,86,61, + 113,226,68,206,59,239,60,94,123,237,53,246,238,221,203,175,126,245,43,22, + 45,90,4,192,199,31,127,76,67,67,3,243,230,205,67,18,79,4,33,61, + 36,6,71,247,197,224,46,186,232,162,148,245,37,194,16,185,77,155,54,117, + 18,185,92,196,45,215,126,117,55,71,202,114,75,196,117,215,93,199,222,189, + 123,1,24,61,122,116,39,1,123,231,157,119,88,182,108,25,23,93,116,17, + 167,157,114,74,82,97,26,60,112,160,246,135,63,254,81,189,246,218,107,0, + 212,214,214,178,120,241,98,64,119,95,206,157,59,151,91,111,238,60,117,65, + 16,132,248,72,12,46,73,217,124,199,224,114,117,5,154,69,110,220,184,113, + 128,158,104,145,139,184,229,163,95,221,69,87,136,91,249,37,47,178,110,201, + 55,0,88,119,243,147,172,35,133,5,7,172,187,249,102,22,29,152,198,121, + 231,13,167,188,188,156,198,198,70,46,185,228,18,30,126,248,97,158,126,50, + 122,170,65,42,81,139,101,250,244,233,52,52,52,240,235,95,255,26,143,199, + 131,211,233,100,236,216,177,220,124,243,44,190,250,213,105,204,206,67,82,145, + 32,244,22,36,6,71,247,197,224,162,4,40,75,81,49,68,238,147,79,62, + 97,220,184,113,140,24,49,162,115,221,25,146,143,126,117,7,169,196,109,197, + 138,21,25,215,217,191,127,127,26,207,126,130,183,223,126,155,61,236,129,56, + 241,181,120,156,119,222,112,190,252,229,47,115,238,57,231,104,0,79,63,249, + 100,39,113,203,134,193,3,7,70,9,162,219,229,226,227,15,63,228,227,15, + 63,228,198,27,114,174,94,16,122,21,18,131,235,70,150,45,91,214,241,33, + 135,39,97,24,34,151,171,229,150,239,126,29,73,102,207,158,157,85,185,242, + 190,125,181,198,230,102,85,94,94,30,89,201,60,29,28,14,7,253,251,247, + 207,170,77,65,16,186,7,137,193,209,125,49,184,1,3,6,68,125,62,120, + 240,96,36,67,50,91,114,153,70,96,16,219,175,163,133,120,75,32,229,189, + 126,77,83,101,101,101,217,87,34,235,177,9,194,81,139,196,224,146,148,205, + 119,12,238,226,152,167,196,15,26,56,16,50,92,79,175,19,185,150,167,115, + 191,242,50,209,251,232,88,137,73,16,132,94,140,196,224,232,190,24,92,54, + 43,122,119,37,137,87,244,62,54,38,122,11,130,32,36,67,98,112,221,72, + 54,43,122,167,170,235,129,7,30,136,44,136,154,41,233,173,232,45,8,130, + 112,108,34,49,56,142,157,245,224,98,235,89,23,158,148,252,220,115,207,101, + 45,114,249,236,151,32,8,194,209,196,49,29,131,51,30,180,171,148,74,186, + 30,156,249,216,76,218,205,119,12,46,31,66,18,43,110,151,93,118,25,139, + 23,47,206,73,228,58,247,75,145,219,154,112,10,36,6,39,8,194,17,230, + 152,142,193,41,165,8,133,66,104,154,22,17,178,216,253,198,106,222,201,4, + 174,187,98,112,185,10,92,172,184,25,228,42,114,98,193,9,130,208,19,57, + 166,99,112,193,96,48,34,114,6,102,33,83,74,69,137,220,145,38,151,133, + 69,19,137,155,65,46,34,23,191,95,217,90,113,71,58,117,70,16,4,65, + 231,152,142,193,185,221,110,52,77,67,211,180,168,57,83,102,215,37,116,8, + 97,34,114,137,193,101,66,182,2,103,136,219,146,37,75,146,30,55,113,226, + 68,62,250,232,163,140,69,46,113,191,50,21,57,17,55,65,16,142,30,242, + 26,131,203,149,76,99,112,7,14,28,64,11,175,250,108,44,126,25,207,29, + 105,88,114,153,182,155,239,115,238,138,21,189,19,145,73,189,201,51,57,141, + 235,150,76,232,68,216,4,65,56,250,200,41,6,151,232,216,108,201,52,6, + 183,115,231,206,78,219,60,30,79,194,250,157,78,103,220,237,153,8,89,34, + 49,76,167,221,124,175,232,157,47,98,251,21,255,9,34,201,4,78,18,74, + 4,65,56,250,200,41,6,151,203,163,148,170,170,58,139,83,186,12,27,54, + 42,235,178,211,167,103,255,228,143,92,218,229,174,187,178,90,209,187,43,73, + 180,162,183,32,8,66,79,224,152,142,193,229,139,238,138,193,101,179,162,119, + 170,186,22,44,88,192,249,231,159,159,85,29,71,251,138,222,130,32,8,185, + 112,76,199,224,186,186,221,124,159,115,190,86,206,54,4,105,247,238,221,128, + 46,84,217,138,92,62,251,37,8,130,112,52,145,215,121,112,185,146,203,243, + 36,115,161,59,196,27,242,179,114,118,172,184,141,27,55,142,79,62,249,36, + 39,145,59,150,86,244,22,4,65,72,151,188,206,131,19,146,147,171,43,208, + 40,191,107,215,174,72,246,40,228,46,114,226,162,20,4,161,39,34,49,56, + 186,47,6,151,203,202,217,102,113,3,125,234,131,49,7,16,224,140,51,206, + 96,211,166,77,89,137,220,177,178,162,183,32,8,66,38,72,12,46,73,187, + 249,62,231,108,87,206,54,196,237,133,23,94,72,121,108,65,65,65,198,34, + 215,19,86,244,22,4,65,136,69,98,112,116,95,12,46,215,21,189,11,10, + 10,210,62,54,147,122,143,214,21,189,5,65,16,114,65,98,112,221,132,102, + 177,112,137,249,51,16,223,33,219,189,104,208,169,95,130,32,8,61,1,137, + 193,209,125,49,56,65,16,4,161,251,144,24,92,146,118,187,203,117,41,8, + 130,32,228,31,137,193,33,66,38,8,130,208,19,145,24,156,32,8,130,208, + 35,145,24,28,18,131,19,4,65,232,137,72,12,46,73,187,226,186,20,4, + 65,56,118,145,24,28,34,100,130,32,8,61,17,137,193,9,130,32,8,61, + 18,137,193,33,49,56,65,16,132,158,136,196,224,146,180,43,174,75,65,16, + 132,99,23,137,193,33,66,38,8,130,208,19,145,24,156,32,8,130,208,35, + 145,24,28,18,131,19,4,65,232,137,28,241,24,156,82,42,242,158,40,22, + 54,125,250,244,168,99,243,141,196,224,4,65,16,122,30,71,60,6,167,148, + 34,20,10,161,105,90,68,200,98,247,7,131,65,66,161,80,151,9,156,8, + 153,32,8,66,207,227,136,199,224,130,193,96,68,228,12,204,66,166,148,138, + 18,57,65,16,4,65,72,135,35,30,131,115,187,221,104,154,134,166,105,88, + 44,150,200,118,179,235,18,58,132,80,16,4,65,16,210,225,136,11,220,129, + 3,7,208,52,125,29,105,77,211,34,214,92,172,152,25,150,156,32,8,130, + 32,164,131,45,81,204,173,187,216,185,115,103,167,109,30,143,39,225,241,78, + 167,51,231,54,19,37,149,116,117,187,130,32,8,66,247,161,41,49,139,4, + 65,136,131,102,184,86,146,48,107,214,172,241,243,230,205,91,111,188,103,216, + 196,92,96,14,112,95,248,239,216,246,101,108,18,114,226,136,187,40,5,65, + 56,54,153,53,107,214,186,240,187,177,233,236,52,139,158,12,252,4,248,50, + 16,4,110,4,134,0,255,13,108,203,111,47,133,222,140,88,112,130,32,196, + 37,158,5,55,107,214,44,59,80,4,20,2,19,128,135,0,39,186,88,185, + 129,118,192,61,111,222,60,127,130,106,191,1,252,237,129,7,30,116,92,117, + 213,181,156,114,202,72,170,170,170,120,241,197,23,249,197,47,126,225,3,190, + 3,188,24,110,95,198,38,33,39,68,224,4,65,136,75,172,192,205,154,53, + 171,8,24,3,156,6,156,0,12,5,134,133,119,87,1,213,192,94,224,51, + 96,251,188,121,243,220,49,85,158,12,108,90,182,108,153,99,253,250,50,92, + 46,63,179,103,79,136,236,92,190,124,57,23,93,116,145,15,56,3,216,38, + 2,39,228,138,37,245,33,130,32,244,118,102,205,154,213,23,184,0,152,1, + 92,4,12,2,154,209,93,139,213,225,191,7,133,247,205,0,46,8,151,49, + 243,147,7,31,124,208,49,101,202,20,190,243,157,147,120,233,165,29,28,56, + 208,22,217,57,101,202,20,30,124,240,65,7,186,251,82,16,114,70,44,56, + 65,16,226,98,88,112,97,161,186,20,152,132,30,51,107,4,90,208,221,145, + 3,129,58,64,67,119,91,246,1,202,1,43,240,30,240,175,121,243,230,53, + 135,171,220,187,99,199,142,161,163,70,141,2,96,246,236,143,105,107,11,80, + 84,100,99,240,224,34,102,205,26,203,206,157,59,25,61,122,116,53,112,130, + 88,112,66,174,136,192,9,194,81,137,66,169,32,161,16,28,56,224,101,233, + 178,22,86,127,220,194,182,109,77,212,30,240,209,210,226,193,98,81,244,235, + 111,165,178,210,198,184,177,101,92,112,65,57,23,76,26,72,105,169,61,252, + 240,132,220,28,52,154,166,105,97,183,228,101,192,133,128,15,56,8,156,8, + 124,23,248,26,96,196,218,140,216,92,31,160,31,186,240,57,128,21,192,226, + 176,187,50,224,247,251,173,54,155,158,219,86,91,235,230,75,95,122,157,107, + 174,25,201,109,183,157,206,113,199,21,19,8,4,176,219,237,65,192,38,2, + 39,228,138,8,156,32,28,85,232,255,142,237,237,65,94,91,80,207,255,205, + 63,204,39,155,26,241,122,107,241,249,170,8,169,26,66,161,38,2,65,63, + 154,178,16,82,125,128,62,104,148,3,125,41,43,183,115,233,165,67,184,229, + 150,83,153,56,113,32,86,171,5,221,14,75,153,241,223,137,219,111,191,221, + 1,156,143,46,112,78,160,6,221,90,171,7,94,1,126,5,44,10,31,110, + 163,67,224,250,163,187,43,43,1,15,176,24,248,96,222,188,121,59,205,22, + 156,126,158,1,10,11,59,146,185,197,130,19,242,137,76,19,16,132,163,132, + 80,40,64,40,164,88,188,184,153,95,63,84,195,193,131,245,180,181,45,167, + 177,241,3,74,74,221,156,125,246,72,70,142,28,66,223,178,209,20,22,22, + 18,12,132,112,187,189,28,58,212,204,182,109,219,248,252,243,6,26,27,7, + 242,143,127,12,225,165,151,62,227,178,203,142,231,129,7,38,113,210,73,229, + 216,108,118,210,152,214,22,75,37,48,17,93,176,170,129,6,116,113,59,12, + 188,14,220,1,252,53,124,172,13,221,101,105,182,232,10,209,19,81,38,2, + 123,128,183,95,124,241,197,155,238,185,231,158,72,3,102,113,3,120,241,197, + 23,1,222,206,180,163,130,16,15,177,224,4,225,8,163,148,254,104,58,151, + 43,200,47,238,217,199,170,85,7,113,123,22,177,127,223,34,38,77,58,147, + 75,191,50,133,211,199,158,128,195,97,195,225,176,226,176,59,176,90,173,88, + 172,186,56,168,144,34,16,244,211,216,232,97,217,178,29,44,92,184,129,45, + 91,60,168,208,48,74,75,29,60,244,155,11,184,254,187,103,226,116,218,177, + 88,210,191,167,189,253,246,219,39,2,215,160,11,85,21,176,15,168,69,23, + 184,86,244,140,201,139,128,77,232,2,247,8,112,22,112,11,48,24,61,1, + 101,24,186,240,45,8,199,226,54,45,91,182,204,49,101,202,148,78,237,73, + 22,165,144,111,196,130,19,132,35,140,82,138,198,198,0,215,127,183,138,54, + 119,53,123,170,230,48,246,180,193,252,242,255,205,101,200,9,229,20,20,216, + 41,41,46,161,164,164,132,162,162,34,10,10,10,176,90,173,29,49,54,165, + 8,134,130,248,124,62,78,60,113,40,51,102,76,224,237,127,237,230,209,71, + 223,97,127,77,41,119,220,254,47,62,223,126,144,57,115,166,80,90,90,26, + 245,80,243,20,12,2,250,210,145,80,226,166,99,174,155,7,61,137,228,62, + 116,23,230,221,192,183,129,145,64,133,233,184,246,112,29,131,128,143,129,239, + 92,116,209,69,127,123,240,193,7,29,223,248,198,55,24,54,108,88,188,121, + 112,50,217,91,200,11,98,193,9,194,17,68,183,220,252,124,243,27,123,104, + 247,110,96,245,199,15,113,203,45,211,185,242,202,73,216,29,118,202,202,250, + 82,81,94,78,73,73,41,78,167,19,155,205,22,89,125,35,166,38,66,33, + 125,89,41,159,47,128,187,173,149,234,234,6,238,189,119,49,255,122,187,30, + 141,16,119,222,57,129,217,179,47,161,184,164,24,171,213,154,178,111,183,223, + 126,251,247,128,139,209,221,139,123,208,221,148,117,232,174,74,23,112,10,240, + 62,240,0,112,47,186,176,149,160,103,81,14,70,119,79,14,15,191,222,157, + 55,111,222,252,112,213,230,39,153,84,162,199,246,222,38,230,73,38,98,193, + 9,185,34,22,156,32,28,33,244,117,14,253,252,244,167,251,104,117,237,100, + 227,198,7,248,229,189,183,113,238,196,147,41,46,41,102,224,128,1,244,235, + 215,143,194,194,66,140,204,195,196,104,88,44,250,146,83,118,187,29,167,211, + 78,73,105,9,79,60,249,77,238,185,231,93,254,241,220,46,30,123,108,37, + 39,157,92,193,140,25,103,83,82,82,146,77,76,46,150,141,232,49,183,159, + 163,207,145,75,222,195,196,130,53,20,184,41,252,18,132,188,33,19,189,5, + 225,136,161,120,103,73,43,171,86,213,179,121,243,195,220,252,253,111,51,113, + 226,201,244,237,211,135,161,199,31,207,224,193,199,81,82,82,146,134,184,117, + 198,106,181,225,116,22,50,120,240,64,254,251,191,175,224,194,11,43,9,4, + 6,51,103,206,43,236,217,85,135,199,227,73,103,249,169,96,248,221,110,122, + 217,76,47,43,80,6,252,22,216,108,218,30,123,60,64,32,227,147,16,132, + 28,17,11,46,1,161,80,8,139,197,66,48,216,241,164,5,77,51,150,204, + 233,124,231,107,177,88,8,133,244,241,64,41,79,248,88,45,188,221,88,137, + 92,225,243,5,105,247,53,210,216,226,160,233,176,157,234,189,33,26,235,15, + 178,171,218,73,107,147,131,221,59,107,216,91,229,163,205,85,72,99,163,7, + 183,187,62,110,255,138,251,192,241,199,245,227,132,97,14,74,74,251,48,96, + 64,27,67,135,13,161,108,160,149,126,165,48,244,4,11,101,253,252,148,149, + 21,81,100,211,112,56,108,145,216,139,223,239,143,184,168,204,231,104,156,159, + 197,210,225,190,10,133,130,40,165,47,35,100,181,22,71,93,27,33,55,2, + 1,197,111,30,170,161,221,253,14,167,156,210,151,203,174,56,143,146,146,66, + 42,143,59,142,126,253,251,227,112,56,114,170,95,211,52,236,118,27,3,6, + 244,225,145,71,175,224,162,11,95,164,174,206,202,83,79,47,231,158,123,46, + 103,192,192,129,169,196,179,14,253,9,37,78,244,68,147,162,240,171,157,14, + 193,10,160,187,22,157,113,142,43,12,191,154,209,231,207,9,66,183,34,2, + 151,16,253,238,214,60,168,155,247,25,131,190,65,40,228,52,9,67,49,126, + 191,159,96,80,209,234,10,81,189,63,64,245,222,16,59,119,6,89,191,182, + 145,45,159,214,179,231,243,189,52,123,52,80,30,208,156,40,213,151,162,2, + 63,110,175,29,0,77,51,198,3,111,248,189,192,212,154,151,246,122,168,175, + 119,179,105,51,160,60,104,90,59,240,49,74,121,112,22,56,240,120,125,244, + 235,55,136,243,207,63,145,17,163,42,57,99,108,11,229,253,7,50,244,4, + 11,99,79,45,192,221,236,162,176,143,149,96,176,163,214,104,97,11,153,182, + 21,155,182,155,10,8,89,163,84,136,15,63,108,98,231,206,70,14,31,126, + 157,159,223,115,55,78,167,149,254,3,6,80,94,81,145,80,220,148,82,168, + 144,23,21,242,129,197,142,197,98,71,211,140,239,77,195,248,221,154,111,194, + 172,86,27,167,157,218,159,153,223,63,135,223,253,79,144,87,94,89,197,13, + 55,156,71,73,105,9,37,37,165,201,92,149,134,192,13,66,159,223,214,23, + 61,121,196,152,10,96,163,67,232,108,116,60,201,196,56,182,15,122,76,174, + 46,252,18,132,110,69,4,46,1,198,96,175,15,244,42,230,179,134,213,90, + 28,217,103,28,31,10,133,56,220,224,163,122,127,128,141,159,133,216,188,214, + 195,186,141,27,216,182,185,133,195,13,133,104,90,63,83,11,199,163,105,16, + 82,109,160,64,211,60,180,251,64,211,98,159,79,11,209,226,22,38,44,140, + 128,46,144,132,31,251,167,129,199,7,133,5,86,14,31,110,96,209,162,181, + 40,85,136,254,116,37,24,126,220,80,198,158,51,140,169,23,67,159,210,18, + 198,141,31,204,169,39,57,112,56,108,248,253,126,44,22,95,164,9,77,43, + 140,123,109,116,113,47,142,187,79,72,141,49,45,224,205,55,27,105,111,223, + 194,136,17,253,25,57,106,0,125,250,244,165,162,162,31,5,5,5,113,142, + 15,160,20,40,229,5,111,13,154,247,0,88,75,8,58,135,160,217,42,208, + 52,80,33,31,10,133,197,82,128,166,89,77,194,167,255,62,175,191,126,12, + 143,254,239,191,169,173,115,241,201,230,221,84,30,223,143,162,162,164,9,39, + 7,194,175,161,232,137,35,177,243,220,220,196,127,146,73,127,244,132,147,114, + 244,167,153,24,245,8,66,183,34,2,151,0,191,223,143,221,110,143,184,30, + 163,221,120,26,30,143,15,171,85,191,243,61,120,240,32,107,215,212,179,115, + 207,9,172,92,86,197,7,171,252,52,183,20,19,84,205,132,66,86,52,173, + 16,165,156,40,101,212,161,91,127,74,57,163,62,235,214,90,103,49,43,116, + 88,105,247,153,45,167,130,104,47,169,242,160,103,109,119,208,238,5,77,107, + 15,139,27,232,99,13,236,57,224,98,207,194,207,88,184,80,223,122,230,233, + 229,156,121,134,159,47,78,61,141,161,163,251,51,238,20,39,253,42,28,4, + 131,65,172,86,133,199,227,35,24,244,83,88,216,225,158,77,36,124,66,38, + 40,214,172,105,192,235,221,193,25,103,156,134,221,110,167,79,159,190,20,58, + 11,163,44,170,80,200,79,200,95,15,254,6,64,67,83,1,66,109,27,9, + 184,62,67,43,24,64,40,48,25,138,108,216,105,7,111,141,94,166,96,48, + 154,99,112,148,112,105,154,198,201,39,87,48,100,104,63,170,246,12,98,243, + 39,59,152,52,233,100,202,202,202,18,10,220,188,121,243,14,206,154,53,235, + 93,116,177,26,65,180,181,86,68,98,129,51,30,213,213,23,216,129,158,65, + 121,48,15,73,45,130,144,17,34,112,9,176,88,124,132,66,29,113,38,195, + 98,51,4,175,213,21,226,147,173,30,54,173,83,172,92,118,136,69,111,180, + 3,219,8,133,218,208,180,102,148,234,139,197,162,91,57,74,57,209,52,143, + 73,208,250,81,216,231,16,170,93,31,27,138,138,6,161,217,234,81,129,19, + 244,253,182,122,220,126,243,114,90,33,10,45,237,209,29,12,245,1,192,237, + 181,163,105,209,238,75,3,35,135,64,119,95,98,218,238,1,237,56,0,54, + 126,218,200,198,79,27,249,251,75,219,56,110,80,5,23,124,241,98,166,94, + 222,159,51,79,179,48,244,120,27,253,42,28,128,13,165,218,241,251,237,56, + 157,185,197,133,4,48,238,78,118,239,110,195,231,63,196,9,39,140,195,105, + 183,83,84,92,136,213,102,142,109,42,84,208,5,109,219,9,185,195,139,101, + 91,202,81,237,27,8,212,108,130,65,67,240,250,142,135,64,41,125,44,251, + 8,185,215,160,84,16,10,191,64,168,180,152,130,2,43,86,171,77,119,107, + 170,16,154,166,113,210,73,21,84,237,41,98,255,254,58,60,237,110,2,254, + 128,30,57,75,192,188,121,243,182,206,154,53,107,25,122,50,73,63,58,92, + 145,198,220,184,216,39,151,24,15,91,238,139,238,54,88,54,111,222,188,173, + 249,186,114,130,144,9,34,112,9,208,180,194,168,4,140,80,168,144,195,13, + 62,62,248,208,199,206,157,65,94,127,221,69,109,117,19,159,239,170,195,98, + 41,38,20,106,51,149,46,192,162,237,161,176,207,64,10,195,66,2,29,43, + 135,104,182,122,250,149,57,57,220,20,68,133,92,40,181,19,21,4,180,157, + 180,186,218,176,208,136,215,103,167,99,228,49,91,103,250,54,187,67,255,234, + 28,14,240,249,108,20,22,148,226,245,233,131,163,82,133,20,22,218,104,15, + 235,90,196,138,139,184,52,9,91,125,6,229,4,252,78,170,247,193,115,207, + 189,198,203,47,7,56,110,80,5,215,124,109,34,35,70,4,153,116,225,104, + 134,143,178,83,86,100,139,36,157,104,154,51,42,102,39,100,130,194,231,11, + 225,245,90,177,90,21,118,71,17,109,30,59,187,118,250,41,47,11,97,177, + 88,81,42,68,40,232,70,181,239,33,212,182,129,64,253,50,52,103,1,65, + 203,80,44,161,61,88,107,14,19,234,31,36,224,221,130,53,4,126,107,45, + 154,247,19,112,121,241,148,13,32,164,141,64,179,20,82,160,89,0,197,166, + 141,245,140,62,177,140,162,66,39,54,91,49,237,30,47,62,127,144,64,48, + 128,82,42,233,148,129,121,243,230,189,23,94,181,251,106,116,203,172,4,125, + 30,156,57,217,196,16,190,18,116,183,228,65,224,245,121,243,230,189,215,101, + 151,81,16,82,32,2,151,132,80,40,68,40,228,160,186,206,197,242,149,65, + 54,175,169,98,197,178,118,54,126,210,210,73,212,44,150,98,42,250,234,151, + 179,188,124,16,198,58,144,86,235,1,218,61,85,145,227,92,109,94,90,154, + 219,56,116,72,207,142,84,120,208,240,208,241,112,136,104,87,99,34,124,62, + 227,56,61,121,173,221,171,39,176,169,176,0,182,183,15,14,215,239,164,176, + 160,20,0,143,87,143,195,105,154,51,226,226,84,170,48,202,194,211,40,192, + 239,43,96,111,181,151,223,63,186,2,133,151,179,78,175,97,242,197,67,153, + 50,117,24,231,159,231,160,95,133,51,124,125,130,4,131,161,240,121,70,139, + 157,100,89,198,39,20,10,176,109,155,135,91,111,169,162,168,176,15,45,205, + 13,40,5,159,125,234,229,177,199,22,240,210,75,95,227,196,19,203,176,89, + 125,208,190,147,80,235,106,66,190,15,177,180,239,37,232,183,225,47,240,98, + 179,54,80,80,223,130,178,122,177,171,53,224,109,65,217,220,104,238,3,248, + 125,26,222,246,70,252,246,54,28,133,65,236,54,197,59,75,26,248,249,221, + 111,242,234,130,171,9,6,3,140,28,117,38,139,23,175,197,233,248,132,223, + 60,92,73,159,62,161,168,120,93,60,194,34,87,15,124,21,56,9,221,74, + 235,23,115,152,145,137,181,13,120,77,44,55,225,72,35,2,151,128,128,255, + 48,141,77,65,22,191,233,98,201,187,22,222,94,124,152,134,102,253,102,213, + 112,61,26,239,21,125,109,148,151,59,41,46,49,132,162,157,230,67,7,104, + 245,249,104,115,53,226,241,86,163,240,160,199,217,155,208,69,172,25,40,8, + 235,140,23,93,224,226,17,155,69,105,124,46,11,191,55,155,246,57,195,245, + 57,81,28,192,176,246,218,189,133,64,25,26,101,40,156,40,229,69,163,0, + 103,129,3,104,195,227,45,142,136,156,166,57,81,202,131,194,75,81,225,16, + 60,158,86,54,125,86,195,103,219,55,179,224,213,10,174,189,182,63,95,188, + 232,98,190,242,37,189,110,35,14,25,12,167,99,166,243,132,140,222,139,98, + 199,14,47,87,94,177,27,165,66,88,172,91,112,183,239,71,97,225,64,173, + 159,189,85,123,56,92,191,159,1,253,253,84,148,180,65,235,122,66,77,111, + 161,149,108,3,75,35,150,134,34,180,227,237,88,44,237,40,87,43,118,71, + 11,90,208,143,55,216,76,48,228,64,107,169,199,26,40,38,224,108,35,232, + 111,39,24,242,161,148,147,173,91,154,217,181,103,43,135,15,79,194,231,243, + 97,181,246,163,95,197,104,94,126,117,19,77,205,45,252,245,111,223,162,127, + 255,196,177,56,131,176,187,242,48,250,19,76,78,4,70,163,199,231,64,127, + 186,201,14,224,115,96,235,188,121,243,100,90,128,112,196,233,21,2,103,78, + 109,55,210,251,53,173,144,96,48,136,221,110,39,24,108,35,24,112,99,179, + 247,195,98,177,224,247,251,249,195,227,54,214,175,109,229,157,119,62,231,240, + 225,50,83,93,109,17,107,109,200,80,197,9,195,244,152,84,245,238,106,26, + 26,247,227,106,243,226,110,115,160,66,75,241,248,3,116,88,101,205,232,34, + 230,37,177,149,230,36,158,59,82,199,75,103,218,209,189,66,222,152,99,154, + 77,199,20,96,88,121,138,50,12,43,79,1,30,111,25,138,50,44,154,5, + 69,57,133,206,0,30,79,43,0,22,173,47,30,79,107,68,236,252,190,98, + 170,170,91,120,252,113,197,95,255,246,47,190,125,221,201,76,153,58,140,47, + 94,84,64,223,66,93,248,253,126,59,86,171,46,118,122,146,138,133,128,191, + 1,0,71,193,128,240,245,11,161,84,123,100,250,69,111,65,169,16,109,109, + 126,190,123,253,46,148,10,241,147,187,75,249,241,143,63,66,41,47,161,96, + 0,187,61,136,82,138,246,214,38,188,77,110,148,218,143,242,174,1,215,191, + 177,245,175,67,5,124,104,135,67,104,39,20,97,177,123,176,122,66,96,245, + 96,85,65,156,1,8,56,74,177,180,251,240,218,109,168,80,11,248,107,193, + 91,10,78,43,129,160,66,133,66,180,52,55,226,15,4,216,182,173,153,202, + 193,37,160,138,89,242,238,90,30,252,175,50,230,204,189,156,190,125,203,98, + 19,83,58,205,4,255,227,31,255,152,214,249,74,66,137,112,52,208,99,5, + 46,24,108,139,196,137,140,20,126,221,109,86,28,158,232,172,194,137,36,86, + 252,126,59,14,135,238,109,153,255,204,142,136,197,230,118,215,227,246,218,49, + 123,219,250,151,247,229,252,73,246,200,231,237,219,14,82,181,119,15,30,239, + 33,20,123,128,221,68,11,76,135,168,169,24,97,211,58,69,247,205,251,251, + 154,254,142,151,181,216,132,46,94,198,59,36,202,194,236,168,187,9,240,162, + 209,14,12,15,187,51,203,9,41,221,186,115,183,59,35,150,157,199,219,209, + 23,205,84,167,199,123,136,160,106,228,247,143,110,103,193,171,3,185,230,107, + 19,249,206,13,35,56,105,180,134,221,214,140,187,185,128,162,190,37,145,9, + 238,142,130,1,4,131,109,180,181,181,81,92,92,28,222,222,27,179,48,53, + 158,124,242,48,155,54,184,249,197,255,59,158,23,95,92,143,207,119,24,80, + 250,122,109,74,3,165,17,12,182,99,241,85,161,90,62,68,179,111,66,11, + 214,163,105,109,208,14,90,107,59,54,187,27,13,31,248,125,104,22,208,218, + 3,88,66,205,216,156,126,44,222,0,86,171,134,221,86,133,51,184,2,139, + 171,138,128,101,2,33,127,1,10,8,133,116,189,10,133,52,90,93,86,208, + 138,81,170,128,167,158,94,196,21,87,156,202,121,231,159,68,73,73,177,136, + 147,208,99,232,185,2,23,112,163,175,38,98,184,19,45,120,60,62,28,14, + 27,86,171,149,128,255,48,142,130,1,250,32,236,176,177,240,13,23,47,189, + 80,207,154,143,218,249,124,87,29,118,107,37,65,21,192,98,1,171,214,151, + 211,78,115,113,234,233,253,113,181,182,176,183,202,71,99,227,38,234,234,118, + 226,241,237,67,23,14,227,213,33,102,134,128,25,127,27,159,157,5,250,243, + 104,251,20,13,162,127,255,98,10,156,253,25,49,108,4,0,149,67,237,56, + 10,244,196,148,62,197,80,90,174,127,69,173,141,1,74,203,109,180,54,234, + 214,82,139,41,167,165,177,182,138,102,151,70,85,21,132,216,141,215,83,207, + 150,207,13,87,168,135,104,23,104,25,186,120,26,130,87,75,135,117,87,142, + 162,140,118,47,56,28,253,241,249,108,17,113,211,69,79,159,245,231,243,129, + 134,110,209,61,250,232,219,44,120,181,15,119,253,120,2,147,46,28,205,169, + 39,57,8,248,15,211,230,13,81,82,88,129,207,23,192,225,40,164,176,16, + 60,30,125,142,157,195,209,99,127,118,9,241,250,130,204,155,87,67,101,165, + 149,253,251,235,249,224,253,29,232,33,43,133,82,26,10,133,166,41,172,120, + 177,6,247,162,90,182,98,173,172,198,162,92,250,69,119,41,104,15,97,47, + 104,71,185,2,104,129,0,90,64,97,105,81,132,188,62,172,35,125,104,202, + 138,85,179,226,44,216,143,197,83,135,173,109,11,33,26,8,184,39,0,138, + 144,82,97,23,182,66,133,130,104,20,162,40,198,227,169,229,153,103,222,230, + 228,83,6,80,80,224,200,249,9,42,130,112,180,208,163,71,26,227,209,83, + 30,143,15,167,211,129,211,233,192,31,78,191,183,217,251,225,241,248,168,169, + 111,227,177,223,249,249,215,27,27,169,173,9,208,210,94,78,129,245,100,188, + 193,109,88,44,197,140,59,221,202,133,83,251,115,232,160,147,173,159,108,99, + 227,167,27,40,176,239,195,227,255,156,104,241,104,142,178,208,52,173,21,104, + 69,169,82,52,156,12,44,63,135,227,135,12,99,196,176,17,12,29,53,149, + 9,227,182,83,58,192,74,81,97,41,74,21,18,8,117,88,125,54,75,95, + 2,161,102,236,86,135,105,30,91,52,230,227,11,156,167,226,245,232,110,88, + 191,79,79,110,9,5,70,176,107,215,94,118,239,172,230,195,85,126,246,213, + 236,161,185,229,0,30,191,11,93,216,140,39,43,25,212,134,207,71,79,68, + 241,250,12,129,214,227,118,30,111,248,122,70,156,86,205,56,28,54,124,62, + 27,85,213,45,220,117,231,42,198,143,93,193,119,110,186,144,235,110,60,133, + 190,197,1,66,33,93,204,116,151,165,138,76,49,136,126,42,76,239,224,131, + 247,93,84,85,185,153,52,169,148,37,239,236,10,187,205,21,250,188,66,107, + 228,25,36,90,176,13,107,232,16,154,175,30,75,97,27,4,130,160,41,104, + 213,176,184,130,132,10,60,88,90,3,224,7,229,7,117,64,65,67,16,235, + 23,21,65,45,132,149,54,156,206,3,168,198,32,214,34,11,94,95,27,202, + 219,31,8,187,135,1,208,80,104,40,44,232,73,143,133,44,89,178,154,131, + 7,47,167,111,223,190,34,112,66,143,161,199,10,156,205,94,17,113,77,234, + 131,172,110,242,88,44,250,64,29,12,6,249,215,59,30,238,251,229,231,124, + 246,89,9,48,4,127,176,6,104,195,111,169,102,210,197,21,156,61,118,8, + 0,43,151,172,13,11,219,102,156,5,77,180,123,247,17,207,82,235,112,57, + 58,25,88,54,137,227,135,12,227,130,73,99,24,49,106,40,99,199,245,195, + 233,12,225,245,122,177,216,15,16,244,233,86,154,49,87,205,102,49,187,36, + 117,10,11,21,222,128,11,128,144,223,74,137,106,194,165,149,225,15,250,176, + 91,59,6,161,144,31,236,86,43,74,21,98,115,234,243,222,236,22,55,227, + 206,40,98,220,25,39,241,213,111,6,65,251,2,251,119,216,216,184,185,154, + 61,59,246,178,234,253,229,180,186,219,105,247,6,136,22,58,221,234,211,51, + 59,157,132,56,46,34,116,161,112,114,10,128,166,13,194,239,171,3,234,113, + 56,250,227,247,121,88,183,185,137,61,247,175,226,189,165,123,184,231,190,75, + 24,122,124,144,210,18,253,137,249,14,135,3,143,199,71,160,221,67,97,159, + 232,199,127,245,6,222,121,167,14,77,11,224,113,183,177,127,255,33,84,88, + 220,64,195,162,249,195,15,62,214,176,171,3,216,172,53,88,220,110,176,248, + 81,190,144,110,117,213,1,45,33,44,78,31,161,214,16,154,91,129,15,180, + 127,131,230,242,131,213,10,238,16,86,60,104,125,66,104,159,5,208,70,129, + 237,243,106,20,251,65,41,84,176,5,13,227,81,112,22,52,180,176,155,218, + 78,67,99,53,159,110,174,226,184,202,254,148,148,148,72,178,144,208,35,232, + 177,2,103,177,88,163,30,42,12,16,10,233,43,33,31,110,240,241,224,127, + 125,206,115,207,237,163,169,65,183,120,130,170,217,100,177,13,167,180,204,199, + 242,229,27,88,253,193,70,124,190,53,64,45,30,127,29,224,1,237,80,196, + 50,43,112,106,120,61,186,200,13,40,59,129,51,198,140,231,228,179,79,225, + 242,171,71,68,68,75,211,218,41,44,116,211,222,174,225,15,250,40,176,91, + 35,79,25,49,167,232,27,214,154,166,181,211,167,68,31,136,172,193,82,44, + 246,32,118,85,135,215,90,73,97,65,27,5,161,82,44,22,79,248,156,156, + 248,67,110,10,108,22,2,94,13,127,200,141,82,133,56,11,170,113,187,244, + 233,1,118,28,20,151,104,140,62,53,200,241,163,138,241,122,198,112,203,29, + 19,216,252,201,97,86,46,93,197,222,106,47,91,183,213,134,173,59,195,178, + 107,210,251,194,1,116,215,165,142,61,236,186,180,219,219,240,251,250,162,209, + 23,159,207,139,70,0,13,39,13,13,205,188,242,79,47,107,55,28,98,206, + 220,139,184,98,218,16,108,14,23,190,118,232,91,50,0,171,181,16,143,199, + 71,113,239,210,55,54,111,110,197,162,41,14,31,118,227,247,251,163,158,26, + 233,176,4,8,4,219,64,131,62,5,171,41,40,221,142,182,175,25,44,33, + 180,86,13,213,2,28,80,208,170,80,33,63,90,61,208,170,192,173,161,54, + 128,102,133,96,83,8,203,78,13,85,9,90,169,87,95,185,237,44,13,107, + 77,51,86,199,33,208,202,177,171,122,52,53,16,48,102,137,104,104,216,80, + 56,80,74,177,107,215,126,220,109,167,18,8,4,69,224,132,30,65,143,21, + 184,80,40,20,249,39,213,51,250,10,9,6,3,188,249,150,30,107,123,229, + 133,114,188,193,58,52,109,23,154,214,143,138,190,54,190,124,89,63,198,159, + 83,206,250,181,141,60,254,199,151,240,249,54,163,47,121,229,197,89,96,35, + 164,53,227,245,232,113,140,2,167,134,207,3,22,53,154,241,99,207,229,162, + 139,47,228,204,177,67,25,126,162,7,139,197,67,123,187,134,57,245,223,16, + 55,0,175,39,72,73,81,17,118,207,1,92,148,81,88,168,34,125,54,132, + 203,98,45,37,224,247,99,177,7,177,217,237,40,251,16,10,45,37,104,22, + 221,114,11,4,236,225,227,192,70,95,108,54,27,142,2,208,231,216,130,10, + 157,70,191,114,208,44,30,60,237,237,180,123,117,151,166,221,82,68,105,191, + 66,60,237,237,156,57,97,0,147,190,248,93,106,246,7,216,181,107,47,239, + 47,223,197,251,31,238,161,238,240,231,56,237,253,77,238,76,195,117,233,140, + 184,46,253,62,39,10,27,22,173,47,26,78,148,50,18,81,60,56,28,54, + 246,86,31,228,182,91,159,230,182,205,95,224,182,31,77,161,172,172,136,198, + 198,70,138,139,75,113,56,58,92,197,6,118,187,157,158,204,190,106,55,74, + 121,105,105,110,215,159,44,98,218,103,213,60,160,26,65,5,41,44,223,140, + 163,186,14,246,121,208,154,67,168,131,16,201,93,178,106,88,106,20,161,29, + 154,158,148,191,23,180,253,186,187,87,251,196,2,107,130,104,67,53,152,166, + 161,214,133,80,39,91,177,110,110,199,238,8,160,41,133,93,213,17,82,253, + 0,115,251,90,248,229,163,165,181,25,175,215,75,48,16,128,2,113,83,10, + 199,62,61,86,224,140,7,36,27,66,215,228,246,243,207,151,170,121,236,145, + 237,108,218,82,142,85,235,75,129,245,100,66,180,112,217,229,62,38,95,52, + 140,234,170,125,252,227,153,133,172,219,252,41,250,136,2,198,106,31,30,223, + 33,0,52,6,224,116,244,167,79,225,201,76,186,100,10,23,76,25,25,113, + 63,250,85,0,143,92,243,43,203,0,0,32,0,73,68,65,84,199,2,20, + 225,176,106,248,130,209,89,214,69,246,162,200,223,22,75,27,193,162,190,20, + 132,10,48,66,82,54,187,29,155,77,183,226,156,4,192,102,199,111,43,196, + 30,104,199,111,43,68,95,158,43,108,217,217,236,56,194,143,117,242,5,162, + 99,90,1,159,149,66,139,43,92,198,78,65,129,147,98,71,31,130,1,93, + 84,2,129,0,5,5,229,224,109,196,239,63,192,128,129,208,167,223,0,206, + 248,194,104,174,217,222,198,198,205,213,44,123,119,69,216,170,131,142,132,20, + 103,196,117,9,167,160,209,132,82,250,118,133,19,45,156,249,233,243,213,163, + 225,196,235,43,229,145,255,93,207,158,29,123,185,245,238,235,57,235,172,18, + 218,125,141,56,172,37,189,46,206,227,106,243,17,82,1,60,126,5,81,242, + 166,176,18,132,160,27,77,105,88,189,109,104,139,219,193,170,17,220,9,150, + 173,232,15,195,218,162,224,120,80,85,22,88,15,212,107,240,169,5,26,67, + 40,47,168,151,53,180,189,192,62,5,175,162,207,70,91,26,66,109,129,208, + 176,64,56,139,210,131,10,249,233,16,53,69,199,16,16,36,16,240,16,12, + 5,9,202,138,17,66,15,225,152,21,56,159,247,16,142,130,1,145,101,105, + 236,118,63,193,128,27,127,160,136,194,194,66,64,35,24,108,195,239,183,83, + 83,223,198,252,191,180,241,167,71,27,105,110,25,14,52,227,15,214,112,226, + 200,32,151,79,131,17,35,224,189,165,43,120,227,173,143,240,248,86,1,78, + 208,86,69,218,82,170,20,84,41,133,5,253,57,101,204,87,56,115,220,69, + 92,243,77,69,81,97,105,248,201,239,122,108,13,188,24,25,214,254,16,104, + 26,148,168,38,90,57,14,167,83,23,33,91,216,82,177,217,202,163,206,167, + 208,25,155,222,175,127,118,0,216,138,41,214,83,66,177,218,59,127,101,230, + 8,90,208,31,192,90,98,35,232,183,162,5,3,216,173,54,252,182,0,96, + 1,155,209,70,1,190,64,16,205,98,44,215,165,183,19,8,180,48,252,68, + 63,195,79,28,192,229,215,222,204,166,143,119,176,114,233,42,62,250,216,71, + 221,225,67,116,100,101,214,134,135,104,125,2,185,195,81,130,223,87,16,158, + 36,78,88,232,234,80,52,161,225,228,213,69,251,88,183,233,165,136,203,18, + 71,51,158,22,27,78,167,222,243,226,226,98,66,161,32,1,127,3,86,91, + 17,193,128,59,50,111,174,167,80,84,168,80,202,175,63,251,49,6,165,124, + 88,180,0,33,165,161,246,133,208,118,128,230,10,161,138,45,176,60,136,218, + 109,65,115,41,104,1,181,9,180,109,33,84,131,6,43,20,150,102,5,65, + 208,22,6,209,66,64,80,17,250,99,8,173,25,168,83,168,62,26,202,103, + 3,130,104,49,150,99,184,117,244,167,109,121,195,83,56,82,46,130,42,8, + 199,12,199,172,192,25,226,102,183,219,177,90,67,128,21,171,13,28,5,198, + 250,109,193,136,184,253,104,86,21,139,223,116,0,197,248,131,53,216,173,149, + 204,248,214,32,198,159,83,78,117,213,62,30,249,159,53,84,85,175,0,254, + 13,52,133,7,102,112,20,244,193,231,41,160,176,160,132,145,39,156,205,212, + 75,206,231,255,179,247,230,97,146,220,229,157,231,231,23,87,70,228,89,85, + 125,223,82,75,66,2,36,25,4,194,6,196,33,176,96,48,30,217,140,109, + 24,99,174,129,241,154,245,12,182,121,198,107,27,31,203,120,188,187,222,177, + 253,48,198,131,89,123,141,7,97,33,134,197,6,219,18,136,75,71,35,144, + 133,145,208,65,235,70,221,93,221,213,234,163,186,170,242,206,184,227,183,127, + 252,34,34,35,179,170,91,2,73,86,183,58,190,207,147,79,101,70,70,70, + 68,30,21,223,248,190,239,247,125,223,215,95,245,74,182,110,51,232,245,142, + 161,153,234,74,87,145,219,106,84,42,21,66,54,81,55,117,212,240,99,242, + 1,147,69,5,6,96,234,198,42,242,138,147,42,186,54,194,182,87,59,41, + 19,127,128,27,55,168,85,101,254,88,171,212,41,248,92,114,120,222,234,46, + 41,102,24,17,22,246,159,169,64,195,48,136,162,8,194,101,94,254,202,141, + 252,200,143,190,135,159,121,116,200,63,252,253,237,220,126,71,230,196,156,97, + 92,22,209,206,195,150,82,110,70,144,17,93,86,22,161,66,174,243,11,223, + 227,67,191,241,32,247,239,125,53,111,127,247,85,60,111,103,130,231,121,212, + 106,13,134,195,33,150,101,97,85,54,48,104,247,112,154,213,233,195,61,227, + 177,101,171,197,3,15,170,139,177,177,130,82,208,136,72,8,16,72,120,68, + 34,142,39,170,149,241,223,162,34,195,3,137,180,52,196,102,13,241,96,2, + 71,5,194,151,136,187,37,34,53,167,200,0,197,83,166,64,91,76,32,20, + 48,148,16,235,208,141,65,100,223,117,186,127,153,164,143,2,96,8,4,84, + 29,7,193,217,231,112,45,241,220,197,25,75,112,160,242,54,73,18,23,102, + 181,57,133,25,109,130,219,239,28,241,223,255,68,141,175,209,80,86,105,77, + 235,242,203,31,88,207,142,157,38,119,236,41,170,182,14,118,37,198,245,59, + 8,161,236,253,129,215,226,5,23,252,232,4,177,13,188,62,189,180,8,45, + 9,117,252,169,14,35,217,44,175,177,82,155,252,136,51,165,150,169,23,117, + 223,73,9,106,76,100,134,145,17,226,164,210,43,188,136,234,212,227,34,162, + 40,196,48,178,99,208,167,158,139,241,112,39,8,213,70,169,191,48,142,80, + 10,47,33,142,66,154,198,136,230,165,130,247,239,184,156,87,255,248,107,248, + 230,45,243,124,233,203,95,197,11,59,249,107,69,161,45,152,105,173,39,12, + 148,203,50,145,93,198,102,21,155,99,203,30,215,93,123,27,237,19,26,191, + 249,191,95,206,236,236,28,113,28,226,121,30,186,110,18,199,1,213,86,29, + 215,117,159,115,38,148,75,46,105,112,211,215,15,16,71,233,156,54,41,201, + 170,210,52,17,161,225,41,201,255,16,136,0,146,57,29,113,44,129,77,2, + 17,75,120,137,32,57,63,65,124,59,165,198,138,64,26,18,57,171,129,47, + 144,231,130,88,72,144,150,64,110,50,16,139,49,178,170,195,8,132,159,32, + 228,100,96,20,65,234,220,84,37,46,66,184,108,217,186,5,45,55,151,148, + 74,174,196,153,143,51,150,224,178,206,36,65,16,163,235,9,186,174,229,57, + 55,16,220,240,165,1,191,255,123,143,114,120,65,164,179,217,22,56,239,156, + 58,191,244,31,47,98,174,181,204,159,255,233,151,120,224,225,135,241,194,111, + 98,217,139,248,158,196,11,250,105,87,137,13,108,156,217,201,43,94,113,5, + 63,247,51,47,99,247,11,182,3,30,189,222,128,48,14,168,87,27,171,84, + 219,244,144,202,140,216,138,161,199,105,82,83,235,165,68,102,175,127,194,247, + 108,219,54,158,231,229,219,145,193,100,174,68,88,250,120,121,225,155,205,136, + 174,248,56,219,70,20,133,68,145,218,78,145,244,204,164,74,24,172,224,122, + 62,213,104,9,125,195,22,94,255,122,141,93,59,207,101,215,238,55,240,141, + 155,15,241,192,195,119,224,133,3,108,179,14,68,120,225,81,130,160,131,109, + 173,35,8,207,79,75,10,198,109,206,4,176,184,236,113,205,117,119,209,237, + 206,243,219,127,240,62,118,109,247,9,124,101,62,1,101,8,178,44,107,226, + 194,229,185,128,215,190,118,61,127,250,223,124,36,6,160,49,86,112,202,172, + 159,77,157,17,143,131,212,65,188,88,170,48,228,54,16,247,3,63,34,17, + 47,16,136,187,19,228,107,52,196,253,169,210,250,128,142,252,219,24,222,0, + 242,1,77,189,246,195,192,255,42,144,191,172,193,103,65,14,45,228,161,201, + 73,223,146,4,149,211,93,1,86,104,52,102,56,255,252,13,24,134,145,154, + 179,202,110,38,37,206,124,156,177,4,167,230,147,169,226,237,36,73,242,206, + 36,0,55,124,105,192,111,124,240,32,237,182,34,55,128,75,47,214,249,143, + 191,177,139,193,210,126,254,252,79,191,193,93,123,31,67,112,19,136,5,2, + 95,93,60,75,217,192,169,92,192,171,47,221,194,27,223,246,30,118,239,222, + 201,166,45,30,195,193,32,175,61,51,180,22,94,122,177,13,138,216,148,57, + 100,242,163,204,66,144,197,208,163,109,59,5,101,182,218,53,104,79,169,176, + 181,80,171,53,136,227,16,93,55,193,49,199,247,97,98,185,136,79,78,14, + 158,231,81,209,76,252,68,169,188,162,210,203,200,110,56,130,153,153,89,102, + 128,78,167,130,63,24,18,27,6,231,95,80,97,235,182,231,113,241,37,151, + 112,211,29,59,184,249,239,191,201,241,229,5,148,130,83,164,237,5,135,17, + 52,198,223,85,94,39,152,181,43,59,202,223,127,17,132,118,19,31,250,253, + 31,231,220,115,27,180,87,14,97,85,102,177,109,27,199,113,242,230,205,32, + 158,19,147,9,94,251,218,77,108,217,98,114,228,200,8,33,12,148,66,74, + 59,153,128,10,25,202,132,228,197,2,142,9,53,85,237,223,168,58,55,90, + 26,236,76,16,151,130,108,106,104,63,9,73,91,67,236,22,240,186,4,190, + 3,252,152,64,58,2,158,47,161,150,144,92,161,161,93,33,145,75,2,237, + 129,52,140,153,24,140,199,72,128,10,31,31,1,22,121,229,203,223,64,173, + 102,97,87,108,116,253,140,61,45,148,40,49,129,51,246,151,172,154,35,219, + 185,146,51,204,57,194,48,228,198,175,184,124,242,19,251,57,116,112,125,218, + 141,36,226,149,175,218,206,187,127,113,59,123,239,60,200,167,175,253,22,203, + 43,119,34,120,4,80,164,150,133,36,55,205,94,193,155,223,248,26,126,254, + 189,47,163,90,29,145,36,125,6,125,13,112,48,52,71,25,40,132,139,227, + 72,146,100,76,70,69,114,115,236,202,4,81,197,73,21,219,150,24,134,254, + 132,164,150,17,149,186,127,242,43,104,93,183,210,92,206,244,107,204,252,117, + 186,62,233,82,140,11,142,206,90,45,45,246,141,199,138,175,72,118,81,20, + 210,168,169,2,243,145,11,166,53,199,214,141,27,208,173,136,78,167,141,208, + 60,126,228,178,152,23,94,124,33,47,185,200,228,51,159,218,159,170,225,62, + 146,89,148,171,242,152,218,7,54,176,57,85,115,89,97,188,135,105,213,249, + 187,235,111,166,178,49,225,87,127,241,66,118,238,92,71,69,83,199,181,188, + 18,208,168,107,105,121,71,26,198,59,195,73,206,113,52,254,221,123,47,224, + 255,252,63,110,39,201,75,42,212,123,138,165,69,34,91,8,49,128,203,116, + 24,10,117,173,112,169,132,227,144,92,4,66,211,208,234,18,185,3,228,118, + 96,135,36,121,57,136,102,2,155,52,146,243,5,218,72,64,75,32,18,137, + 220,174,35,37,68,187,107,132,223,75,155,107,39,27,144,66,7,98,226,56, + 64,114,0,216,135,97,68,252,196,155,175,196,182,109,106,181,218,170,139,181, + 18,37,206,84,156,177,191,228,68,182,80,78,201,56,29,76,154,228,228,166, + 166,107,47,160,105,53,126,242,205,14,87,191,173,197,45,123,110,226,11,127, + 243,29,144,243,192,190,180,49,114,218,82,75,110,224,178,75,126,134,119,188, + 251,245,188,252,149,27,25,244,99,92,87,224,56,30,20,50,93,245,134,78, + 20,170,19,181,237,140,243,101,211,97,200,162,41,196,48,180,9,98,123,34, + 66,139,99,169,26,230,166,249,197,56,78,242,26,177,204,84,3,144,149,141, + 77,230,32,227,52,76,91,92,150,164,235,107,249,84,133,108,134,91,86,114, + 48,173,248,100,96,18,166,199,99,85,212,79,36,138,66,252,145,129,105,205, + 97,219,35,34,175,77,100,56,92,241,170,221,236,222,189,147,235,63,127,14, + 55,126,101,79,234,182,220,130,26,13,228,96,91,53,252,192,75,51,58,202, + 120,34,217,130,31,28,70,99,134,235,62,113,43,222,177,133,60,92,137,23, + 82,117,108,178,147,63,156,249,228,6,234,187,254,149,95,185,140,207,126,246, + 30,246,237,59,14,178,150,134,43,33,144,117,18,214,35,89,32,217,214,64, + 142,86,160,18,163,213,33,105,9,69,104,71,12,226,145,134,216,17,145,24, + 49,98,139,134,118,33,32,116,146,205,26,90,69,32,231,82,114,139,4,212, + 117,130,197,38,35,125,51,158,187,13,100,155,80,91,143,250,151,79,240,252, + 69,224,126,132,56,204,155,223,244,211,60,239,162,77,52,155,45,170,213,42, + 186,126,230,127,222,37,74,192,25,76,112,150,101,164,39,62,117,234,252,246, + 183,70,124,244,143,231,217,243,173,165,137,250,182,171,223,182,155,91,246,220, + 196,103,62,241,101,148,37,237,62,16,11,121,134,193,182,206,229,141,175,191, + 154,255,240,107,63,69,171,213,162,219,237,82,173,142,24,141,170,140,70,74, + 177,133,113,64,197,214,113,125,85,40,173,233,227,240,219,180,98,203,194,144, + 167,34,181,105,117,86,44,114,214,245,113,94,45,155,132,176,214,122,197,117, + 166,239,79,46,83,39,43,165,116,39,159,215,245,226,192,210,177,42,196,49, + 9,34,69,218,73,218,75,204,48,134,80,13,49,227,145,90,110,111,77,221, + 153,30,207,191,168,194,142,95,127,61,23,191,88,227,211,159,186,153,123,246, + 42,114,3,23,47,88,78,219,67,217,169,138,219,133,160,139,228,14,18,206, + 69,99,51,55,126,237,40,173,250,39,120,255,7,175,98,247,238,205,105,158, + 49,127,215,64,248,156,40,4,159,155,115,248,171,191,250,9,222,242,150,191, + 162,211,57,140,34,113,141,64,214,144,218,58,16,130,144,77,68,91,143,99, + 152,30,137,30,33,155,2,125,70,18,28,53,17,253,42,250,150,62,154,158, + 32,103,33,89,111,130,39,144,235,5,113,175,2,213,4,177,18,162,199,130, + 200,110,208,91,126,30,109,247,5,12,195,115,144,116,17,122,3,197,93,75, + 196,241,45,32,30,226,5,207,127,17,239,122,207,91,104,212,155,204,206,206, + 174,233,216,45,81,226,76,197,105,79,112,197,89,110,197,19,183,148,46,73, + 226,32,165,199,221,247,73,62,252,225,121,238,184,99,29,154,54,34,161,199, + 213,111,126,148,119,188,239,117,92,255,185,91,249,204,117,95,198,169,44,48, + 242,191,11,164,89,8,121,62,118,37,230,223,191,247,3,188,253,93,47,1, + 192,247,219,84,171,170,11,73,177,133,86,189,170,8,45,203,181,77,59,33, + 167,73,45,11,181,101,166,143,76,169,21,137,237,100,39,236,103,202,88,177, + 150,10,154,38,208,140,92,227,56,161,145,41,74,67,166,203,108,60,15,72, + 93,157,138,132,212,201,48,14,35,42,198,60,111,254,137,11,216,48,187,133, + 207,127,254,111,249,199,27,19,53,77,220,140,240,194,3,192,22,100,30,170, + 132,188,80,156,123,240,130,89,254,231,23,0,253,49,254,195,175,239,98,203, + 134,99,24,209,144,64,191,144,70,29,130,32,64,38,29,12,115,142,44,135, + 116,38,170,58,77,211,120,249,203,183,243,233,235,222,201,175,126,224,26,246, + 237,223,15,24,72,169,35,13,19,41,151,8,188,173,68,181,163,8,121,28, + 49,16,104,117,65,44,5,82,111,225,15,107,88,173,8,211,136,96,29,72, + 195,36,25,89,208,212,241,186,13,116,45,164,98,246,73,34,73,100,213,25, + 6,187,241,204,151,96,214,91,200,164,171,114,107,114,4,220,132,166,221,197, + 43,95,241,58,62,240,129,183,179,126,125,131,13,27,214,211,106,181,86,57, + 110,75,148,56,147,33,164,148,167,189,31,56,11,179,77,159,212,2,255,4, + 137,108,241,198,55,29,231,161,239,29,99,169,221,197,212,183,242,194,23,14, + 248,240,31,92,196,39,63,177,159,175,125,229,47,241,194,111,146,205,104,203, + 58,254,111,156,121,30,191,245,187,191,197,21,175,218,141,239,183,243,246,90, + 69,151,100,150,107,43,90,254,159,12,185,157,140,216,50,167,231,233,138,226, + 197,196,56,140,169,194,166,113,60,110,173,149,57,57,61,207,195,243,60,52, + 225,210,239,69,160,55,49,28,135,35,223,63,198,71,63,250,8,159,191,254, + 239,0,144,204,22,26,82,207,96,87,54,224,249,170,112,60,41,148,17,216, + 150,206,47,255,178,106,237,229,104,203,88,149,89,18,89,163,234,196,216,54, + 120,158,250,76,179,169,4,103,34,164,76,240,3,159,67,7,143,243,153,207, + 236,225,59,223,249,30,111,120,195,229,108,222,188,5,91,244,121,193,246,199, + 168,37,119,81,179,231,209,42,29,68,16,16,91,22,65,127,3,177,172,81, + 171,236,199,110,28,65,30,182,8,119,54,145,163,10,81,199,196,175,108,69, + 211,70,56,98,17,173,158,208,237,108,162,155,92,73,236,188,22,171,190,157, + 175,125,117,63,47,190,108,35,215,95,127,152,35,71,238,228,178,151,156,203, + 11,94,184,157,70,173,206,198,77,27,216,184,113,19,141,70,13,33,158,91, + 161,225,18,103,55,78,91,130,155,206,35,173,245,207,214,238,29,231,191,252, + 103,193,199,255,251,18,177,236,98,138,29,156,187,251,65,126,253,195,63,198, + 222,59,15,242,151,31,255,56,94,120,23,146,249,116,124,141,194,198,153,55, + 241,155,191,243,94,174,120,213,110,0,150,219,135,0,48,117,11,199,145,184, + 174,200,109,255,89,174,45,115,69,158,140,216,178,229,211,164,118,38,135,214, + 84,179,106,45,39,187,44,132,153,145,157,231,165,125,51,205,136,192,149,68, + 81,76,28,24,120,81,204,225,197,46,255,227,83,15,113,243,223,127,147,99, + 203,209,196,112,87,167,114,1,158,31,32,241,83,21,231,97,91,58,94,112, + 152,77,235,54,240,161,223,123,55,63,255,246,139,232,117,15,51,183,161,129, + 165,215,145,65,140,225,216,196,113,72,237,12,47,146,147,82,18,4,1,221, + 110,151,118,187,141,235,142,104,181,102,168,218,22,126,255,48,201,104,30,61, + 152,39,246,23,17,201,128,72,218,132,178,142,33,36,51,214,253,84,234,7, + 96,160,49,52,102,137,195,38,137,108,224,39,91,209,136,168,26,199,144,68, + 120,201,122,70,250,75,177,102,47,99,118,253,54,52,205,192,117,221,52,95, + 29,211,233,116,16,66,208,106,53,153,153,153,165,90,173,174,250,31,43,9, + 174,196,153,142,51,130,224,50,196,241,16,93,87,39,55,207,11,248,248,95, + 12,249,208,255,118,52,39,183,132,30,159,251,194,118,174,255,220,173,124,242, + 186,47,2,123,176,236,46,129,87,1,161,122,73,190,225,165,111,230,29,239, + 255,16,47,188,204,98,249,196,32,159,187,6,228,234,205,243,52,234,13,125, + 162,150,45,179,251,159,138,216,116,93,16,199,18,203,210,79,107,165,246,195, + 34,107,144,92,84,116,25,201,129,50,162,36,241,128,126,47,162,214,104,112, + 228,72,135,255,239,127,62,202,117,215,222,198,177,229,8,45,173,137,147,120, + 104,226,194,180,16,28,224,88,78,112,208,225,37,151,92,197,239,254,254,107, + 121,233,229,235,209,132,75,34,29,172,202,58,26,245,241,9,247,76,86,113, + 25,226,56,198,247,253,244,66,194,192,52,117,226,48,38,240,123,4,110,15, + 111,212,193,243,70,200,88,34,116,19,93,139,48,163,227,36,254,60,73,16, + 225,199,85,164,86,67,90,45,52,179,137,174,27,232,120,196,145,79,44,45, + 52,123,51,141,217,77,180,102,54,96,85,172,188,13,87,28,199,68,81,136, + 38,52,172,74,5,211,52,214,156,226,93,18,92,137,51,29,103,12,193,197, + 241,48,239,81,152,36,73,161,214,205,99,165,171,250,251,253,209,159,92,4, + 192,239,254,230,111,131,118,31,158,191,160,108,233,169,122,123,241,197,239,231, + 131,191,246,14,46,127,153,228,240,177,222,196,254,50,229,6,208,154,25,23, + 39,23,77,36,182,237,228,247,179,80,228,180,105,228,76,86,108,79,132,98, + 8,51,8,98,44,75,39,142,19,149,35,75,75,13,52,83,125,23,43,39, + 250,216,182,195,145,35,29,238,184,35,228,15,255,224,83,28,91,142,168,88, + 219,241,131,195,8,206,65,80,65,226,163,122,91,102,51,232,0,92,254,205, + 79,94,206,111,255,193,251,104,213,143,33,204,132,173,27,207,97,56,236,51, + 51,99,19,134,102,238,52,125,46,64,74,57,65,48,113,28,19,134,17,65, + 24,18,71,97,222,188,64,211,53,100,36,241,124,23,207,119,137,163,8,93, + 215,208,13,27,211,52,48,13,3,93,211,136,226,144,40,74,48,76,3,199, + 182,169,216,14,150,101,158,114,159,107,161,36,184,18,103,58,78,107,147,201, + 120,242,179,36,142,70,232,70,149,36,73,184,119,239,136,79,126,98,63,237, + 118,200,74,55,66,202,101,126,229,87,118,113,222,121,58,111,251,185,255,135, + 32,92,64,242,125,4,118,94,227,118,217,37,191,192,7,127,237,29,92,116, + 169,224,209,3,135,169,55,171,36,161,34,208,48,14,192,181,168,213,235,68, + 169,74,57,153,106,155,206,177,21,201,237,185,62,67,171,88,142,96,154,33, + 113,44,210,94,160,58,56,18,225,122,4,241,128,192,149,212,235,117,162,40, + 166,53,51,203,21,175,105,242,11,243,175,230,227,31,255,103,188,224,49,4, + 51,168,9,226,51,169,101,68,245,182,148,144,154,82,224,11,95,252,38,231, + 156,191,147,183,191,251,42,118,108,51,88,60,218,166,177,46,203,195,169,227, + 41,150,77,156,201,152,38,26,93,215,209,52,13,203,50,144,50,109,96,157, + 213,103,75,168,198,117,146,56,66,38,18,161,9,132,16,232,186,150,111,71, + 74,213,151,75,104,170,72,126,173,223,229,19,145,91,137,18,207,5,156,214, + 4,167,186,155,43,123,187,110,84,17,194,97,254,72,151,107,175,57,204,63, + 125,43,204,77,37,111,122,179,195,107,95,183,139,127,255,239,254,134,32,120, + 12,187,178,15,47,232,99,85,4,190,215,224,133,23,188,145,15,254,218,59, + 184,240,98,135,142,251,40,245,214,22,98,63,33,74,186,24,90,139,153,214, + 152,216,178,156,219,90,185,54,219,182,159,83,57,182,31,22,138,232,106,132, + 97,48,81,214,224,56,14,184,32,107,6,177,39,105,89,1,154,88,100,221, + 92,133,183,191,251,42,0,62,242,167,55,230,83,208,179,105,3,146,25,84, + 49,248,49,188,240,40,170,195,198,44,215,93,123,27,23,95,114,9,51,235, + 214,17,142,14,209,88,183,179,80,66,160,46,46,158,43,36,55,13,33,132, + 234,89,185,6,84,228,220,124,82,42,172,68,137,179,25,167,125,12,34,35, + 57,33,20,241,236,189,71,231,250,207,237,103,165,27,97,234,91,57,103,87, + 204,213,111,219,205,167,255,250,22,86,86,142,3,123,112,253,37,0,124,79, + 178,105,246,10,222,247,75,111,227,162,75,133,50,147,120,155,72,130,33,66, + 184,212,171,13,132,112,137,194,16,219,113,48,12,131,102,173,70,179,86,163, + 234,140,67,146,197,222,141,112,234,46,35,103,11,194,48,196,202,122,95,74, + 15,215,85,225,69,203,178,168,26,2,71,87,195,93,173,202,44,221,225,50, + 155,214,119,121,251,187,175,226,103,174,126,51,26,155,11,91,82,245,113,154, + 104,1,155,211,78,40,10,199,151,7,252,205,255,251,37,246,63,252,16,205, + 217,89,22,23,14,145,200,90,222,131,51,142,79,203,232,250,191,24,74,114, + 43,81,226,212,56,173,9,46,73,146,220,65,25,133,203,220,187,119,196,71, + 62,210,229,224,241,141,152,98,7,177,236,242,182,119,205,178,247,206,131,220, + 240,149,71,144,220,10,89,206,77,94,130,83,89,207,91,255,237,85,92,254, + 178,89,60,215,205,235,217,164,84,100,153,132,58,149,74,37,87,109,142,93, + 81,125,35,245,38,154,94,199,182,109,42,154,73,173,214,64,215,77,44,203, + 202,115,63,217,237,108,133,105,154,121,29,157,174,215,82,103,163,68,215,117, + 116,93,80,169,59,24,142,186,40,152,157,81,245,85,219,54,15,120,199,123, + 206,229,245,47,59,150,110,101,51,146,14,112,28,41,143,163,137,86,74,126, + 179,168,46,247,7,216,243,207,247,243,165,47,53,232,15,85,71,153,40,56, + 140,27,91,12,135,125,226,88,141,159,153,158,14,94,162,68,137,18,112,26, + 19,156,58,121,106,169,173,121,200,32,108,178,231,214,144,189,119,237,69,23, + 45,66,185,192,43,174,172,208,239,88,252,195,23,190,141,38,239,1,252,188, + 206,13,58,252,252,91,126,137,171,223,242,34,64,205,108,243,125,95,41,182, + 164,139,227,72,52,51,206,107,220,50,51,73,213,129,86,115,220,94,107,156, + 111,59,123,67,146,79,30,89,189,159,158,183,28,179,109,27,75,175,99,24, + 38,173,214,28,175,184,226,66,222,254,75,191,202,75,46,217,14,28,195,178, + 212,20,133,172,33,179,76,167,131,43,216,192,81,190,117,203,45,124,231,91, + 71,104,206,206,210,239,69,184,125,229,190,44,58,56,75,146,43,81,162,196, + 52,78,91,130,3,229,156,204,48,191,47,228,211,215,124,159,32,82,39,209, + 117,235,58,252,244,155,207,229,182,155,238,226,224,194,87,241,194,219,177,43, + 131,220,84,242,134,203,47,229,234,183,94,73,171,213,194,243,52,28,71,42, + 51,9,170,51,73,146,216,121,88,50,35,55,219,118,208,210,147,113,69,27, + 231,220,74,114,123,114,40,186,238,44,75,79,213,156,153,231,45,135,195,62, + 186,45,120,245,85,235,120,231,251,94,195,166,117,17,97,16,145,205,146,147, + 50,173,171,99,51,217,180,112,128,239,238,253,58,183,222,242,56,71,79,108, + 70,198,125,194,164,79,20,101,37,11,97,90,182,160,148,92,209,233,249,108, + 35,187,64,59,83,111,37,74,156,233,56,109,127,197,153,131,50,240,79,160, + 235,53,246,220,26,242,192,3,117,188,112,134,88,118,185,234,170,11,89,56, + 20,114,228,232,215,129,135,177,43,117,188,224,0,0,155,102,175,224,93,239, + 127,59,91,183,25,116,187,221,201,182,91,82,117,206,152,86,110,211,78,73, + 195,25,147,155,174,107,37,185,61,73,20,79,142,202,193,39,176,109,139,102, + 179,73,69,51,137,61,73,205,244,185,226,53,231,243,11,239,124,53,146,78, + 65,189,249,105,43,175,86,186,204,65,145,95,135,123,191,119,43,223,187,251, + 24,66,111,224,121,30,81,164,106,185,60,207,155,232,178,82,236,192,82,162, + 68,137,179,27,167,45,193,1,121,81,247,221,247,13,248,203,143,29,6,32, + 73,134,156,119,78,157,221,207,179,184,237,166,187,232,246,212,85,127,34,150, + 213,139,228,6,222,241,238,119,113,193,197,23,49,240,250,57,185,185,174,96, + 86,27,17,218,155,208,52,111,66,185,197,73,117,194,41,169,200,77,228,249, + 182,162,61,190,196,147,67,177,134,49,115,58,86,91,170,237,150,229,8,118, + 108,51,120,213,149,175,207,67,149,0,150,21,41,146,19,118,90,20,62,131, + 114,84,218,220,179,119,200,55,111,121,128,110,63,198,245,124,60,207,205,103, + 215,201,32,158,32,185,18,37,74,148,128,211,152,224,226,56,38,73,18,172, + 202,6,174,189,230,0,251,230,7,249,115,151,255,88,141,239,125,119,137,135, + 30,189,13,47,220,11,56,4,190,42,220,222,56,251,82,94,245,234,221,116, + 187,93,146,96,152,27,74,0,100,99,59,134,105,210,172,52,214,204,185,85, + 52,115,106,166,218,116,235,162,231,118,157,219,51,129,76,249,102,197,202,25, + 52,49,228,21,47,183,120,251,187,119,231,69,222,42,92,169,32,153,73,235, + 229,236,244,214,230,198,175,236,225,142,59,66,154,205,45,0,120,158,139,231, + 121,248,201,184,195,138,218,87,121,33,82,162,68,137,211,152,224,178,19,227, + 221,247,13,248,234,141,71,149,177,36,62,194,5,187,55,1,112,223,189,119, + 166,179,221,142,131,216,11,168,209,55,191,249,59,239,101,219,142,8,219,86, + 161,170,76,193,101,189,37,1,132,93,203,109,255,89,206,45,83,110,197,253, + 151,132,246,212,145,36,113,218,100,90,75,139,151,45,28,107,150,102,179,73, + 163,174,241,154,215,95,201,207,94,253,122,212,48,212,142,154,250,45,61,4, + 21,76,203,64,178,133,44,76,121,124,249,4,183,221,244,13,14,47,118,85, + 104,50,84,132,56,29,170,44,195,148,37,74,148,128,211,152,224,146,36,65, + 74,151,107,175,57,192,163,251,26,170,223,164,190,149,231,191,48,198,31,124, + 143,249,133,239,225,133,75,144,186,38,165,108,240,19,87,189,159,43,94,181, + 155,165,229,69,124,223,207,183,101,106,202,98,174,107,117,26,245,113,163,94, + 149,119,27,43,55,32,207,185,149,120,122,32,165,34,172,113,87,26,213,71, + 50,142,37,110,208,230,156,243,76,222,244,214,215,177,115,199,78,44,107,125, + 74,106,42,76,25,4,75,83,91,235,112,251,29,243,28,123,244,65,130,40, + 33,140,163,137,80,37,144,27,78,74,148,40,81,226,89,59,147,23,195,72, + 73,18,175,186,69,225,50,97,104,114,227,13,227,215,156,183,251,48,245,70, + 147,187,238,57,129,224,33,224,96,222,68,217,169,92,192,59,223,251,90,194, + 240,40,134,214,154,216,151,102,198,216,142,131,208,20,25,22,77,37,48,89, + 10,240,47,69,110,89,141,223,218,207,157,252,179,121,42,219,61,249,107,226, + 85,251,125,186,160,235,53,116,189,150,27,79,50,101,174,137,46,142,53,75, + 236,73,126,234,141,33,175,123,245,70,162,112,29,97,16,229,51,227,4,187, + 168,88,219,81,117,113,170,157,87,111,240,16,55,222,33,136,2,29,215,243, + 137,195,8,77,168,80,229,200,213,243,109,151,101,3,37,74,148,120,214,8, + 238,137,194,127,134,57,199,103,190,224,209,110,167,38,146,100,136,237,204,224, + 15,190,199,241,227,251,128,113,13,148,148,13,126,254,45,111,165,86,31,226, + 71,147,39,247,74,165,178,202,49,9,172,106,191,165,200,77,95,53,4,244, + 153,196,90,86,236,105,114,131,177,10,58,217,243,211,219,252,65,44,222,89, + 83,235,226,223,127,9,168,225,165,164,179,222,108,174,126,235,149,204,205,181, + 10,53,112,99,20,235,226,92,63,226,145,127,94,224,200,227,17,50,81,203, + 35,47,198,48,116,52,49,156,48,155,252,160,68,95,162,68,137,231,22,158, + 245,88,220,244,9,53,35,152,56,78,248,242,231,110,97,165,27,161,139,22, + 235,103,91,236,220,101,177,127,191,133,23,220,15,116,0,15,41,27,108,156, + 121,30,87,191,245,74,0,226,160,142,110,41,67,74,70,110,134,97,160,27, + 38,166,174,90,111,214,235,245,85,166,18,149,115,251,151,251,56,166,247,149, + 41,180,113,72,47,158,32,54,96,226,185,172,70,240,7,81,119,107,31,135, + 190,230,223,103,26,113,156,164,37,4,234,241,171,174,172,240,175,255,149,133, + 83,105,164,19,6,20,130,192,72,103,201,141,137,239,187,123,191,206,254,253, + 106,134,95,24,71,184,129,10,73,122,158,135,12,98,194,168,154,238,163,52, + 155,148,40,113,54,227,89,13,81,102,170,161,168,154,178,16,219,222,7,125, + 110,190,89,205,252,138,101,23,97,44,177,50,74,56,116,100,63,138,220,124, + 16,39,16,216,188,234,138,183,178,117,155,34,47,219,78,136,181,33,154,57, + 121,114,179,12,13,221,52,114,114,43,150,3,60,147,53,110,79,38,252,87, + 84,106,25,178,251,113,52,90,117,203,158,139,194,149,31,72,221,253,32,68, + 184,22,113,62,221,234,206,52,77,226,104,4,192,76,213,228,237,255,203,107, + 168,213,103,199,70,19,97,163,137,86,218,237,68,213,196,57,21,3,232,112, + 195,223,238,231,200,227,17,163,145,160,55,28,146,196,3,60,207,197,79,50, + 195,73,153,139,43,81,226,108,199,179,174,224,138,40,182,231,186,246,154,3, + 244,220,113,227,221,153,198,118,134,199,143,177,180,242,8,112,60,237,97,8, + 27,102,118,242,211,111,121,37,3,79,205,124,11,165,129,219,17,84,3,245, + 120,186,83,73,134,204,84,242,47,241,158,166,195,127,197,191,69,114,91,139, + 204,140,104,37,191,101,200,158,203,238,103,175,47,110,51,219,95,113,95,79, + 182,158,175,248,124,241,184,159,206,122,192,226,69,133,227,56,68,225,50,47, + 126,177,195,107,94,57,61,183,204,33,12,106,144,151,12,40,60,248,232,30, + 218,237,177,97,104,228,78,188,44,15,85,150,185,184,18,37,206,94,156,54, + 4,55,125,34,250,238,253,33,115,45,165,202,146,100,200,166,115,67,86,186, + 143,35,80,227,84,84,67,229,13,108,223,113,57,141,89,19,223,109,43,245, + 230,39,84,157,6,161,189,9,195,52,209,141,241,9,179,216,169,4,158,217, + 169,0,211,10,232,100,74,46,83,96,25,81,229,199,58,69,106,197,101,211, + 203,139,36,119,42,53,247,68,198,158,181,20,94,246,56,142,135,79,41,20, + 58,141,44,63,150,200,177,33,168,81,209,120,211,91,95,183,106,93,33,236, + 188,38,206,245,7,128,207,98,59,164,215,31,215,70,78,79,22,47,81,162, + 68,137,103,149,224,178,124,210,52,78,44,121,60,124,119,204,104,180,68,146, + 12,169,86,66,230,170,90,106,46,57,86,88,179,197,43,175,120,30,155,182, + 120,152,186,69,152,140,208,173,1,82,58,121,238,205,50,52,108,219,158,8, + 77,102,174,73,120,246,250,75,158,140,40,114,242,138,187,167,188,77,147,93, + 70,114,97,248,228,222,79,70,134,39,187,77,67,8,123,226,181,79,21,174, + 171,36,151,109,91,4,65,132,110,84,9,130,128,127,253,6,139,185,185,130, + 11,86,216,72,233,96,90,197,209,133,46,208,225,177,71,254,41,87,238,174, + 167,242,118,69,162,43,187,155,148,40,113,118,227,89,37,56,33,236,60,236, + 149,17,141,231,5,180,151,230,233,246,106,184,193,8,77,171,81,173,174,231, + 208,193,0,55,24,66,26,154,204,240,178,151,190,140,78,119,5,205,140,241, + 189,152,138,161,222,146,97,156,124,150,107,177,199,228,51,141,181,242,106,211, + 143,215,82,111,25,98,127,101,226,118,42,196,209,8,211,12,215,52,167,172, + 117,191,184,223,147,221,95,235,181,69,178,251,97,145,153,75,60,47,192,182, + 173,188,45,91,163,174,177,115,235,238,130,209,164,2,194,78,187,156,100,189, + 41,85,168,121,225,224,65,124,183,77,20,169,130,239,56,140,240,83,243,77, + 54,51,174,68,137,18,103,47,158,181,137,222,202,68,224,228,243,222,194,48, + 68,38,29,44,107,29,95,252,202,38,98,249,48,82,182,144,114,200,236,236, + 38,218,237,111,35,56,0,233,137,79,202,6,47,188,64,141,194,169,216,58, + 113,80,167,106,10,252,168,143,94,81,196,149,229,222,78,230,154,124,186,80, + 84,99,107,169,155,40,84,196,164,27,213,220,60,145,45,43,194,136,86,32, + 238,78,18,89,212,133,36,37,117,109,134,56,234,166,43,183,208,43,202,106, + 111,0,145,161,238,199,209,8,221,168,230,199,34,132,157,19,82,118,108,197, + 144,232,147,37,182,108,59,79,151,203,50,27,96,107,154,33,113,28,34,132, + 77,173,86,227,196,146,199,79,253,148,207,125,15,180,144,210,65,242,72,90, + 23,119,14,153,115,22,42,128,207,183,255,57,224,61,163,173,140,106,22,118, + 252,56,210,78,136,252,109,68,122,140,111,132,224,133,105,174,245,185,57,245, + 187,68,137,18,167,198,179,170,224,138,86,249,76,77,5,65,196,109,183,30, + 156,88,175,86,119,25,12,125,138,181,111,0,23,93,152,230,223,188,24,33, + 92,130,212,53,215,168,142,79,102,113,82,205,239,23,67,147,79,23,214,170, + 85,131,73,247,99,113,89,182,238,52,50,114,203,17,117,39,201,13,212,253, + 194,227,216,95,33,74,149,202,116,94,46,12,77,194,208,92,21,118,44,154, + 87,214,122,93,49,228,121,50,194,123,58,112,178,146,140,117,115,22,63,249, + 179,87,229,143,5,21,69,208,194,70,96,227,84,234,40,21,231,210,27,60, + 196,254,253,135,16,137,250,220,66,239,228,117,111,165,217,164,68,137,179,15, + 167,133,201,36,12,195,92,25,140,34,201,222,187,14,146,36,42,212,164,105, + 42,116,53,28,28,206,215,151,120,56,149,245,156,115,254,78,182,110,51,8, + 3,63,111,199,5,160,27,202,92,98,219,54,181,170,92,101,44,121,186,174, + 230,167,237,253,107,145,218,169,28,144,211,207,71,65,172,212,91,70,108,73, + 135,216,107,35,147,222,228,45,58,43,21,212,226,0,0,32,0,73,68,65, + 84,4,81,151,97,144,32,100,151,200,85,175,31,250,73,190,15,77,116,137, + 227,48,207,201,77,239,55,219,119,241,24,166,31,79,191,46,203,153,62,157, + 229,2,69,133,169,126,7,26,151,188,160,194,174,205,27,242,231,165,116,112, + 108,53,55,206,245,235,249,107,93,127,192,227,135,35,226,244,125,247,252,62, + 196,170,233,246,244,188,184,178,253,90,137,18,103,31,158,181,16,37,140,157, + 116,69,194,233,116,70,244,131,0,33,116,164,180,153,107,25,120,110,27,47, + 136,153,84,112,179,188,232,146,29,184,131,30,166,85,193,170,106,4,253,24, + 167,162,12,10,150,49,121,66,19,150,254,180,150,6,100,133,216,192,42,194, + 90,11,39,91,174,54,160,20,136,144,99,213,38,147,30,210,95,65,0,210, + 7,153,180,17,154,42,155,16,149,57,72,58,212,52,24,6,13,106,86,151, + 254,160,74,171,222,161,235,207,80,75,67,180,166,145,133,33,215,56,142,162, + 90,156,134,222,154,88,55,50,230,242,208,103,22,174,204,62,131,31,54,100, + 89,172,129,44,222,247,188,0,211,12,185,228,165,187,56,248,197,187,242,105, + 16,174,103,164,29,77,178,252,159,90,222,62,118,16,216,132,166,55,0,242, + 254,148,89,159,209,12,170,1,179,40,7,121,150,40,113,22,225,89,35,184, + 44,7,83,68,24,85,233,44,75,72,206,1,142,35,132,135,48,66,150,86, + 6,228,197,221,41,154,85,53,85,32,76,166,84,137,97,16,71,33,24,149, + 116,206,219,51,123,66,91,147,220,78,69,30,160,8,100,106,157,162,114,147, + 73,143,88,44,34,146,126,254,124,48,90,196,74,69,106,34,34,244,68,13, + 159,169,105,0,138,144,250,3,15,28,165,228,50,146,59,217,177,69,65,172, + 8,117,77,172,160,87,207,157,120,109,145,228,224,233,169,133,203,136,45,142, + 147,156,232,76,51,36,142,70,156,187,91,87,23,16,98,22,178,73,223,162, + 133,101,52,240,194,14,160,142,125,165,119,84,109,43,238,231,36,23,135,17, + 216,217,148,1,168,213,50,162,43,11,191,75,148,56,155,240,172,42,184,12, + 217,137,174,86,171,113,239,3,189,147,172,149,85,242,170,147,221,182,237,187, + 208,56,72,24,87,169,154,51,68,97,136,110,141,144,73,11,195,138,211,194, + 110,185,170,223,228,211,133,162,81,99,45,98,203,141,34,5,83,8,81,87, + 253,101,5,189,50,183,166,153,36,87,110,214,126,96,3,164,19,200,163,197, + 4,54,46,98,57,22,208,32,22,139,57,201,13,131,6,240,56,194,216,134, + 230,30,163,81,183,233,250,51,249,166,115,178,75,143,47,78,149,97,126,108, + 5,19,75,118,172,241,232,64,110,98,201,20,29,128,231,129,174,199,185,11, + 53,27,102,250,195,32,8,98,44,171,208,128,89,211,73,18,27,195,180,185, + 228,114,149,123,203,40,201,177,170,120,65,27,55,52,210,169,114,234,247,112, + 104,193,103,56,168,33,132,75,179,89,39,136,98,32,154,216,79,28,135,232, + 186,245,67,29,99,137,18,37,206,92,156,22,241,154,108,126,87,146,36,12, + 150,246,179,210,141,144,178,88,119,117,124,213,107,206,221,117,46,115,219,198, + 121,55,211,59,158,231,225,44,67,67,152,107,27,14,158,49,55,93,129,60, + 114,53,86,200,165,17,164,198,153,116,249,42,114,75,33,179,229,174,9,182, + 154,148,16,184,1,206,253,251,20,201,137,25,68,178,95,237,75,44,210,233, + 248,212,180,177,210,3,56,222,29,135,13,147,208,200,13,44,121,142,47,219, + 103,210,65,70,135,242,220,222,244,177,230,38,150,180,238,46,127,171,105,94, + 43,223,71,18,255,80,141,141,173,41,211,79,24,134,196,113,66,28,39,188, + 232,133,26,21,43,129,116,178,128,27,20,149,122,22,170,118,121,252,240,65, + 250,237,48,111,205,22,167,185,183,181,199,232,148,205,151,75,148,56,155,112, + 26,16,220,164,1,224,190,59,15,174,90,99,52,180,200,231,190,225,81,177, + 5,173,214,57,249,88,156,48,25,49,16,51,249,212,128,12,217,56,156,167, + 91,189,61,41,76,57,30,115,2,153,70,65,69,201,68,169,215,196,142,128, + 14,184,195,124,181,145,49,159,110,168,195,176,208,193,3,160,179,162,46,0, + 6,221,113,191,42,111,160,72,79,51,211,161,160,197,186,176,130,90,4,69, + 170,177,88,28,19,29,48,12,146,177,137,37,136,233,15,60,134,126,66,16, + 171,125,79,147,211,15,14,129,166,169,48,164,231,5,128,186,248,200,110,59, + 182,101,193,5,21,150,118,236,168,48,157,125,92,11,183,216,14,209,24,255, + 102,2,191,253,20,143,171,68,137,18,207,21,60,107,33,202,44,217,159,213, + 193,5,254,9,132,54,195,114,111,23,73,178,132,16,30,234,228,86,37,150, + 217,73,171,131,192,38,240,90,212,154,143,99,219,235,48,189,17,161,118,14, + 73,90,0,222,106,164,39,94,109,3,134,161,174,216,45,75,25,24,134,195, + 33,186,174,33,165,151,23,22,159,12,107,25,40,138,198,146,12,171,106,215, + 166,242,104,0,186,220,56,17,82,148,73,15,145,52,39,182,19,123,109,132, + 236,42,51,201,8,96,6,233,236,131,81,135,104,113,51,213,232,28,122,77, + 15,240,168,53,234,48,234,211,117,171,52,215,45,48,232,238,192,237,6,212, + 90,43,192,54,170,122,74,140,41,65,70,186,82,63,66,118,199,234,204,107, + 35,43,203,136,81,31,161,205,34,70,125,226,84,16,235,9,212,180,133,52, + 100,57,14,79,182,244,78,90,111,55,194,117,85,177,118,28,155,232,58,128, + 76,243,114,202,200,145,125,175,217,231,6,76,24,84,130,64,133,57,53,77, + 117,51,81,235,37,233,107,99,116,91,176,121,110,19,243,199,34,16,45,92, + 207,199,174,116,241,252,153,137,76,154,93,89,225,120,219,98,139,104,50,112, + 31,103,67,173,133,129,75,28,26,185,31,197,243,188,66,30,174,68,137,18, + 103,11,158,53,5,151,245,54,4,117,2,212,141,42,186,174,211,107,11,132, + 232,166,33,202,10,225,72,166,205,118,199,176,43,77,172,202,22,6,163,62, + 3,49,131,23,183,49,42,67,102,235,26,43,221,46,70,85,35,114,221,220, + 42,238,186,30,113,60,164,86,171,161,105,250,19,146,219,147,58,254,172,150, + 108,218,80,82,80,70,25,178,176,99,166,146,166,213,210,42,200,14,211,29, + 91,0,234,90,27,233,44,43,226,74,115,115,189,229,73,179,199,160,235,78, + 40,185,12,185,67,179,248,184,128,209,252,49,196,104,28,234,204,21,103,212, + 101,84,80,69,67,63,97,232,39,152,198,136,172,43,214,56,244,55,86,201, + 69,183,98,230,144,84,131,79,213,125,213,189,68,79,95,63,76,47,40,50, + 98,84,203,103,214,157,140,148,198,78,74,207,87,159,97,221,110,80,49,52, + 58,110,72,196,164,129,169,162,153,101,219,174,18,37,206,66,60,123,4,87, + 24,251,162,105,58,66,56,4,65,68,167,231,231,174,57,128,208,140,48,173, + 33,234,164,86,201,151,55,107,228,33,202,122,170,218,66,47,161,81,175,17, + 246,187,52,106,35,44,71,96,219,54,150,101,17,134,230,15,52,237,122,181, + 122,27,191,110,186,158,172,168,222,50,147,136,114,65,238,39,92,218,135,140, + 15,40,165,52,234,231,170,46,9,98,146,32,38,246,218,196,94,155,238,64, + 45,207,136,171,8,231,254,125,234,152,142,23,66,147,98,102,98,29,67,30, + 194,237,6,120,225,9,106,53,117,60,69,178,91,58,145,150,52,164,251,3, + 20,161,201,14,50,25,19,152,24,245,145,254,10,73,16,211,233,248,19,251, + 232,15,198,223,75,86,115,167,58,145,200,244,187,148,19,196,150,125,222,197, + 91,113,121,182,110,246,91,80,51,238,148,18,108,84,52,164,182,158,226,119, + 174,144,145,155,139,93,49,201,66,149,221,110,151,209,72,73,208,96,106,232, + 173,159,148,67,80,75,148,56,27,241,172,17,156,110,84,39,122,26,198,113, + 140,149,53,212,21,227,176,88,53,207,171,121,216,149,38,96,227,249,26,189, + 33,232,21,141,48,86,249,155,36,177,25,164,230,57,179,117,62,85,125,152, + 231,161,50,67,68,54,138,39,240,79,60,233,227,28,159,152,229,106,231,100, + 22,154,44,24,74,164,191,146,134,25,213,190,163,197,132,209,65,79,25,70, + 100,39,39,186,238,96,81,133,8,83,37,53,83,171,176,116,98,28,138,5, + 96,164,147,244,36,250,210,244,4,130,14,216,39,112,228,188,58,198,72,253, + 237,118,143,83,21,49,110,55,64,70,143,83,171,173,80,171,173,48,242,219, + 172,159,245,243,28,96,22,10,205,201,84,118,20,137,202,78,78,120,178,178, + 172,142,100,229,120,190,61,0,205,29,55,187,14,226,65,174,226,194,208,36, + 142,147,188,99,72,146,36,19,3,71,139,147,198,165,116,201,44,251,186,94, + 195,48,231,38,10,190,85,233,64,49,16,169,136,86,104,217,239,194,6,252, + 84,189,141,213,170,109,39,216,142,67,20,164,195,91,197,164,146,45,231,195, + 149,40,113,118,225,89,35,56,85,7,55,14,105,201,164,67,16,68,233,115, + 235,210,14,38,147,10,194,243,179,43,113,159,102,13,146,96,136,169,91,12, + 7,3,53,26,71,171,115,231,119,108,58,203,38,129,126,33,205,214,22,124, + 105,96,219,22,150,165,211,238,29,39,73,98,12,115,238,73,29,163,10,161, + 74,164,116,215,46,11,152,88,121,42,52,105,159,152,48,137,40,116,214,84, + 104,25,225,52,156,69,50,114,147,178,3,213,120,82,181,101,168,198,12,251, + 131,180,100,96,140,117,77,31,67,30,154,88,230,118,3,220,110,144,119,69, + 153,36,55,181,175,192,13,198,199,231,132,32,59,104,158,65,195,86,239,215, + 105,169,253,100,106,48,112,199,68,97,26,170,193,51,168,118,107,89,216,81, + 211,180,124,74,186,166,105,196,241,112,124,75,63,199,36,73,82,131,137,50, + 156,4,65,140,235,170,110,41,150,101,32,146,37,40,54,93,158,64,133,233, + 223,135,239,251,68,81,132,208,60,194,56,98,228,150,163,115,74,148,56,155, + 241,44,186,40,213,73,50,8,162,52,52,165,80,223,48,233,123,217,190,73, + 162,145,41,155,116,196,74,197,164,55,84,195,48,29,71,82,169,84,136,194, + 16,127,160,113,104,255,94,62,243,169,175,243,23,127,182,200,77,183,40,5, + 17,134,33,81,184,66,179,86,71,211,116,58,163,201,58,169,181,144,29,211, + 116,183,146,98,205,219,116,113,118,166,222,144,243,72,198,68,227,220,191,111, + 146,236,236,19,180,156,17,189,229,152,206,208,167,51,156,60,81,159,10,134, + 214,133,145,34,145,97,212,198,48,30,0,198,42,14,84,184,50,236,60,70, + 216,121,140,245,173,227,172,111,29,207,195,146,99,116,166,254,78,61,59,244, + 115,117,25,118,30,155,120,46,137,199,164,27,70,213,92,197,5,65,76,28, + 199,19,125,31,139,173,189,116,189,166,26,108,203,22,113,156,112,195,151,6, + 188,243,223,222,200,199,62,246,61,78,44,121,216,182,133,227,140,27,58,79, + 135,40,171,85,109,106,108,206,12,78,101,59,0,115,27,46,165,217,220,140, + 235,119,177,57,245,247,91,134,41,75,148,56,59,240,44,22,122,11,164,116, + 177,44,27,48,232,246,117,110,248,154,199,241,3,38,73,162,72,228,69,151, + 238,224,249,23,175,231,158,251,111,37,43,19,176,43,227,67,214,43,26,189, + 65,72,189,106,19,38,35,182,109,223,205,79,254,236,85,220,251,64,194,175, + 252,226,151,113,156,19,92,253,166,29,92,253,214,43,249,137,127,53,131,174, + 155,120,94,192,92,189,146,135,29,139,185,182,162,115,82,17,218,26,189,27, + 11,245,110,211,118,123,96,149,66,115,252,239,3,26,82,118,16,98,6,69, + 40,53,144,29,90,78,214,161,100,35,193,104,113,188,137,108,27,110,31,237, + 72,7,152,67,95,138,233,157,123,140,22,235,65,116,168,234,224,38,32,101, + 139,100,120,4,173,182,149,36,154,71,51,206,153,216,127,150,71,107,216,107, + 132,38,1,152,33,90,244,200,2,193,195,254,128,90,163,78,179,166,211,89, + 246,209,210,143,123,185,19,99,23,60,31,129,43,177,28,129,12,98,132,165, + 99,154,227,190,151,89,1,120,118,95,253,85,198,158,229,149,128,135,247,250, + 252,217,71,111,229,174,123,78,112,112,225,81,182,159,123,158,250,76,211,139, + 138,36,81,249,88,165,224,198,88,63,215,2,118,179,180,188,23,53,225,123, + 6,215,159,225,246,61,251,209,141,29,236,218,41,216,182,99,29,131,40,162, + 65,137,18,37,206,118,60,235,243,224,64,112,239,222,17,31,252,181,35,252, + 214,175,126,149,67,7,103,209,180,26,154,86,227,5,23,175,231,178,151,206, + 82,84,25,158,175,231,206,57,128,102,221,68,211,60,42,134,70,183,211,230, + 193,187,31,230,69,47,212,120,201,203,94,65,187,109,115,205,117,247,243,254, + 247,126,152,223,248,141,135,241,188,0,93,23,105,14,78,41,200,48,12,11, + 83,171,147,147,54,19,62,101,47,73,24,171,55,10,4,229,212,224,251,227, + 143,88,202,14,195,72,237,119,24,181,115,82,107,47,77,146,98,210,43,228, + 138,218,107,171,13,183,176,216,106,141,213,89,18,205,79,168,185,137,99,76, + 214,170,17,91,173,224,134,253,193,42,119,102,85,168,199,131,174,59,46,67, + 0,66,93,169,106,111,106,216,128,174,235,57,185,101,61,38,239,190,111,192, + 13,95,11,248,179,143,222,202,109,119,84,56,116,120,11,130,93,106,125,91, + 76,52,118,30,69,171,243,101,182,51,147,146,156,131,34,184,45,216,214,118, + 62,255,197,199,248,195,63,248,20,215,127,238,86,58,109,255,148,179,0,75, + 148,40,113,246,224,25,35,184,98,216,49,142,135,4,254,137,130,1,33,38, + 10,151,89,94,9,249,79,191,190,196,207,255,204,1,62,251,217,227,172,180, + 183,19,202,5,116,209,162,233,180,249,185,183,173,231,238,187,218,216,166,1, + 120,88,246,34,170,7,225,102,181,97,217,195,143,85,119,121,211,220,66,156, + 12,248,200,71,19,174,253,212,136,119,255,98,139,138,149,32,233,112,124,121, + 129,189,223,221,207,145,165,33,113,44,9,163,106,90,58,160,88,34,8,84, + 88,45,203,31,77,35,55,148,140,14,168,78,37,195,3,170,158,44,233,144, + 184,243,169,237,95,133,38,65,41,53,67,235,170,48,229,5,41,19,125,191, + 15,213,24,180,67,224,14,169,25,171,11,207,45,103,68,220,109,163,53,5, + 163,52,60,40,122,235,209,89,66,103,137,154,177,5,128,81,243,56,78,250, + 205,9,161,214,51,140,7,112,228,60,45,39,205,111,165,68,215,172,28,165, + 89,57,186,202,165,41,101,71,149,28,160,66,168,135,55,171,227,169,54,86, + 168,53,234,180,236,35,19,199,54,146,58,94,120,2,223,158,99,20,215,24, + 166,23,25,73,168,200,164,216,200,58,251,92,149,26,86,23,20,15,62,18, + 176,231,214,144,206,98,76,179,33,168,27,1,200,127,70,178,71,189,198,147, + 36,178,69,34,91,68,225,114,193,69,57,14,223,138,100,137,231,93,180,17, + 167,114,57,146,115,145,216,184,193,16,129,205,226,114,157,107,62,59,228,67, + 255,233,78,110,251,230,110,130,40,33,242,218,36,241,0,207,243,144,129,234, + 115,25,133,203,107,126,199,37,74,148,120,238,225,25,35,184,44,36,21,199, + 67,132,176,177,42,27,38,122,14,126,249,107,21,126,241,125,15,243,153,235, + 190,203,252,193,180,227,136,104,161,139,22,26,77,54,108,218,193,158,91,61, + 30,217,123,3,94,24,1,30,129,167,242,49,78,26,166,76,66,61,31,149, + 98,88,49,81,24,242,232,247,15,240,141,91,230,1,216,181,243,28,108,75, + 39,11,111,70,174,59,81,15,165,218,55,201,194,227,201,241,55,176,134,114, + 43,204,104,147,73,143,196,142,148,99,50,109,171,37,101,103,172,224,70,250, + 132,130,203,114,103,153,146,11,77,117,17,80,171,42,147,71,224,86,209,154, + 147,196,167,179,68,204,250,137,101,77,44,168,198,56,122,234,138,20,227,154, + 182,96,180,152,147,28,144,231,248,138,203,214,82,109,219,143,73,70,177,90, + 62,236,15,232,122,91,129,113,110,47,83,112,69,20,205,38,211,117,102,153, + 97,8,200,27,52,127,241,11,135,184,251,174,54,175,124,211,149,180,54,108, + 161,98,133,76,207,248,51,205,144,161,159,224,15,92,60,119,242,56,165,182, + 158,115,207,219,202,11,158,231,162,177,25,141,25,4,106,78,28,216,72,58, + 220,181,247,49,126,247,183,254,43,31,251,147,3,12,163,231,147,72,135,106, + 195,192,79,66,86,218,58,97,84,165,108,186,92,162,196,217,129,103,140,224, + 146,100,108,25,207,66,84,0,43,3,159,107,62,249,24,191,255,123,15,115, + 253,13,75,44,47,207,172,126,45,61,54,239,152,225,171,95,186,151,239,238, + 61,12,180,81,87,242,217,137,76,169,135,48,14,16,169,21,60,10,116,42, + 149,89,92,207,224,190,189,11,124,249,115,183,176,180,210,197,11,14,3,105, + 43,171,81,147,145,171,227,121,30,65,60,96,56,236,167,125,21,67,130,32, + 64,211,130,147,54,81,158,152,211,70,218,9,196,95,25,147,155,59,204,157, + 143,84,83,50,168,198,104,53,69,124,218,145,181,149,67,70,114,161,57,36, + 52,135,184,137,10,63,86,53,137,232,9,162,166,34,57,64,145,165,222,165, + 71,160,204,38,128,44,144,91,182,173,34,201,181,156,81,126,95,133,68,215, + 54,149,0,84,6,18,119,160,99,134,171,11,225,59,125,69,68,21,111,5, + 55,74,112,12,13,203,17,121,43,176,12,217,236,53,171,96,6,17,194,102, + 225,80,194,119,190,251,48,119,223,249,24,157,197,152,238,137,163,120,193,50, + 224,209,91,74,123,107,198,170,251,127,224,74,134,193,8,219,153,33,51,153, + 72,105,243,248,209,101,118,236,52,185,240,71,119,0,231,32,153,65,48,254, + 253,8,102,208,152,193,11,98,62,121,221,183,248,165,119,253,53,119,221,221, + 32,112,37,154,25,225,232,1,142,227,16,4,241,211,62,215,174,68,137,18, + 167,31,158,49,130,11,130,8,93,215,243,177,56,182,109,145,36,9,255,112, + 189,207,31,253,223,251,121,224,129,58,166,190,21,93,180,136,101,55,255,27, + 198,71,56,103,87,76,191,125,148,131,135,230,213,107,77,131,98,189,83,86, + 46,80,177,117,42,149,10,189,193,88,61,180,170,14,80,225,27,183,135,12, + 7,109,212,9,221,37,9,231,169,87,123,104,98,72,224,183,115,245,145,133, + 175,100,16,79,228,128,78,229,150,140,189,54,196,243,42,44,57,69,110,134, + 214,85,228,163,143,137,71,11,142,231,185,180,102,67,157,84,197,20,49,69, + 125,129,61,236,224,104,228,202,204,144,109,140,130,127,37,35,203,38,22,61, + 253,4,186,222,131,153,99,72,209,69,136,46,85,189,139,30,60,78,104,14, + 9,70,139,56,114,158,96,180,168,136,45,85,149,195,72,170,99,21,234,113, + 55,77,203,233,75,227,146,132,208,28,146,12,199,33,202,229,222,216,201,232, + 133,227,26,194,192,149,36,161,145,247,167,204,84,92,16,100,29,106,198,161, + 202,250,76,130,235,25,44,156,240,184,238,127,220,65,207,95,64,93,184,120, + 204,110,72,232,123,110,126,241,177,10,210,67,211,106,44,45,141,184,251,174, + 54,175,123,237,143,243,162,139,213,108,60,187,178,1,153,147,156,135,196,67, + 96,35,241,184,123,239,18,255,229,119,190,197,183,191,83,197,27,244,177,170, + 62,163,110,118,172,165,147,178,68,137,231,58,158,49,130,203,106,163,50,132, + 97,200,53,159,29,240,177,63,122,152,125,251,183,231,203,51,114,3,72,146, + 33,27,54,132,108,58,55,228,240,227,7,113,125,85,44,45,52,53,11,78, + 57,40,39,235,161,66,105,208,172,171,208,103,63,208,8,34,129,148,54,209, + 72,133,250,156,202,88,97,12,70,205,252,4,154,229,102,78,137,120,178,235, + 127,94,10,80,89,78,139,162,231,199,228,38,58,185,170,2,208,91,17,134, + 214,101,224,15,17,189,245,12,170,46,102,111,126,98,243,69,146,51,26,18, + 191,62,25,158,44,154,29,51,213,154,161,137,133,168,197,42,92,9,56,26, + 136,126,23,87,31,82,213,187,185,34,204,110,195,168,77,104,170,231,38,182, + 115,98,65,189,213,245,58,98,115,130,83,87,228,148,133,77,1,180,164,131, + 85,87,170,206,54,213,164,109,55,74,38,20,92,54,92,21,198,141,152,139, + 93,77,6,29,13,199,170,34,93,147,71,246,245,89,94,57,72,49,60,25, + 185,46,129,191,140,231,121,68,81,156,231,248,38,81,225,238,59,31,99,93, + 3,94,253,227,47,69,224,225,250,125,4,149,116,24,170,106,198,45,57,128, + 99,213,144,120,220,115,255,173,92,251,87,159,228,232,137,205,44,47,119,137, + 131,3,68,174,71,28,203,60,247,90,162,68,137,231,38,158,49,130,27,119, + 165,80,187,184,241,43,46,31,251,163,135,121,224,1,101,10,137,101,151,184, + 208,15,49,150,93,94,116,105,147,171,174,186,144,185,170,150,170,175,99,192, + 81,92,95,229,224,60,127,0,248,56,149,117,0,248,94,76,18,76,23,83, + 167,208,170,184,126,63,125,45,244,71,80,49,230,213,24,21,47,198,141,18, + 252,120,136,231,121,12,131,81,238,6,52,162,149,137,241,50,192,234,46,37, + 195,148,20,186,237,177,114,171,165,138,64,87,234,173,221,157,84,8,245,145, + 131,236,64,52,212,112,147,177,74,179,135,29,236,97,135,100,184,250,132,222, + 29,6,171,150,161,247,208,173,33,61,198,207,53,103,86,114,69,198,161,35, + 233,231,223,157,32,80,96,146,220,228,12,184,234,2,66,95,138,209,151,98, + 228,177,181,127,14,179,51,14,97,111,172,232,42,158,34,125,111,208,207,149, + 176,202,109,41,4,65,140,148,110,193,157,58,84,10,46,253,60,69,197,73, + 115,163,10,237,19,106,191,195,244,162,100,56,18,200,48,59,22,31,132,77, + 146,12,145,210,230,145,239,63,202,158,91,14,242,218,43,109,94,116,241,139, + 243,109,8,42,152,86,29,145,146,166,154,0,127,20,56,160,92,150,31,190, + 137,163,39,54,51,138,107,132,186,155,135,166,227,88,18,134,225,84,237,94, + 169,238,74,148,120,46,224,25,44,19,16,128,58,121,252,227,13,61,62,250, + 199,7,38,200,13,148,169,100,174,101,208,106,14,185,244,98,157,183,92,189, + 153,203,94,58,203,161,131,1,158,127,2,21,94,60,134,186,210,87,97,39, + 0,215,87,249,157,138,163,194,84,126,148,32,52,245,156,101,72,132,240,48, + 171,2,65,5,149,183,155,97,215,46,114,103,93,207,13,137,70,9,50,212, + 72,252,1,81,20,227,13,250,121,127,197,252,29,100,13,138,211,46,32,137, + 29,21,100,85,7,237,248,0,209,47,144,70,129,64,156,245,125,208,187,212, + 43,74,249,24,61,69,88,70,45,201,29,144,64,174,218,244,122,106,124,16, + 147,57,178,81,218,110,204,29,136,137,146,129,89,107,181,242,208,219,171,203, + 0,50,82,155,38,187,108,63,195,232,232,170,215,100,136,70,74,149,181,59, + 133,240,112,56,217,230,204,114,198,170,179,216,213,68,8,123,194,172,51,219, + 52,0,63,39,57,5,117,17,228,59,49,196,138,224,61,207,29,223,119,59, + 20,21,187,154,48,49,203,141,55,192,190,125,49,207,191,244,34,156,202,184, + 226,45,12,6,169,146,219,82,32,208,89,4,30,127,119,253,205,252,95,191, + 247,215,28,61,177,153,19,199,99,60,207,195,243,188,85,179,237,96,82,121, + 150,40,81,226,204,197,51,246,159,172,250,13,194,222,7,125,62,249,137,253, + 220,246,79,234,100,25,79,117,177,7,184,248,133,22,239,120,207,5,92,122, + 249,12,119,223,213,230,145,71,238,69,145,154,75,49,140,37,68,159,105,215, + 29,64,205,80,39,235,170,209,131,100,4,248,132,131,73,101,119,240,224,120, + 24,38,64,24,71,196,161,82,119,89,207,66,205,61,70,127,224,209,31,120, + 147,243,211,178,253,231,221,246,11,78,201,147,192,241,109,228,80,71,36,43, + 99,147,8,74,193,21,73,172,50,80,161,201,202,64,82,25,172,118,247,85, + 235,234,4,238,212,37,26,29,244,101,192,73,79,250,122,170,250,226,113,239, + 78,177,160,222,99,102,62,113,19,69,110,211,219,206,20,103,182,254,196,251, + 156,38,195,83,32,83,112,50,136,9,163,106,94,236,61,61,86,104,225,80, + 2,210,195,177,116,76,63,72,21,150,66,197,213,233,246,83,181,23,70,132, + 113,84,8,31,23,154,111,203,46,136,22,251,230,7,220,177,231,27,108,216, + 88,103,243,220,38,36,126,218,144,27,52,54,35,152,193,11,14,35,153,5, + 102,144,216,8,142,242,133,47,222,207,159,255,201,205,24,142,147,183,240,202, + 72,14,178,154,200,164,12,91,150,40,241,28,193,15,77,112,170,9,113,60, + 81,239,166,150,171,233,206,113,52,98,121,37,228,35,127,188,200,23,191,164, + 8,164,152,111,211,69,139,115,118,197,236,216,118,130,159,254,89,201,79,255, + 172,122,253,35,123,111,192,245,251,72,142,49,118,252,249,64,5,228,134,244, + 177,114,69,250,110,27,41,29,130,68,89,218,221,32,59,137,87,64,171,166, + 235,169,198,188,141,42,68,81,68,132,131,244,134,234,22,247,209,162,54,145, + 23,83,213,135,56,250,40,191,21,213,155,76,122,16,207,167,165,0,233,49, + 137,14,250,232,4,122,187,141,161,117,209,157,113,8,47,92,191,140,20,62, + 218,74,66,63,76,93,128,244,16,11,33,162,39,48,154,105,65,184,232,226, + 53,122,57,201,121,141,113,152,210,104,182,105,44,90,227,215,50,158,31,231, + 153,93,68,5,122,177,141,209,24,130,181,128,81,75,232,14,3,26,166,143, + 232,119,105,152,93,28,61,53,173,104,76,150,31,136,14,61,253,4,200,25, + 170,209,57,0,244,55,47,228,79,47,186,163,220,145,185,22,50,21,231,70, + 9,118,250,93,132,186,139,105,140,208,68,23,211,12,73,18,53,193,33,83, + 67,245,153,4,132,141,27,140,48,170,50,117,63,118,40,214,185,13,71,75, + 132,113,68,16,37,133,137,0,21,16,182,82,111,194,70,74,27,41,143,240, + 192,67,85,78,44,14,152,89,103,34,240,8,2,3,242,60,92,7,216,146, + 134,43,59,8,218,233,115,109,110,252,202,30,254,225,239,32,24,118,89,94, + 241,73,100,13,25,196,12,220,149,212,73,171,161,105,193,15,52,121,162,68, + 137,18,167,39,126,104,130,203,78,92,66,216,249,21,111,28,15,145,210,67, + 211,52,12,115,29,215,126,218,229,107,95,86,246,248,140,216,50,5,119,206, + 174,152,205,59,102,120,245,143,191,148,43,94,115,62,13,219,97,207,45,7, + 217,251,136,151,231,81,158,252,177,168,245,27,213,201,249,97,166,85,79,239, + 77,118,149,247,210,14,101,161,151,48,8,117,180,168,157,55,18,30,249,237, + 85,228,150,141,184,201,144,21,72,3,68,254,58,244,185,241,99,189,21,97, + 7,2,28,117,114,172,143,148,139,84,208,204,239,103,168,106,138,144,179,48, + 101,246,56,199,73,186,152,100,152,8,83,166,161,200,140,80,227,88,17,98, + 86,48,158,119,62,73,213,99,19,43,15,175,198,235,245,156,232,70,253,57, + 54,58,227,124,26,0,107,116,64,169,120,43,172,171,140,149,47,140,71,232, + 100,78,212,162,209,104,208,201,126,106,211,77,147,211,195,74,191,67,233,141, + 137,181,104,16,154,110,172,188,180,210,101,208,239,33,181,245,204,205,169,223, + 150,100,60,157,66,153,77,236,212,129,59,198,241,229,5,174,251,228,239,115, + 108,57,98,118,118,142,36,238,208,29,245,113,44,21,238,246,188,32,119,254, + 150,40,81,226,204,198,83,82,112,64,58,200,114,117,7,144,123,247,142,248, + 135,47,29,96,185,115,60,95,150,145,220,92,203,96,219,214,132,203,94,92, + 225,157,239,174,242,162,75,170,252,211,29,1,183,221,188,176,106,184,233,106, + 216,171,150,36,137,90,214,31,133,169,114,131,32,18,132,65,214,20,88,157, + 176,146,184,143,244,134,121,51,94,211,158,124,251,249,96,207,2,185,37,65, + 156,207,77,195,29,42,114,27,233,24,181,4,153,158,180,227,174,1,182,143, + 110,141,79,206,66,166,38,155,66,221,153,70,39,207,147,141,18,193,40,17, + 84,69,139,196,29,144,184,107,76,13,88,3,178,151,164,4,42,17,21,144, + 194,71,175,169,247,211,12,12,154,35,69,4,70,179,173,182,175,73,16,29, + 21,178,20,29,70,201,234,14,42,250,82,204,200,152,87,199,45,186,196,3, + 181,142,95,40,114,215,146,201,144,172,23,158,152,24,172,90,28,163,3,227, + 209,52,74,9,141,167,30,56,214,218,221,98,64,133,144,67,195,193,140,212, + 118,179,92,235,90,164,184,188,28,112,232,160,50,218,212,107,21,156,74,3, + 203,90,221,100,217,13,179,109,120,57,217,221,179,247,48,127,241,103,143,209, + 247,92,150,150,150,48,12,157,225,176,207,96,208,71,19,221,180,1,120,92, + 230,226,74,148,56,195,241,148,20,156,166,233,133,33,150,170,142,76,8,135, + 19,75,30,31,249,227,69,238,249,238,97,132,88,151,215,184,129,34,183,217, + 89,155,31,121,137,198,107,175,180,185,228,5,21,30,219,119,140,235,63,119, + 43,15,127,255,176,218,22,199,24,171,174,233,78,251,171,213,221,90,10,206, + 50,100,65,193,77,162,231,247,209,162,14,241,96,5,131,99,104,145,186,213, + 180,62,53,22,198,166,146,32,86,106,174,208,222,138,145,62,145,67,211,71, + 99,211,133,168,128,72,10,173,165,228,164,242,17,61,77,57,35,227,22,85, + 77,82,213,36,35,217,69,84,99,68,117,156,147,210,211,220,154,182,70,81, + 182,104,106,120,150,68,122,1,82,76,125,54,153,121,39,37,209,172,230,174, + 72,106,211,42,81,11,212,5,72,81,93,102,134,23,71,215,24,244,134,180, + 154,1,179,51,14,157,238,17,154,28,160,201,1,0,106,181,149,124,78,28, + 64,75,239,228,245,131,154,232,230,74,78,230,228,168,136,42,242,106,83,83, + 1,210,139,19,198,121,210,40,208,167,20,220,20,201,9,85,248,45,146,37, + 180,104,35,158,31,16,6,181,52,223,102,23,186,156,120,168,11,28,27,47, + 52,114,146,251,228,117,95,228,31,63,247,45,76,107,142,36,30,208,29,46, + 99,24,102,58,233,96,220,82,174,68,137,18,103,46,158,182,75,84,41,61, + 116,163,74,16,68,121,104,210,237,109,152,32,55,128,217,89,155,203,127,172, + 198,143,92,234,240,138,151,91,232,186,206,87,190,188,200,158,91,192,15,52, + 160,91,8,81,254,96,161,202,40,138,82,147,201,52,92,250,163,108,139,6, + 51,250,73,78,92,217,216,155,164,135,144,221,113,247,125,210,217,105,213,88, + 213,187,213,18,164,167,20,151,236,104,200,97,218,130,107,138,112,100,91,145, + 26,64,212,4,45,136,104,250,67,208,187,121,30,110,154,112,50,114,59,21, + 28,109,237,48,31,237,169,16,167,222,197,168,37,249,62,70,137,64,215,123, + 19,251,48,158,96,119,51,115,243,106,211,29,151,157,173,241,251,107,114,32, + 159,53,39,163,199,113,244,17,145,171,200,173,216,222,172,56,244,20,192,11, + 103,48,171,130,48,152,84,91,142,53,38,97,15,3,195,138,11,10,206,103, + 250,66,199,177,170,12,7,189,124,157,172,44,37,83,113,153,227,118,50,76, + 233,165,109,223,0,92,254,232,15,111,97,48,106,114,236,196,248,55,211,31, + 36,4,241,32,109,227,86,230,224,74,148,56,147,241,148,67,148,69,8,225, + 240,224,35,1,159,190,230,251,172,116,163,60,36,153,161,213,28,82,171,187, + 92,246,210,89,46,189,108,51,73,220,97,207,29,143,112,203,205,112,124,197, + 162,98,37,169,122,59,21,86,135,40,51,140,162,230,84,136,114,117,200,202, + 38,162,19,235,8,218,84,234,65,222,99,209,144,135,242,246,91,89,189,91, + 113,180,140,148,170,144,219,168,37,121,190,75,164,99,125,140,176,173,114,110, + 78,146,147,156,20,147,228,156,17,73,63,51,142,12,199,161,186,76,205,21, + 81,124,126,45,120,214,120,125,33,39,9,79,22,115,119,122,151,81,34,104, + 152,93,85,47,7,136,218,36,233,232,44,97,244,148,26,205,10,189,133,232, + 230,83,10,6,189,33,36,237,188,129,115,18,205,211,176,71,24,242,16,134, + 60,68,141,5,70,126,155,145,223,38,114,87,232,15,188,188,158,48,87,111, + 241,1,192,199,54,59,140,214,112,41,142,13,66,99,140,21,220,218,132,110, + 105,202,97,58,136,212,111,71,8,59,53,155,76,125,86,97,68,22,166,206, + 96,155,17,199,151,23,248,200,159,127,141,90,197,34,26,37,12,123,17,73, + 220,193,140,157,137,26,185,18,37,74,156,153,120,202,10,174,104,54,9,130, + 136,107,63,53,226,240,130,200,149,91,44,187,36,201,48,15,77,238,220,101, + 113,222,121,58,59,182,25,60,126,172,206,13,127,23,241,232,195,139,184,254, + 10,158,127,226,135,82,111,73,98,35,19,27,145,116,115,5,167,66,148,167, + 30,155,18,12,134,116,250,222,170,41,216,57,177,165,211,1,38,74,2,10, + 181,110,178,91,232,163,233,62,185,143,178,97,42,2,20,181,56,15,29,142, + 146,246,68,24,49,35,32,209,211,86,117,48,153,70,70,110,122,103,188,158, + 236,104,227,18,2,20,129,198,113,83,149,45,212,226,156,60,139,117,115,157, + 205,105,222,107,48,38,214,168,175,142,73,208,166,213,156,44,58,239,14,22, + 73,162,121,90,77,159,78,199,87,161,93,84,30,179,170,29,165,63,240,242, + 217,121,70,180,66,187,173,114,171,238,26,229,23,48,169,224,50,76,42,184, + 73,146,27,249,38,161,25,177,220,73,63,43,77,93,76,101,10,206,178,214, + 167,77,152,243,173,49,190,56,242,240,194,1,96,115,211,231,175,229,161,239, + 43,23,174,231,143,63,143,233,242,129,18,37,74,156,121,120,90,66,148,113, + 28,35,165,199,131,143,4,220,118,211,93,244,123,91,38,194,146,213,138,58, + 65,108,219,154,240,234,43,119,177,99,167,198,194,227,17,223,250,198,99,220, + 118,243,2,7,15,205,35,57,150,218,187,87,55,95,86,56,249,212,107,77, + 243,16,154,167,114,112,5,5,247,131,98,28,146,132,192,85,39,244,188,129, + 178,88,157,15,211,232,140,157,142,78,225,175,147,224,197,130,164,163,194,146, + 146,94,78,84,211,37,102,163,164,77,85,155,85,249,184,108,158,220,80,167, + 95,115,85,113,119,118,108,129,82,95,178,167,246,227,104,21,132,157,170,65, + 225,211,166,137,232,66,194,12,3,127,210,226,111,52,219,24,205,246,152,56, + 107,171,73,102,230,216,88,225,100,53,116,70,99,172,170,134,189,195,171,94, + 211,92,167,19,139,69,234,173,5,58,29,31,183,171,62,179,97,48,86,144, + 89,184,114,118,118,152,215,179,153,254,26,29,90,158,16,171,191,127,51,92, + 125,1,147,149,11,132,65,148,247,165,92,141,108,217,49,22,219,53,174,253, + 171,79,50,240,183,35,227,62,73,60,224,200,82,26,126,14,226,220,44,83, + 146,92,137,18,103,30,158,114,153,128,186,31,160,235,53,174,253,212,136,7, + 31,186,20,221,216,59,177,110,181,186,158,217,89,155,173,59,27,156,119,158, + 82,8,247,62,144,112,203,205,176,112,116,136,31,104,185,114,147,171,148,219, + 248,202,93,61,231,229,203,140,106,218,87,178,232,162,204,20,156,150,157,228, + 109,192,161,81,112,190,207,234,170,240,90,36,93,214,215,85,9,64,18,205, + 35,227,3,105,99,226,121,204,133,71,136,187,237,113,3,229,102,59,207,187, + 101,110,73,217,2,209,26,19,159,144,118,174,228,28,173,130,152,159,12,187, + 37,169,162,204,212,86,195,236,210,48,199,138,41,187,47,106,49,205,189,21, + 106,133,50,128,196,50,208,122,138,252,165,240,212,205,11,112,43,30,158,37, + 105,220,167,142,67,163,67,115,228,171,130,112,200,91,122,201,161,142,28,234, + 244,58,106,89,143,96,50,148,9,244,172,136,70,115,37,15,151,102,5,223, + 173,185,46,173,185,46,134,241,64,126,3,8,151,137,92,6,100,0,0,32, + 0,73,68,65,84,246,33,70,125,122,203,49,245,214,2,179,149,135,169,177, + 64,77,235,35,163,199,233,245,151,114,21,167,190,191,77,233,247,38,201,186, + 211,100,200,134,148,218,68,232,134,50,11,77,154,76,38,33,68,151,48,237, + 131,41,147,1,50,233,34,165,151,118,175,81,106,110,60,105,96,134,233,16, + 37,216,216,149,17,208,225,246,59,230,89,56,176,143,8,135,126,47,162,86, + 149,68,81,136,159,132,107,118,58,41,81,162,196,153,129,167,144,131,155,84, + 1,119,223,55,224,27,183,204,147,208,99,228,155,171,214,175,213,93,54,108, + 80,196,176,112,40,97,239,157,7,89,56,112,132,225,160,141,148,94,238,126, + 123,98,140,215,137,70,89,191,203,213,46,74,117,18,205,48,54,153,156,12, + 89,91,42,203,25,91,218,179,238,250,232,93,136,91,99,5,84,136,150,61, + 81,211,143,100,141,48,105,100,170,154,171,162,146,202,140,31,162,22,79,244, + 153,204,143,37,85,130,19,112,18,108,93,98,235,171,79,192,153,210,83,27, + 31,111,155,153,128,217,150,182,102,171,175,53,143,127,141,30,153,160,6,172, + 186,222,8,236,19,180,102,15,170,125,86,150,233,116,124,72,58,212,52,213, + 245,37,246,87,84,94,174,189,214,254,212,247,182,220,219,165,12,66,192,32, + 82,78,202,40,152,206,65,174,206,195,77,43,56,187,98,77,173,113,170,48, + 119,7,207,215,0,143,227,203,11,220,252,245,219,25,141,68,218,69,197,37, + 138,212,119,83,12,85,150,40,81,226,204,194,83,14,81,102,3,77,239,125, + 32,97,126,223,18,177,236,162,105,42,223,146,153,76,178,220,219,142,93,106, + 138,192,193,3,251,249,238,125,71,56,116,100,63,94,26,174,122,242,197,221, + 39,95,175,231,141,101,90,54,77,224,100,16,137,98,166,172,207,226,186,117, + 217,51,147,161,200,124,66,64,154,123,211,173,33,210,79,141,37,83,40,26, + 75,100,58,255,78,91,195,232,210,15,167,76,30,133,124,89,143,128,38,214, + 42,117,53,222,199,236,234,247,34,237,85,14,202,88,57,249,115,34,19,169, + 107,115,214,10,193,61,121,184,119,26,122,93,34,68,119,130,232,170,122,151, + 154,33,212,36,2,119,8,238,16,49,92,64,140,250,212,91,11,202,172,19, + 169,188,230,48,72,84,169,197,154,176,129,10,235,154,138,32,51,146,203,20, + 220,19,33,156,154,69,167,92,184,147,219,159,188,104,114,152,52,41,217,249, + 227,219,191,245,40,71,30,159,220,94,113,218,68,28,75,60,47,72,219,121, + 149,229,3,37,74,156,9,120,74,4,151,57,41,151,87,66,110,185,113,137, + 206,208,42,60,55,36,150,93,230,90,6,181,186,203,185,187,213,21,249,190, + 125,49,247,221,121,144,165,199,5,43,43,147,39,235,213,225,201,181,112,106, + 149,23,176,246,201,167,81,93,115,177,58,214,116,106,245,68,222,237,9,48, + 161,144,82,100,197,221,249,227,222,234,143,87,244,52,90,253,73,242,205,186, + 142,0,249,248,155,85,199,104,25,104,189,16,86,86,19,235,169,246,151,247, + 173,132,92,201,21,173,251,73,51,117,137,166,234,48,11,195,58,122,39,159, + 120,0,138,232,170,186,154,80,224,38,32,31,93,224,112,95,207,63,43,41, + 231,65,118,212,164,133,120,158,88,44,18,118,30,163,198,2,195,32,65,227, + 96,190,173,209,40,251,236,60,178,220,90,18,247,243,48,229,106,84,152,204, + 193,169,247,52,173,224,42,214,248,59,145,83,191,19,185,138,216,188,194,95, + 143,135,30,62,198,254,253,135,112,61,159,222,96,196,176,223,207,215,46,85, + 92,137,18,103,38,158,66,14,78,71,211,52,194,208,100,225,241,136,59,191, + 61,204,149,155,122,126,124,127,231,46,117,210,54,180,131,116,122,67,238,189, + 207,100,185,19,231,211,184,229,41,12,36,171,177,54,9,102,46,74,139,181, + 237,245,39,11,81,206,206,56,42,60,89,44,230,78,97,84,150,39,148,155, + 110,13,85,49,119,202,25,167,10,79,198,195,201,147,175,22,68,107,170,57, + 81,139,87,41,56,189,21,193,202,36,201,174,245,90,24,147,106,241,88,68, + 79,131,182,204,221,146,225,236,248,228,92,12,175,34,187,104,189,153,137,208, + 231,180,1,69,138,46,82,116,213,4,4,49,57,144,117,103,127,145,164,39, + 11,173,203,58,224,132,138,232,70,125,154,149,163,19,14,203,12,213,106,246, + 179,27,147,142,166,55,136,162,136,250,154,28,55,253,251,88,251,247,50,173, + 224,100,65,161,173,70,246,156,234,87,233,133,3,110,223,179,63,47,56,207, + 66,149,107,205,12,212,180,83,151,112,148,40,81,226,244,192,83,110,182,12, + 176,231,214,144,199,14,28,76,151,79,58,248,102,103,213,9,166,49,171,212, + 218,254,71,3,58,203,33,195,193,100,110,39,203,193,137,124,138,192,15,134, + 105,23,101,254,183,0,131,21,180,168,195,40,53,62,104,73,135,112,241,161, + 60,60,105,57,39,97,65,189,55,73,12,167,58,14,187,144,195,11,34,240, + 214,200,143,117,152,108,235,245,255,179,247,110,207,146,92,217,121,223,111,239, + 157,89,149,117,175,234,211,23,12,128,190,97,48,67,14,7,224,96,192,139, + 37,114,56,131,1,41,146,18,37,146,34,37,145,182,72,75,150,34,164,7, + 133,45,133,173,80,136,150,173,8,69,248,65,225,63,64,17,126,112,132,109, + 234,193,47,126,16,29,182,44,91,182,69,137,20,21,18,57,154,17,73,145, + 67,2,211,221,64,19,232,70,159,238,186,87,101,85,230,222,219,15,59,119, + 94,170,242,244,13,3,78,195,145,95,196,137,115,78,157,172,188,84,213,217, + 95,174,181,190,245,173,158,206,191,134,42,70,175,106,206,35,182,152,36,19, + 161,148,34,69,43,98,216,138,163,232,77,204,65,190,85,242,200,236,29,16, + 100,167,48,129,246,24,238,142,13,150,243,30,61,175,34,245,142,43,191,47, + 143,212,154,214,206,88,47,87,46,18,142,238,49,91,239,232,143,222,117,102, + 213,184,113,55,182,18,229,22,53,56,163,93,196,180,170,229,241,199,123,241, + 203,17,220,33,220,148,111,39,56,114,40,55,128,59,194,252,213,95,187,201, + 226,126,39,175,255,233,164,56,153,50,209,53,138,202,6,13,62,30,248,80, + 41,74,107,99,150,43,195,63,250,71,43,172,141,142,200,109,216,153,210,239, + 190,75,127,48,100,57,107,113,227,134,226,157,247,126,159,229,126,143,53,115, + 204,153,181,153,135,161,254,142,220,154,168,162,162,172,115,52,73,57,7,64, + 175,148,33,92,181,174,1,69,122,18,225,166,115,203,247,10,114,8,186,202, + 53,112,71,190,137,187,62,130,240,117,55,32,87,49,30,194,79,5,208,251, + 94,161,198,44,53,117,43,85,239,237,73,84,156,180,175,245,121,162,75,55, + 58,143,240,60,209,137,133,196,204,128,237,206,121,87,250,231,238,220,245,60, + 10,222,241,164,226,122,210,51,168,253,31,84,30,83,98,225,84,166,253,7, + 4,253,7,116,7,15,72,91,239,177,94,174,24,77,110,177,184,175,49,53, + 189,111,237,146,200,37,20,55,105,181,39,4,65,144,19,93,208,42,63,167, + 254,245,126,88,13,78,224,9,188,78,188,228,173,187,202,254,159,51,230,139, + 247,249,23,255,252,27,236,118,83,182,241,174,36,56,241,102,226,141,162,178, + 65,131,143,19,62,20,193,233,116,195,191,252,181,61,191,241,175,126,11,41, + 123,8,17,87,82,147,97,87,208,187,244,92,174,158,188,119,175,199,250,84, + 179,94,77,243,197,168,154,158,140,142,106,39,143,139,60,130,243,144,221,90, + 87,139,50,38,227,14,253,253,77,230,219,250,2,157,40,181,228,121,231,144, + 220,169,228,236,82,216,67,97,239,187,72,72,181,214,232,204,88,58,79,11, + 170,69,94,31,59,74,127,198,22,113,48,37,220,69,111,18,117,31,214,251, + 226,218,237,208,32,247,41,203,15,90,149,122,155,143,226,236,89,86,95,25, + 242,233,228,56,65,140,39,58,95,159,91,246,182,200,253,93,6,225,142,192, + 78,243,41,230,62,157,107,75,211,196,71,89,84,172,63,248,61,119,93,34, + 102,179,49,236,246,33,229,155,149,125,214,100,45,149,115,39,121,180,138,178, + 157,215,224,182,250,236,235,57,91,188,52,161,154,238,222,17,39,41,191,252, + 127,191,115,180,101,89,81,9,52,36,215,160,193,199,4,79,77,112,90,107, + 90,237,11,188,253,182,38,73,175,98,204,154,64,190,116,20,197,157,243,245, + 22,123,151,119,238,206,242,190,55,99,231,8,218,249,157,182,32,206,26,189, + 225,184,103,169,30,65,230,94,97,76,228,102,189,165,41,123,227,72,99,159, + 138,204,213,226,78,190,63,181,153,103,179,193,92,122,210,43,40,59,246,38, + 219,120,227,250,222,58,3,194,121,86,143,203,78,199,138,29,209,34,2,49, + 116,206,33,29,131,169,211,161,116,10,98,208,239,142,28,233,68,2,185,79, + 243,118,1,57,48,216,7,83,226,97,156,139,62,242,182,0,61,68,41,69, + 60,140,143,82,142,62,61,121,136,184,101,49,183,12,221,15,18,228,34,193, + 14,13,234,212,96,90,1,163,59,9,124,117,148,55,159,123,215,147,56,156, + 187,153,114,55,109,101,206,156,175,219,37,151,190,145,171,46,187,210,165,150, + 151,189,45,235,151,238,230,61,122,0,86,158,195,156,147,174,62,57,114,228, + 185,9,223,162,43,70,110,192,234,118,205,58,185,225,102,233,65,158,158,236, + 118,37,150,56,235,115,43,222,67,112,253,112,58,77,16,50,46,57,153,248, + 231,182,107,135,177,118,212,14,33,71,7,34,147,236,70,36,171,181,137,163, + 72,206,207,136,3,71,158,109,224,14,219,248,223,240,214,239,63,199,62,139, + 226,128,163,40,78,41,209,40,41,27,52,248,24,224,169,9,78,41,69,28, + 239,249,202,175,79,115,215,18,223,34,224,73,110,60,112,109,1,247,238,245, + 92,244,118,247,78,73,65,87,64,60,86,141,165,188,77,177,80,181,148,200, + 251,224,202,104,5,143,113,151,157,57,135,180,58,45,70,94,208,185,117,41, + 50,179,190,80,217,52,143,132,58,246,72,45,89,134,21,113,254,247,206,174, + 88,4,43,34,145,169,165,179,203,246,161,22,12,85,245,252,203,41,197,67, + 113,137,153,65,172,139,191,71,202,30,145,173,105,5,103,138,90,252,115,34, + 101,89,116,51,162,26,102,211,189,51,238,8,167,33,11,29,33,122,58,55, + 133,30,170,24,115,215,145,161,200,94,183,213,110,141,232,233,252,181,241,41, + 87,177,156,23,61,132,144,13,138,45,176,217,24,162,150,170,16,152,148,113, + 222,38,144,63,173,83,132,208,34,111,193,168,255,172,88,51,175,105,19,56, + 142,224,142,51,4,254,119,71,102,167,167,107,126,235,55,127,51,143,36,125, + 212,230,163,56,239,110,210,24,49,55,104,240,236,227,67,165,40,255,253,215, + 247,252,159,255,228,55,142,162,54,143,94,223,69,72,171,229,130,213,114,193, + 131,249,31,96,205,241,29,248,147,169,40,201,28,40,64,136,45,73,86,107, + 83,242,120,52,78,49,229,249,108,2,85,231,58,32,198,172,83,91,153,122, + 237,199,200,148,33,204,46,27,83,243,232,118,134,188,143,173,44,50,137,109, + 229,247,160,171,242,168,77,141,210,156,32,244,58,168,23,168,100,68,86,110, + 236,174,235,129,203,137,45,182,216,7,211,156,112,173,216,21,98,153,173,100, + 184,217,185,105,225,165,104,49,72,166,40,165,42,164,43,122,154,133,142,232, + 156,207,200,127,6,106,177,200,125,53,85,47,205,123,235,134,180,176,119,178, + 244,179,157,33,196,156,245,114,133,237,221,203,211,215,221,174,36,222,107,200, + 157,105,10,120,146,139,72,17,230,244,232,117,45,215,227,194,110,201,202,236, + 32,130,243,120,178,148,247,142,15,166,75,110,190,245,14,105,146,144,166,105, + 30,197,173,75,125,149,205,56,157,6,13,62,30,248,80,4,247,238,59,134, + 7,15,92,212,230,35,55,99,92,187,64,103,88,189,107,127,247,198,123,172, + 214,187,218,187,236,71,163,218,7,21,239,92,205,44,209,123,250,118,134,49, + 17,66,198,185,64,193,163,60,0,115,210,121,43,255,89,154,25,152,41,189, + 96,134,126,176,101,191,249,160,54,245,5,46,42,137,91,246,88,133,152,161, + 182,247,12,224,193,236,168,102,6,46,213,88,62,84,30,245,152,157,139,132, + 58,109,228,13,115,68,110,117,251,2,96,43,144,239,202,195,254,244,252,88, + 21,242,235,24,232,100,54,92,182,157,71,112,101,212,245,247,249,40,179,179, + 139,156,32,166,180,79,159,154,244,237,19,106,148,178,78,223,103,115,227,29, + 204,162,122,13,81,232,78,178,136,226,51,226,53,153,2,55,123,255,210,52, + 37,38,192,202,243,217,73,149,213,151,197,57,39,155,98,255,135,17,220,113, + 86,224,113,137,46,230,198,173,27,196,113,177,175,56,142,81,114,147,219,119, + 53,227,116,26,52,248,120,224,137,217,166,60,38,231,237,183,53,214,102,211, + 178,15,162,184,110,88,136,30,66,113,147,237,46,64,136,75,103,238,247,225, + 119,218,199,110,242,0,237,200,213,165,124,122,203,167,149,172,141,142,20,118, + 169,120,153,192,222,207,29,76,84,86,139,235,79,238,210,234,108,92,159,151, + 63,151,153,27,111,227,83,113,117,86,88,143,194,163,44,188,108,198,215,229, + 246,131,213,249,172,209,188,36,96,169,179,250,42,35,93,246,16,223,40,174, + 85,157,22,239,143,152,27,196,28,236,236,216,213,37,93,246,242,233,223,249, + 246,11,233,102,216,181,201,163,202,67,200,7,230,248,218,58,134,109,187,136, + 196,134,251,128,126,187,135,28,205,233,244,117,126,243,224,45,220,186,93,249, + 80,91,182,163,94,56,81,77,35,214,161,46,130,43,43,41,203,40,126,63, + 60,7,183,253,46,62,229,131,119,223,71,201,126,30,81,234,36,205,211,148, + 30,141,216,164,65,131,103,27,79,21,193,25,99,216,239,83,190,242,235,83, + 16,163,156,220,252,212,0,127,167,238,241,141,111,180,216,173,182,249,157,187, + 181,79,54,200,212,225,120,113,219,197,154,85,38,117,44,75,204,133,136,9, + 147,160,164,162,220,49,223,220,32,176,75,164,153,49,234,223,37,10,4,210, + 206,10,113,9,28,77,12,168,21,146,120,28,14,23,45,193,138,216,17,141, + 127,254,97,52,150,69,125,219,118,156,19,67,186,41,185,139,220,40,182,63, + 170,165,77,125,4,150,53,120,127,109,150,31,231,72,136,50,3,117,91,195, + 7,199,169,52,53,91,16,191,87,108,127,84,175,139,118,8,179,203,35,204, + 60,130,205,156,84,206,170,239,233,121,224,198,245,76,13,98,33,8,228,60, + 159,78,224,81,103,163,22,240,128,128,7,24,189,100,177,203,222,199,82,138, + 210,213,224,234,83,205,162,38,61,157,255,173,244,156,170,208,164,142,96,221, + 96,213,27,239,156,242,149,223,204,6,213,38,9,251,212,160,194,128,245,70, + 84,196,38,13,26,52,120,182,241,196,4,39,165,68,74,201,114,101,248,202, + 191,121,43,79,29,73,217,99,187,215,149,54,1,128,119,110,185,168,100,185, + 47,122,196,234,106,110,143,239,69,233,208,27,185,5,166,159,73,29,15,5, + 10,135,227,114,78,58,217,34,111,166,152,245,123,72,59,163,215,221,19,14, + 103,200,209,156,141,157,231,242,120,97,166,143,156,195,6,142,168,228,62,173, + 77,235,153,165,123,105,77,162,42,61,108,98,238,36,252,90,107,39,246,200, + 4,37,158,64,132,217,85,35,164,114,221,174,46,13,121,195,86,31,247,219, + 103,207,177,167,34,63,191,178,56,165,238,156,115,210,234,216,98,160,106,167, + 74,42,135,164,47,140,123,47,203,83,198,125,3,184,29,218,202,252,60,119, + 3,180,59,48,194,118,207,95,152,34,226,247,19,215,243,20,229,35,224,167, + 9,60,42,253,125,182,21,92,117,110,220,118,183,98,122,199,165,77,165,140, + 209,105,82,105,250,246,208,58,105,154,190,27,52,120,134,241,212,53,184,101, + 188,229,235,111,45,243,250,155,67,38,171,78,10,245,155,183,233,2,216,110, + 179,69,252,49,157,41,170,168,113,147,87,245,190,141,103,33,22,119,80,76, + 105,141,166,244,186,123,146,208,45,196,27,35,24,14,14,44,170,50,101,97, + 161,158,44,234,87,240,232,20,100,245,192,238,121,181,82,255,78,125,29,167, + 188,173,73,84,45,185,249,243,48,51,117,20,197,229,207,153,29,247,236,9, + 27,161,111,56,149,231,97,36,54,219,246,96,43,42,74,206,186,250,227,122, + 31,214,190,6,229,193,171,98,225,247,225,102,194,249,97,167,117,17,220,80, + 30,19,69,57,130,179,53,202,213,58,145,137,16,103,167,62,31,111,90,133, + 75,185,207,87,130,221,202,253,123,68,20,215,159,166,154,120,229,34,76,165, + 30,207,20,186,65,131,6,223,26,60,53,193,253,230,191,85,116,162,20,99, + 214,88,123,31,99,214,8,241,60,198,172,25,118,138,21,245,157,91,206,154, + 43,221,8,132,216,102,163,113,158,76,53,233,80,125,206,115,225,109,18,93, + 68,133,67,102,180,121,59,175,243,136,78,146,137,76,10,21,229,152,219,140, + 207,221,36,76,122,110,212,139,124,7,43,230,116,197,136,197,82,161,206,221, + 167,109,110,97,102,89,26,81,140,114,87,145,88,11,167,158,236,152,202,244, + 110,179,148,232,175,20,173,3,194,70,232,211,22,226,150,151,222,23,106,74, + 57,200,82,180,183,65,222,48,249,252,184,249,196,169,77,71,184,218,152,186, + 173,145,225,113,90,81,172,108,78,42,190,29,65,221,174,110,231,159,151,31, + 55,35,190,88,11,34,101,217,102,17,151,250,119,163,124,219,178,234,114,244, + 245,85,158,46,157,117,183,16,205,156,175,102,199,144,110,180,235,157,91,72, + 58,59,141,88,72,210,101,47,63,159,109,59,198,46,12,227,59,29,194,211, + 7,200,201,220,245,248,141,247,244,131,111,56,146,178,49,73,187,149,57,153, + 68,192,136,81,223,210,94,57,191,202,128,7,204,180,162,155,158,86,34,56, + 151,162,220,81,174,199,150,69,38,30,103,165,191,203,117,184,42,209,29,139, + 87,96,198,173,91,16,116,23,236,82,67,76,192,126,61,71,201,13,235,141, + 32,234,15,176,103,76,38,111,208,160,193,179,131,167,38,184,251,203,71,111, + 3,238,46,124,185,223,87,92,254,203,234,70,143,135,139,76,124,51,120,177, + 205,98,221,97,183,121,62,255,125,185,92,209,85,163,188,14,88,69,117,223, + 73,184,38,28,206,16,118,228,34,55,49,99,56,126,0,219,157,155,213,150, + 213,185,236,172,120,121,14,133,38,71,234,201,173,139,38,172,136,143,108,186, + 242,104,172,84,139,203,163,170,131,8,78,205,22,152,68,157,217,216,93,134, + 141,247,46,5,249,129,55,92,54,71,207,21,43,215,39,231,207,63,82,54, + 243,174,188,95,123,140,178,72,37,127,172,151,58,50,61,195,126,204,35,82, + 22,59,205,220,90,178,107,45,79,71,16,34,166,211,57,91,52,51,80,238, + 216,65,22,241,213,227,236,232,255,97,41,202,71,167,192,253,13,148,187,217, + 48,220,96,187,183,236,98,157,171,58,61,54,203,52,31,134,218,160,65,131, + 103,23,79,77,112,179,15,116,158,114,44,67,136,184,82,255,42,55,243,122, + 36,117,174,250,15,93,128,220,93,123,185,134,50,236,109,233,245,51,1,196, + 102,142,232,234,220,68,249,24,49,210,190,71,24,57,69,95,87,101,14,249, + 153,43,190,82,11,212,40,173,216,100,201,125,138,48,15,72,167,195,163,189, + 149,39,5,248,72,41,221,232,74,141,11,168,164,21,43,196,51,171,10,73, + 218,90,228,68,103,110,25,87,167,43,69,112,98,158,9,86,14,95,162,119, + 2,210,184,3,173,26,115,234,92,224,66,78,216,254,213,49,191,157,96,223, + 18,110,191,37,210,53,137,130,216,58,34,235,152,204,99,164,48,144,54,183, + 170,10,77,185,72,144,239,84,39,154,155,89,65,180,30,229,225,170,219,216, + 189,118,187,220,90,172,184,168,242,251,103,130,49,241,118,86,147,154,60,59, + 250,63,84,81,62,93,166,160,56,134,222,85,247,87,55,89,160,81,82,54, + 104,240,236,226,169,9,238,221,91,183,65,68,37,135,137,227,86,1,143,67, + 247,146,39,247,155,60,156,7,230,144,102,146,255,225,32,193,110,142,163,145, + 58,47,202,193,240,129,83,75,142,239,16,206,103,232,247,149,243,130,180,11, + 146,73,226,100,240,11,233,82,138,239,202,218,193,166,80,168,27,237,72,214, + 215,227,102,7,223,15,32,230,228,81,159,143,174,132,141,114,226,243,132,248, + 176,72,46,253,154,129,155,217,254,86,229,250,160,35,68,177,178,16,187,99, + 229,238,43,91,151,82,245,245,57,79,106,30,246,84,84,136,204,147,182,157, + 9,230,191,215,66,157,58,98,243,231,104,167,110,159,46,221,42,16,55,45, + 105,220,65,204,141,107,26,207,70,12,65,81,71,179,219,176,98,182,12,174, + 62,58,40,141,42,146,233,140,168,51,174,124,190,158,20,143,223,11,231,143, + 81,220,40,188,247,94,113,179,226,155,190,207,66,211,240,221,160,193,179,137, + 167,38,184,123,247,122,212,167,139,74,13,217,219,25,187,213,214,121,15,154, + 121,222,51,87,135,167,233,131,243,34,147,205,98,193,112,144,16,172,86,149, + 191,31,166,66,247,221,223,5,53,207,237,167,120,48,69,190,253,13,208,163, + 163,84,161,73,20,220,55,216,133,57,178,230,82,247,201,73,65,204,157,247, + 163,186,95,16,149,93,24,87,47,91,21,219,84,144,201,247,109,77,128,33, + 230,238,239,135,53,56,79,86,21,76,45,50,222,19,4,103,44,176,217,246, + 62,157,58,2,16,67,118,191,163,42,132,232,182,181,57,49,150,149,146,145, + 178,216,93,132,121,187,207,228,157,106,164,40,230,6,115,195,230,17,158,125, + 87,163,78,13,65,92,218,238,64,133,57,138,14,35,158,226,69,48,114,156, + 167,41,103,90,157,225,100,82,143,199,81,81,62,30,50,15,75,115,19,128, + 160,27,19,100,61,157,251,212,128,46,68,52,190,14,215,52,124,55,104,240, + 108,226,169,87,132,127,255,91,199,139,79,249,110,219,11,0,150,251,125,62, + 61,192,15,56,253,112,40,57,89,120,145,73,207,178,209,115,58,189,52,83, + 234,61,98,64,166,90,208,57,191,196,204,96,247,47,37,250,125,5,91,73, + 164,44,162,36,57,20,115,83,59,53,192,46,140,139,116,178,86,0,123,59, + 75,45,250,8,101,74,157,11,85,145,106,196,69,74,121,127,154,23,173,108, + 5,226,134,251,49,159,253,86,122,14,113,181,246,23,188,109,176,179,18,97, + 148,162,198,114,244,198,125,67,122,63,91,132,111,109,232,254,235,228,232,220, + 76,162,92,228,117,219,58,33,201,1,169,155,111,76,171,173,15,89,4,40, + 230,96,119,17,91,179,115,175,203,237,234,185,8,179,171,52,129,239,77,15, + 228,162,148,162,4,97,221,69,75,51,99,179,88,228,36,87,223,38,112,86, + 47,220,168,246,241,42,30,63,26,92,172,220,113,210,77,68,154,36,197,180, + 113,53,100,167,235,51,21,13,26,52,120,182,240,212,4,119,251,93,159,194, + 57,32,143,76,197,22,118,5,187,149,35,180,199,89,124,30,191,15,174,122, + 188,192,22,202,135,237,58,160,211,114,196,16,238,246,181,181,62,112,46,29, + 29,217,198,206,39,180,222,9,144,191,254,118,30,193,217,41,108,87,162,18, + 205,28,122,79,86,72,207,167,250,102,217,60,184,173,155,195,150,174,148,31, + 22,93,143,154,199,211,141,206,213,151,71,200,78,193,183,47,176,149,152,165, + 36,56,112,215,240,209,162,78,131,236,187,68,220,50,185,64,36,253,154,65, + 188,85,244,213,249,237,197,220,16,220,217,22,209,101,105,182,157,94,109,8, + 126,93,187,136,109,41,43,10,77,117,91,195,118,199,46,19,152,112,179,184, + 54,223,107,231,91,14,252,13,80,221,212,245,243,81,17,25,249,90,220,163, + 188,40,15,241,176,129,167,14,103,25,45,31,103,15,132,172,190,65,105,154, + 18,166,219,210,239,213,134,239,38,77,217,160,193,179,135,167,38,184,116,127, + 239,161,127,223,36,9,171,52,75,93,213,24,44,63,57,30,34,24,88,11, + 122,2,58,165,126,173,178,106,19,64,188,85,77,95,122,210,10,238,108,93, + 202,110,83,147,62,157,225,4,26,219,250,151,73,204,13,248,150,191,178,179, + 201,212,194,254,236,116,172,88,185,26,152,39,0,159,226,91,232,40,39,204, + 124,255,30,7,233,70,255,247,124,246,106,153,131,103,212,71,118,128,184,105, + 49,107,121,102,48,35,230,46,186,244,66,154,88,11,212,125,23,165,166,113, + 7,125,183,136,160,210,184,227,182,45,205,156,19,43,87,131,243,176,98,87, + 204,210,123,200,20,134,211,56,19,243,244,44,26,55,218,161,78,160,244,225, + 80,190,232,78,205,227,117,47,38,132,241,93,210,36,169,40,41,1,118,166, + 168,35,74,249,104,213,107,131,6,13,254,112,241,212,4,87,40,37,219,88, + 27,21,125,74,98,196,118,191,201,189,40,133,236,231,17,156,239,81,170,107, + 244,126,124,225,137,123,110,95,185,197,40,21,39,4,118,201,110,185,194,196, + 211,236,56,35,68,187,67,216,10,128,152,78,251,4,0,245,117,80,195,7, + 206,24,216,70,136,209,20,198,208,253,189,132,228,23,247,16,143,17,147,226, + 72,102,166,8,222,206,72,168,180,56,27,79,66,37,226,144,239,202,124,238, + 154,250,101,67,152,172,32,46,154,176,43,125,105,177,35,2,157,165,35,183, + 102,135,176,17,253,95,106,87,234,118,118,36,43,199,49,107,153,247,172,153, + 223,62,129,155,96,219,110,127,233,170,218,26,16,174,53,105,170,242,235,152, + 50,68,159,182,144,255,204,32,123,166,178,134,219,83,225,206,241,212,98,71, + 192,205,98,34,121,71,182,177,191,56,32,253,221,14,65,180,37,136,183,21, + 2,243,219,142,109,132,253,170,69,167,1,225,106,67,122,167,227,124,45,163, + 22,59,101,25,252,107,137,16,177,75,33,203,110,38,50,57,176,223,50,83, + 88,11,20,211,188,85,160,74,138,126,110,91,253,205,78,185,6,87,86,80, + 10,218,249,92,184,2,15,79,151,111,119,105,46,98,218,41,215,142,162,130, + 179,27,187,155,8,174,65,131,103,15,223,132,170,252,174,118,86,215,38,179, + 48,178,102,85,243,156,15,119,188,50,2,123,159,84,12,42,209,219,67,149, + 119,101,99,224,169,173,212,146,184,181,57,170,185,153,165,68,175,3,172,136, + 115,69,161,184,121,16,29,205,112,202,194,173,68,159,182,42,196,167,130,179, + 213,119,76,93,173,43,82,22,43,98,228,244,33,253,95,165,75,138,181,192, + 206,92,4,37,118,20,81,156,63,159,154,203,31,47,102,174,185,252,182,61, + 222,126,86,125,94,26,119,242,232,50,189,111,224,27,15,8,87,155,252,186, + 188,136,68,102,105,76,115,203,96,227,125,165,233,60,76,55,121,218,182,173, + 143,211,217,187,253,32,251,233,49,110,108,206,104,222,46,59,153,60,29,30, + 199,186,171,65,131,6,31,87,124,72,130,123,120,159,209,38,73,106,141,112, + 191,25,94,148,101,4,182,218,117,110,109,132,221,21,119,232,219,93,65,50, + 250,180,197,246,116,112,84,87,139,223,83,164,95,115,170,192,238,7,137,171, + 171,69,45,196,215,92,253,42,214,130,157,178,240,245,86,46,4,41,19,153, + 79,235,169,251,238,113,157,102,47,237,65,234,176,56,224,129,221,215,86,58, + 130,40,109,95,17,152,228,207,115,195,74,237,219,25,233,144,69,113,165,253, + 167,43,85,28,31,80,171,20,59,5,253,21,75,122,170,72,194,190,35,198, + 211,82,107,193,169,205,133,49,225,233,38,143,46,237,255,99,16,191,149,9, + 86,110,151,124,47,103,110,191,226,52,27,184,250,78,224,34,193,252,248,65, + 158,182,13,167,33,167,171,83,114,7,146,48,45,189,48,245,239,187,23,154, + 184,147,171,55,70,62,116,50,121,116,13,238,97,216,82,220,160,61,228,179, + 168,23,216,228,248,223,166,73,81,54,104,240,236,225,169,9,110,187,223,148, + 126,219,213,254,220,13,195,218,8,238,201,188,40,31,78,162,169,112,233,199, + 109,86,51,106,201,181,139,224,76,185,65,219,45,88,47,222,113,11,162,31, + 220,153,239,35,238,208,253,32,113,234,193,185,251,157,153,139,80,204,76,229, + 125,97,35,50,181,228,215,106,136,103,230,236,183,236,194,184,180,228,193,223, + 142,206,123,165,80,183,53,233,7,238,6,64,175,29,65,164,43,149,215,232, + 124,42,80,172,170,81,151,176,145,75,157,102,68,42,118,192,190,147,63,175, + 14,250,214,132,221,239,40,228,188,102,136,234,97,212,151,53,135,139,77,7, + 249,239,4,220,201,246,145,6,21,223,203,52,117,66,26,113,211,186,215,232, + 102,177,11,149,166,200,119,37,194,182,81,247,65,125,61,147,223,219,136,112, + 183,167,22,178,200,15,47,117,121,126,81,29,225,60,141,159,233,163,176,163, + 142,220,218,250,189,188,85,32,209,238,102,41,56,72,87,54,166,203,13,26, + 60,123,120,106,130,235,142,194,131,133,199,251,4,58,216,221,54,79,83,62, + 14,206,174,193,157,189,144,37,251,93,174,162,244,41,202,189,113,222,136,162, + 147,148,38,122,195,60,92,162,78,53,234,126,213,249,62,239,7,155,57,155, + 170,67,111,71,59,179,152,27,182,232,113,251,170,205,9,172,210,75,54,3, + 125,195,41,44,213,42,69,5,222,131,178,248,251,225,115,236,91,34,55,39, + 246,145,31,20,10,200,28,113,17,17,218,83,129,157,9,215,154,176,150,71, + 219,1,4,169,46,142,159,61,174,190,242,128,238,239,37,71,219,167,113,199, + 93,79,76,158,238,52,107,215,188,110,223,213,136,111,164,152,181,68,151,134, + 180,165,113,70,166,251,142,123,222,13,208,95,29,229,215,230,251,242,182,43, + 23,209,249,27,4,95,79,219,163,143,26,189,221,134,46,63,220,123,138,204, + 227,211,247,193,213,71,107,157,118,113,189,190,6,87,134,87,81,54,104,208, + 224,217,197,211,19,92,248,104,39,117,187,171,159,1,247,244,22,74,224,9, + 207,246,234,85,156,45,89,244,40,149,35,197,81,50,224,173,223,49,149,49, + 49,98,14,196,46,82,75,163,14,102,41,177,167,130,32,222,34,86,22,149, + 166,4,169,118,2,18,92,122,83,126,53,19,157,148,136,17,92,138,79,220, + 116,100,72,92,74,27,194,113,83,53,25,9,204,170,246,87,204,50,114,74, + 83,247,115,118,30,71,105,206,15,244,81,164,230,69,45,98,101,115,226,147, + 115,139,10,156,210,82,124,205,96,110,102,3,98,183,69,244,29,174,54,168, + 213,113,157,80,157,26,244,63,210,152,175,186,231,148,85,153,97,186,41,84, + 157,59,16,183,12,193,87,31,184,235,254,160,184,81,233,126,144,73,232,111, + 88,66,198,249,212,137,110,87,86,250,224,14,177,62,124,185,30,50,33,32, + 223,228,177,250,224,206,66,189,122,178,140,52,73,72,247,103,167,33,195,199, + 248,127,104,208,160,193,31,46,158,154,224,94,248,196,137,107,220,62,67,0, + 176,141,3,68,187,147,247,60,29,142,49,57,76,83,158,93,131,171,39,67, + 177,190,240,144,179,219,97,183,97,229,119,15,59,45,250,213,202,8,238,108, + 235,101,249,59,220,196,236,173,68,222,112,105,56,149,166,149,70,238,52,238, + 184,148,227,169,65,190,43,73,77,86,119,60,92,151,103,213,232,204,204,84, + 238,26,98,110,153,130,8,75,81,159,237,31,251,91,166,165,20,169,10,76, + 181,222,87,17,184,20,215,163,111,74,236,204,30,69,118,21,53,101,187,120, + 158,253,45,144,255,204,228,207,145,115,71,248,106,149,230,199,9,19,151,126, + 22,183,109,209,255,230,125,49,179,232,48,221,104,118,191,83,16,67,183,157, + 28,89,183,125,88,248,58,239,147,213,224,106,58,241,179,55,204,123,158,122, + 167,156,125,230,55,41,100,177,253,97,138,178,65,131,6,207,30,158,154,224, + 6,147,79,16,69,131,131,71,171,164,117,102,173,133,39,137,226,158,174,214, + 34,58,62,133,84,79,156,194,182,243,158,178,114,212,81,118,13,209,65,224, + 200,99,230,106,100,250,70,85,152,81,222,117,144,106,204,82,230,62,141,79, + 42,196,51,103,168,31,129,66,238,223,233,186,122,220,77,91,169,243,201,222, + 241,194,238,73,207,127,151,115,151,82,180,109,183,189,45,235,41,74,233,201, + 252,249,95,149,136,95,183,200,185,37,233,185,99,105,239,230,113,36,124,113, + 4,10,84,250,255,42,150,93,25,54,187,144,78,231,225,61,148,71,168,185, + 137,242,13,253,240,36,74,221,71,25,122,151,178,12,102,92,25,199,228,30, + 43,222,212,195,20,101,83,131,107,208,224,217,195,83,19,220,235,175,205,216, + 198,61,151,62,178,113,182,8,85,61,35,247,232,74,195,181,143,226,190,25, + 34,147,149,110,211,9,222,43,20,148,89,253,198,213,224,218,132,73,64,216, + 90,83,158,7,7,174,86,4,110,214,153,92,36,136,187,16,116,179,5,114, + 6,105,228,4,38,186,31,160,86,41,102,36,16,183,45,105,252,10,242,255, + 181,5,241,5,1,68,142,240,100,188,135,49,200,95,213,36,191,210,37,232, + 174,92,205,42,91,47,147,160,75,122,167,3,227,172,109,32,118,251,183,51, + 139,189,233,206,71,254,187,76,96,178,115,167,236,189,44,203,233,77,185,117, + 82,125,243,63,183,9,254,32,205,137,173,34,64,41,41,51,117,42,243,8, + 79,246,12,114,187,33,53,125,210,64,229,207,59,34,182,140,16,195,181,70, + 236,200,163,55,200,210,148,217,53,153,181,68,167,50,239,195,11,2,13,17, + 4,210,165,74,25,103,175,231,63,124,153,214,59,1,9,179,108,102,224,156, + 216,92,121,232,59,126,54,138,19,173,138,156,178,191,238,101,37,83,224,111, + 162,44,187,74,134,160,152,74,81,23,197,57,12,251,59,2,57,34,84,45, + 84,91,186,201,222,25,145,70,209,113,19,127,147,162,108,208,224,217,195,211, + 183,9,136,75,7,191,71,197,157,246,89,67,39,207,120,28,158,84,100,18, + 229,141,222,101,40,170,142,41,135,86,93,253,219,41,225,233,3,244,58,160, + 173,69,197,169,223,43,39,125,212,161,78,211,202,218,167,126,237,22,226,107, + 6,49,207,68,36,222,93,222,167,41,51,107,174,112,229,234,83,106,149,230, + 169,202,112,181,33,248,246,45,226,182,107,132,38,34,175,239,133,167,15,142, + 157,82,226,82,42,243,240,37,139,65,220,113,215,46,14,94,2,255,187,10, + 12,166,211,173,164,35,61,89,129,139,54,15,159,155,95,103,182,141,109,23, + 95,178,231,154,195,229,220,86,142,81,62,167,195,115,245,231,223,58,189,235, + 44,192,32,171,193,125,24,245,99,251,140,159,11,183,28,255,25,107,181,210, + 252,70,170,124,67,101,137,75,100,119,252,153,243,228,119,254,124,47,127,204, + 143,205,241,126,148,113,188,109,84,148,13,26,124,12,240,212,4,247,234,119, + 71,248,59,106,111,162,252,205,49,83,126,20,92,42,105,165,51,51,92,113, + 152,38,61,27,171,23,3,236,109,167,88,220,41,91,169,185,249,158,178,60, + 253,86,94,251,98,216,253,234,210,57,125,180,139,148,161,95,39,189,72,163, + 28,217,121,164,155,62,246,188,32,253,242,121,202,235,170,14,2,167,88,92, + 74,120,39,128,251,134,32,213,36,97,63,39,72,31,96,148,85,145,102,45, + 145,115,91,17,177,212,33,76,86,149,154,90,249,241,186,136,205,195,147,218, + 145,241,7,69,189,175,76,114,181,86,97,25,204,76,145,254,251,3,231,147, + 15,37,48,42,158,91,78,81,194,177,200,196,143,74,178,236,74,145,92,205, + 221,2,80,118,53,105,71,34,251,238,140,158,125,154,210,152,136,136,148,80, + 185,253,54,42,202,6,13,158,125,60,53,193,157,12,64,48,5,27,31,140, + 193,201,22,33,27,231,195,45,63,28,14,23,196,170,85,215,227,61,199,161, + 127,59,205,149,139,135,154,187,188,255,140,194,137,63,23,139,204,112,14,252, + 51,242,244,94,217,26,11,92,138,206,68,197,244,106,191,118,202,237,6,251, + 57,137,121,99,236,34,183,140,12,125,4,40,230,78,217,169,239,167,27,181, + 19,0,0,32,0,73,68,65,84,182,17,187,66,184,1,69,205,171,76,40, + 254,171,76,82,57,41,157,129,242,223,242,122,90,137,216,124,170,177,118,31, + 37,162,43,215,239,252,182,143,34,218,186,58,220,211,163,56,216,118,95,111, + 141,117,152,162,60,59,29,94,239,63,185,143,219,149,201,241,64,158,162,76, + 130,179,253,69,155,20,101,131,6,207,30,158,154,224,46,95,145,24,91,74, + 9,214,165,31,109,156,79,253,182,182,67,212,110,29,111,147,225,108,21,229, + 195,87,80,95,131,235,5,85,229,131,115,203,128,163,48,228,96,222,153,95, + 232,131,64,215,151,99,50,209,132,23,81,28,186,247,31,102,187,84,121,48, + 102,107,139,25,9,248,211,130,246,229,123,216,23,69,158,126,212,65,80,144, + 196,212,17,65,94,211,202,160,86,41,233,166,234,4,99,219,56,191,72,170, + 196,38,118,85,178,41,255,236,73,89,167,18,117,205,228,207,135,172,198,230, + 69,42,145,219,54,39,246,186,107,44,17,94,18,30,187,212,148,95,139,10, + 225,151,208,169,185,57,25,125,72,39,16,107,230,180,91,166,146,6,119,30, + 148,213,99,185,207,217,33,233,30,159,207,149,203,109,182,241,7,185,146,18, + 64,167,9,137,78,209,166,219,168,40,27,52,248,24,224,233,9,238,133,128, + 171,151,135,199,127,56,163,206,38,196,246,41,27,113,159,62,165,85,87,215, + 19,171,76,216,145,213,189,42,181,36,255,119,47,205,111,109,157,0,101,92, + 136,40,252,207,94,120,225,35,41,29,4,4,209,246,40,181,167,94,51,216, + 215,37,68,51,54,159,14,179,90,88,70,130,217,36,2,51,131,244,78,167, + 114,46,62,13,26,116,87,181,209,82,93,228,228,251,223,202,41,198,67,18, + 178,159,147,142,104,203,251,201,174,139,8,196,88,20,162,155,18,210,64,85, + 9,46,162,118,187,186,212,102,16,85,9,37,221,28,119,114,207,31,105,86, + 252,240,25,127,66,142,142,62,95,85,114,171,251,92,22,100,103,137,243,47, + 136,56,55,252,4,224,6,207,118,90,213,243,237,117,109,163,162,108,208,224, + 99,128,167,111,19,232,75,62,247,218,247,60,214,182,229,113,57,117,81,92, + 225,246,94,134,255,253,209,162,132,182,58,163,233,187,52,209,123,30,186,72, + 79,167,129,19,118,100,168,16,64,169,175,45,31,131,83,66,238,230,17,129, + 25,9,116,63,200,35,64,79,90,182,47,114,194,8,215,26,253,19,18,117, + 126,79,172,5,209,243,26,219,46,4,24,73,191,235,38,6,76,143,27,193, + 161,84,235,195,17,81,78,50,135,136,14,82,134,158,176,202,231,158,157,167, + 121,13,184,86,34,246,140,144,236,121,129,61,47,242,8,52,221,244,115,43, + 46,34,8,250,58,175,29,150,73,238,144,248,210,84,161,131,0,57,214,57, + 177,149,107,112,157,40,5,217,173,189,222,135,163,58,69,160,211,170,238,195, + 71,112,15,67,85,61,89,70,57,234,139,184,48,190,200,228,185,171,0,236, + 98,205,118,95,106,114,87,223,236,17,62,13,26,52,248,168,240,212,4,167, + 148,224,250,39,159,175,8,75,242,113,56,7,98,147,120,215,203,23,159,184, + 166,55,238,80,198,157,61,43,251,254,120,17,156,136,221,93,182,119,50,41, + 155,45,31,29,239,182,235,107,43,55,43,87,14,127,13,146,87,74,11,104, + 228,200,205,68,45,183,144,199,46,210,49,81,203,165,247,162,106,67,118,249, + 103,249,93,231,220,85,40,139,189,38,72,77,31,251,65,132,10,210,156,0, + 188,180,223,147,83,26,40,130,64,35,198,153,213,213,186,148,70,45,157,147, + 71,114,190,139,62,31,228,169,70,221,15,10,162,205,160,2,131,25,9,228, + 119,157,67,188,88,61,94,133,52,179,159,3,185,34,92,235,124,127,73,223, + 189,30,114,156,61,150,213,7,253,57,37,231,187,48,38,63,231,28,99,8, + 158,43,25,95,199,1,147,225,211,70,59,103,215,224,234,34,184,252,111,149, + 55,215,159,75,253,231,43,106,187,27,158,43,215,174,19,182,138,227,73,229, + 196,76,103,121,81,54,53,184,6,13,158,61,60,49,193,25,99,48,198,45, + 164,111,124,57,194,218,14,66,108,115,82,179,220,193,242,220,153,207,127,186, + 94,184,236,185,120,229,102,84,177,234,42,183,7,120,47,202,194,108,217,133, + 32,253,110,102,83,53,214,206,29,63,235,135,203,235,81,99,42,78,32,193, + 47,236,81,175,153,156,124,84,154,186,126,183,172,199,75,142,53,234,239,239, + 93,4,83,94,63,199,69,196,98,175,130,189,230,118,48,2,196,155,18,245, + 233,140,128,251,194,17,194,220,32,191,106,156,253,85,148,145,221,190,131,125, + 69,96,190,189,69,186,233,187,104,107,236,246,237,251,235,116,63,192,172,37, + 102,45,9,254,187,61,242,154,206,235,103,158,132,136,192,94,49,4,125,157, + 215,223,228,39,87,232,243,178,32,183,210,185,48,206,126,206,4,54,233,11, + 1,235,255,168,133,252,31,65,252,237,61,182,47,242,20,174,28,107,167,26, + 237,7,172,127,170,133,250,251,123,236,139,2,251,65,84,173,189,249,222,66, + 192,218,251,64,155,233,226,155,71,6,117,77,222,94,92,226,190,156,20,181, + 218,30,224,113,43,255,73,8,23,225,111,119,167,92,185,252,231,56,63,120, + 27,200,220,76,108,49,109,252,44,21,229,225,60,184,102,62,92,131,6,223, + 122,60,49,193,73,153,57,99,200,61,151,175,72,78,78,90,185,138,178,80, + 176,29,71,93,143,170,191,213,247,193,85,155,180,61,58,237,180,98,213,165, + 51,77,164,41,169,71,68,39,41,245,193,197,168,121,41,34,139,193,78,15, + 210,89,89,42,46,127,254,80,194,235,231,176,151,200,155,187,33,75,43,102, + 132,32,175,74,151,186,59,196,181,44,229,215,23,168,222,129,207,227,184,84, + 187,242,105,196,242,216,157,182,83,94,138,87,220,239,185,111,100,84,234,141, + 139,10,49,139,252,164,65,12,37,246,234,241,235,235,35,201,220,129,228,26, + 16,237,176,215,68,190,31,123,94,20,231,81,74,107,218,43,6,251,215,45, + 237,255,108,130,120,165,120,173,202,209,169,10,82,228,88,211,254,254,1,243, + 171,197,147,203,53,55,127,94,97,105,231,133,0,8,158,172,198,90,221,54, + 9,211,220,166,171,156,6,247,226,18,247,117,248,185,42,167,41,93,56,110, + 137,177,118,128,16,75,4,17,87,175,194,224,66,145,30,110,7,103,127,118, + 149,106,34,183,6,13,158,85,60,85,138,210,147,220,229,23,2,190,253,213, + 71,11,77,14,211,152,135,190,148,80,167,162,204,114,129,71,56,59,242,147, + 178,90,120,114,19,189,253,190,50,100,145,154,189,113,252,39,143,32,222,162, + 79,192,254,164,196,190,44,42,45,1,97,90,114,208,184,218,197,190,44,142, + 34,184,218,159,1,213,75,115,226,98,140,171,191,213,93,71,207,96,255,172, + 202,37,246,118,228,136,69,5,89,131,185,143,54,1,251,227,39,112,81,97, + 94,163,24,133,51,46,142,29,68,91,231,33,25,24,204,107,110,234,120,240, + 57,9,207,81,173,213,149,34,79,34,144,63,187,67,252,180,34,188,62,119, + 147,202,107,174,199,246,5,155,239,13,17,95,20,76,88,84,254,102,102,138, + 205,247,134,152,55,199,236,175,120,37,109,209,59,89,224,49,34,249,252,243, + 114,96,5,151,4,121,4,87,238,131,171,78,243,46,139,71,202,233,201,29, + 48,174,244,198,89,59,32,106,247,121,254,114,149,180,76,201,162,75,133,62, + 53,235,182,209,58,201,190,87,111,152,154,249,112,13,26,124,235,241,161,6, + 158,142,71,138,239,250,220,243,192,180,210,11,231,83,150,229,212,101,241,55, + 111,104,91,94,132,234,68,38,199,228,102,179,133,105,187,43,10,253,109,117, + 15,197,28,209,118,86,93,174,6,247,144,69,211,219,112,221,112,97,83,210, + 239,30,215,161,102,174,25,92,126,114,133,121,67,22,181,176,168,69,18,116, + 243,133,94,180,99,236,235,78,116,81,22,166,228,17,204,56,171,245,121,116, + 12,201,167,206,231,98,21,25,22,209,159,237,11,210,77,31,179,150,216,239, + 22,136,151,139,69,214,111,111,251,34,143,12,253,203,163,191,115,14,157,54, + 193,27,10,121,98,16,23,75,175,91,137,232,146,158,194,94,19,110,42,249, + 149,148,228,229,110,17,141,141,65,156,183,249,121,219,23,5,234,39,20,234, + 252,158,173,113,239,147,60,136,242,252,245,182,191,207,16,92,92,185,27,130, + 171,18,123,197,153,70,203,177,166,253,25,141,248,162,160,245,217,106,215,225, + 195,60,74,31,142,227,8,238,97,40,223,52,249,84,229,161,61,151,79,77, + 250,159,135,221,111,231,250,39,47,87,234,111,30,157,168,250,88,20,69,121, + 4,167,212,135,156,29,220,160,65,131,111,58,62,212,127,165,82,138,55,222, + 188,202,185,115,142,212,172,141,29,89,61,196,146,171,14,245,34,19,143,50, + 17,150,154,120,179,26,220,78,215,77,21,120,116,218,75,220,114,142,252,65, + 180,117,105,186,76,72,82,33,186,201,22,249,101,129,188,230,70,216,4,209, + 182,66,94,91,179,195,124,110,136,125,81,184,199,179,197,223,142,164,35,141, + 23,57,74,81,170,207,103,66,141,242,182,217,254,188,19,191,121,67,194,36, + 179,12,11,76,81,83,43,17,22,128,248,156,37,248,156,68,180,99,184,146, + 58,98,74,83,87,243,202,182,245,245,47,245,90,22,185,1,116,12,234,210, + 238,248,28,178,99,136,47,0,89,212,21,41,139,176,7,55,31,99,224,26, + 136,87,92,93,113,107,118,238,58,79,74,251,185,6,234,117,129,26,165,216, + 215,39,149,167,7,221,178,106,180,120,175,166,241,25,117,171,39,252,60,65, + 153,220,234,196,75,62,154,219,150,182,143,192,94,224,133,23,175,242,242,167, + 221,121,248,30,184,32,12,115,155,174,179,208,68,108,13,26,60,123,120,106, + 130,19,34,66,107,205,171,159,215,92,121,254,37,224,120,66,192,195,136,174, + 44,50,169,143,224,60,234,162,177,248,17,227,114,14,85,148,213,168,198,68, + 45,196,237,204,200,184,44,174,40,63,63,155,27,103,174,75,204,27,210,145, + 224,1,118,202,18,124,231,210,213,182,74,144,3,39,10,209,231,139,151,87, + 216,136,57,32,7,243,202,246,149,17,61,184,246,3,241,230,57,39,155,153, + 149,250,221,106,218,22,54,223,27,58,98,19,177,75,35,94,195,73,250,163, + 109,78,90,65,236,122,243,236,85,137,62,33,31,220,42,7,69,218,81,134, + 26,34,129,29,73,54,159,14,49,63,164,16,94,40,178,173,146,159,255,10, + 162,45,233,39,37,193,137,100,167,44,116,12,230,178,201,111,0,204,107,18, + 241,114,200,60,154,33,39,115,18,102,116,219,9,157,86,247,96,92,78,241, + 254,78,162,71,145,196,147,11,147,170,233,73,79,110,187,210,87,17,197,69, + 237,203,124,255,23,62,77,183,227,20,147,85,135,158,2,65,208,144,89,131, + 6,31,7,60,53,193,249,59,214,241,184,203,143,253,153,239,4,138,190,51, + 33,162,156,220,30,55,154,171,143,224,234,106,54,110,218,242,123,139,49,23, + 164,91,76,31,152,62,139,181,168,136,76,90,114,64,178,79,137,178,154,201, + 60,92,58,47,202,171,210,45,194,135,135,203,136,79,151,239,212,183,174,135, + 77,126,249,88,136,97,71,146,118,150,238,51,175,101,47,227,172,218,243,101, + 235,102,112,94,73,17,231,179,8,38,170,146,102,208,215,168,215,12,242,179, + 247,157,108,102,92,184,144,228,199,246,181,178,8,218,223,63,40,234,99,128, + 125,41,200,137,90,134,58,143,36,1,236,117,80,231,139,212,96,250,201,210, + 91,159,157,135,28,24,218,159,209,200,31,168,146,174,21,89,251,199,139,238, + 24,226,188,197,142,36,234,117,247,188,252,50,39,238,119,219,23,216,107,2, + 49,206,154,225,123,26,253,109,109,54,59,151,206,19,237,122,226,48,143,204, + 92,86,63,11,97,242,168,158,180,248,224,103,79,110,94,241,91,117,191,121, + 233,202,75,92,255,228,229,220,127,82,136,45,237,246,163,73,181,73,79,54, + 104,240,108,226,67,253,103,74,185,167,31,46,248,174,207,15,243,62,183,58, + 1,137,181,241,17,209,149,163,189,179,103,195,197,112,224,4,15,176,221,5, + 124,226,19,191,207,61,211,161,173,238,113,78,174,24,4,53,33,14,16,39, + 69,138,240,229,207,72,244,245,177,139,174,130,160,82,131,242,81,137,111,216, + 22,67,9,98,200,28,16,175,24,87,107,243,24,131,56,25,19,237,133,35, + 152,215,207,229,68,162,46,237,48,173,135,47,188,250,197,131,8,192,159,122, + 22,105,149,73,43,159,175,150,137,82,236,72,230,142,41,242,122,245,237,211, + 87,199,165,125,9,182,237,108,26,119,95,96,175,143,137,181,40,210,141,231, + 198,149,168,208,180,2,76,43,64,94,23,196,45,139,141,247,46,138,204,206, + 69,76,168,92,151,28,24,204,149,49,108,75,61,127,99,72,159,203,82,162, + 215,193,198,123,70,177,59,200,249,254,121,132,136,75,253,107,79,56,48,15, + 56,140,224,30,94,131,139,243,207,203,217,233,111,39,44,1,247,217,106,71, + 231,121,233,165,43,36,251,93,197,162,43,8,2,58,81,155,40,138,106,71, + 229,52,233,201,6,13,158,77,60,53,193,25,99,80,170,135,177,35,254,200, + 247,110,248,217,63,115,137,52,57,193,218,152,32,188,255,200,231,31,166,40, + 171,40,167,23,235,84,119,69,138,114,167,47,228,109,2,213,19,116,106,71, + 23,193,185,197,244,214,43,1,193,151,231,164,81,39,39,50,63,255,205,71, + 59,190,5,192,46,12,68,179,124,207,226,39,108,37,181,104,89,184,52,222, + 86,162,46,207,29,1,102,1,129,29,26,183,191,73,169,249,59,222,51,182, + 17,34,106,161,126,66,177,185,24,98,91,231,138,104,110,6,201,203,93,228, + 223,200,102,181,217,200,17,233,197,56,63,174,28,152,92,152,98,207,11,228, + 96,158,19,214,28,8,255,140,83,20,218,145,196,180,2,122,173,172,87,235, + 26,168,107,115,34,101,115,209,136,248,242,210,157,195,72,22,169,212,47,90, + 228,15,103,164,209,49,140,124,122,50,251,110,135,142,236,214,178,133,62,47, + 73,206,223,103,219,142,243,115,176,175,75,212,119,36,238,245,115,154,31,244, + 106,131,26,62,96,249,189,213,168,176,80,184,186,23,45,178,207,85,234,169, + 41,174,65,94,136,184,164,162,116,105,69,91,19,26,151,219,4,220,251,227, + 73,109,6,76,179,239,115,220,103,171,72,77,10,177,4,123,153,139,227,79, + 243,229,31,252,18,50,184,65,216,106,231,81,92,80,211,192,29,4,33,109, + 233,197,37,199,169,235,6,13,26,60,27,248,16,41,74,73,146,36,104,157, + 112,225,194,69,62,247,61,87,243,22,128,100,159,62,193,196,238,42,142,103, + 117,61,70,138,232,96,14,92,25,229,8,14,92,100,86,238,211,10,98,39, + 14,241,117,179,218,115,138,90,152,235,146,205,197,98,177,243,139,61,29,227, + 100,250,151,77,222,184,13,46,69,120,208,181,128,141,139,28,92,167,111,217, + 172,150,149,191,87,250,199,196,65,196,155,145,86,142,107,213,125,151,151,124, + 25,234,226,252,160,114,222,0,108,37,65,87,209,107,37,21,37,39,56,98, + 141,246,213,69,219,215,227,236,200,93,119,175,149,176,232,182,233,200,118,94, + 211,3,39,168,49,151,77,46,108,1,39,68,202,175,33,35,194,112,183,207, + 199,217,120,196,226,14,143,11,33,98,172,141,8,147,32,239,131,59,28,151, + 3,212,212,222,224,112,122,128,219,110,198,133,11,215,121,253,85,147,215,223, + 202,17,92,25,190,254,38,90,170,233,129,107,208,224,25,199,135,78,81,134, + 193,6,41,37,95,248,210,203,92,185,236,200,200,11,70,202,179,184,160,72, + 85,62,60,93,25,1,29,158,196,170,171,46,130,75,14,60,47,251,93,133, + 254,54,224,162,42,22,252,44,53,41,94,116,53,41,111,97,85,7,213,239, + 210,254,140,174,144,160,21,89,244,18,237,144,215,69,53,229,55,12,17,19, + 138,116,99,246,221,138,216,73,234,51,162,40,215,225,196,139,238,252,192,17, + 141,56,111,157,43,72,181,84,228,234,133,175,201,66,96,226,17,101,202,200, + 108,159,158,16,163,231,181,75,185,146,169,34,163,22,116,172,139,220,178,109, + 203,132,8,20,226,146,173,172,16,179,199,224,98,233,177,44,77,41,162,22, + 242,186,32,248,142,108,2,195,58,64,239,123,121,171,132,16,190,6,86,245, + 9,189,191,60,72,87,174,5,99,117,182,19,136,181,81,182,175,194,201,36, + 142,221,205,130,83,228,206,14,156,75,14,231,190,21,233,75,107,7,8,34, + 190,253,219,190,135,139,151,63,193,102,91,220,116,180,219,109,130,32,32,34, + 155,247,103,158,198,67,179,65,131,6,223,42,124,40,130,211,233,134,32,60, + 71,28,239,185,252,66,192,155,95,188,136,181,119,145,162,74,56,135,68,87, + 135,39,157,232,125,136,181,113,141,222,222,170,171,42,64,200,166,52,99,16, + 99,75,167,111,93,63,91,134,244,147,146,224,13,69,250,221,234,40,138,139, + 181,112,68,214,142,97,34,242,58,88,126,222,153,130,81,94,61,142,240,60, + 169,0,142,48,50,146,83,189,180,112,19,121,24,162,162,253,160,18,105,141, + 65,188,38,170,181,186,51,224,4,33,160,199,69,67,190,21,49,54,222,231, + 34,24,177,112,231,41,38,117,123,200,182,201,174,197,48,70,159,151,46,58, + 221,10,71,128,98,231,250,235,112,238,46,233,97,239,191,62,54,3,40,92, + 102,58,40,249,60,145,45,236,221,116,111,204,76,43,58,237,250,26,155,39, + 183,178,147,73,187,101,48,118,126,64,110,91,138,187,131,25,126,88,174,219, + 199,50,175,191,93,24,95,225,251,223,120,137,245,170,71,29,68,212,35,138, + 34,122,93,155,167,39,125,244,214,120,80,54,104,240,236,226,169,9,46,73, + 18,84,137,36,78,206,181,248,107,127,243,7,185,114,249,34,65,120,31,81, + 227,253,87,216,39,29,147,221,227,244,193,21,40,38,122,67,93,47,156,251, + 91,120,32,246,16,93,237,22,247,161,169,142,112,153,8,196,101,117,148,82, + 4,215,10,0,142,20,228,24,182,109,85,33,27,97,163,188,121,186,253,25, + 93,235,78,226,23,127,182,50,143,140,228,184,136,176,202,207,209,90,231,199, + 43,183,25,248,72,107,45,91,216,145,204,201,40,223,55,46,98,242,251,242, + 164,69,36,144,215,93,63,90,158,200,205,200,86,94,23,206,151,50,139,222, + 236,52,75,163,198,237,236,218,218,196,173,236,250,179,182,9,153,17,134,152, + 128,149,109,232,24,244,58,32,156,134,121,52,185,234,110,49,51,176,139,9, + 139,217,57,22,7,17,168,139,174,139,247,123,212,183,220,51,29,82,49,32, + 21,39,249,227,219,93,144,167,53,203,40,63,230,35,56,111,5,87,223,22, + 224,175,188,236,106,82,244,85,126,223,247,125,129,151,94,186,146,239,243,172, + 244,164,135,200,166,137,55,245,183,6,13,158,109,124,136,105,2,238,159,124, + 191,215,68,81,11,176,92,126,33,224,167,127,250,60,251,253,105,190,93,29, + 209,65,77,250,242,137,34,184,2,169,112,119,225,154,17,154,81,46,69,223, + 167,213,197,71,94,184,200,189,77,72,172,5,139,110,73,153,57,114,209,136, + 237,110,29,105,120,89,253,212,145,87,165,182,117,85,22,194,141,18,34,101, + 29,17,76,4,50,212,5,185,224,8,168,92,167,42,239,203,14,77,81,87, + 203,8,175,220,24,110,71,84,83,162,62,141,120,34,17,67,89,33,55,32, + 111,182,246,164,101,135,6,125,222,145,161,104,199,249,249,228,56,55,169,180, + 50,136,137,75,51,138,210,75,238,235,113,229,8,206,255,46,76,17,185,229, + 81,218,69,69,191,221,67,156,43,135,131,78,48,98,109,228,198,229,28,96, + 190,170,94,199,194,20,81,145,16,199,159,157,195,199,54,27,147,153,12,120, + 83,101,47,42,41,55,117,239,10,98,19,62,157,25,211,105,127,138,47,190, + 249,5,218,221,247,104,119,223,227,98,164,73,244,222,165,39,195,48,87,79, + 66,181,255,173,33,183,6,13,158,125,124,136,20,165,69,169,94,254,143,110, + 109,76,183,163,249,129,47,255,32,87,47,127,186,180,93,85,170,93,23,213, + 249,199,5,81,197,173,196,225,201,196,42,221,246,33,1,29,47,144,131,75, + 29,39,103,63,72,253,137,161,75,63,166,53,82,112,0,125,82,109,222,174, + 156,165,178,200,151,138,69,189,34,244,203,162,182,188,22,149,117,111,31,138, + 1,237,208,228,127,59,132,105,5,136,133,35,88,115,217,160,79,106,54,234, + 24,244,208,17,141,39,89,59,162,154,42,205,16,107,129,57,87,60,190,232, + 182,157,242,209,203,254,227,227,243,88,38,197,99,250,4,236,193,91,163,79, + 91,76,247,33,230,249,19,236,212,160,245,16,179,44,24,90,136,152,109,92, + 159,6,124,18,248,8,206,238,182,142,220,76,17,161,29,91,114,249,134,238, + 42,185,1,8,198,252,137,63,246,51,188,252,105,77,178,119,23,179,228,19, + 133,131,73,169,39,50,138,58,4,65,216,216,115,53,104,240,49,194,83,255, + 135,122,161,72,24,134,24,163,73,146,144,48,216,240,35,127,44,226,39,127, + 234,143,100,91,85,45,250,207,34,57,113,208,235,86,141,230,30,223,189,98, + 110,116,30,193,249,185,112,117,208,93,151,210,44,55,101,123,169,187,12,117, + 110,114,12,213,136,71,245,171,34,3,97,163,74,31,88,254,56,142,100,210, + 112,66,56,205,162,145,184,141,82,42,79,249,213,18,212,225,49,179,54,131, + 124,252,142,143,248,38,130,160,171,138,200,176,148,250,244,56,20,141,84,196, + 40,177,83,63,138,158,206,73,107,16,238,92,218,81,236,142,136,235,144,116, + 237,8,130,108,252,80,56,13,81,74,145,46,38,44,116,245,230,100,99,178, + 155,159,141,98,149,190,84,73,45,182,91,9,135,55,31,169,56,97,106,186, + 40,83,144,96,93,138,18,160,211,82,180,56,171,255,172,44,46,41,38,118, + 31,237,163,253,73,126,242,79,127,63,38,189,206,165,115,123,146,253,46,111, + 238,62,108,15,104,220,75,26,52,248,248,225,67,164,40,139,69,72,74,69, + 171,165,16,114,76,186,141,249,187,127,239,34,175,189,242,121,218,225,105,230, + 22,49,194,112,135,118,107,9,25,129,9,102,57,209,149,199,154,60,58,130, + 43,126,223,166,207,243,222,238,34,169,24,176,211,23,8,248,20,227,206,204, + 45,138,178,91,18,50,20,207,9,79,79,104,127,223,45,248,35,29,130,104, + 139,25,22,11,89,252,114,130,126,81,145,70,29,87,67,138,247,57,137,8, + 27,129,93,96,175,137,202,115,108,119,139,216,100,4,116,109,94,52,113,79, + 4,65,50,117,105,195,184,157,215,214,114,194,203,182,1,215,52,158,167,70, + 69,113,174,222,59,82,93,202,162,220,133,75,61,170,235,238,184,224,82,136, + 78,21,105,96,218,65,92,155,35,22,50,79,37,202,235,2,241,105,151,206, + 28,77,59,68,139,200,165,32,183,18,213,90,99,15,156,243,133,117,231,42, + 218,144,110,52,196,237,252,156,250,217,117,50,17,57,9,218,197,132,116,58, + 68,169,5,131,117,135,238,226,18,235,231,5,139,151,47,98,55,10,99,70, + 232,228,88,158,186,219,135,184,155,159,45,66,186,233,217,83,211,101,34,55, + 180,3,153,15,24,21,217,64,62,71,116,109,160,237,82,148,114,145,43,101, + 183,187,37,150,91,88,238,0,239,83,244,188,237,220,119,241,110,37,114,115, + 59,188,204,223,253,207,127,130,193,36,68,6,55,120,176,26,16,182,218,116, + 58,22,147,168,163,230,238,186,1,167,77,131,119,131,6,207,54,190,105,57, + 22,41,21,74,73,68,75,209,82,125,254,218,223,254,2,189,193,103,105,181, + 206,99,185,133,32,34,222,107,218,173,36,175,149,192,97,84,87,119,183,126, + 24,193,181,43,219,93,140,28,113,248,90,156,199,97,13,206,136,231,1,176, + 107,79,64,46,29,233,163,45,112,181,52,59,114,253,104,117,130,147,135,169, + 22,219,186,190,38,147,79,19,208,195,66,64,178,115,53,76,127,12,123,127, + 118,188,189,71,205,121,228,41,71,223,128,93,83,167,202,183,173,81,70,150, + 35,180,113,39,27,192,58,31,231,205,217,197,201,148,148,151,11,131,100,230, + 190,198,78,12,163,247,61,150,73,145,226,93,38,154,245,202,157,127,239,61, + 139,213,238,61,89,39,89,218,212,75,251,107,166,173,111,211,231,153,200,13, + 162,171,115,114,115,168,143,224,183,113,128,221,109,217,110,203,53,61,47,44, + 241,63,207,136,218,125,90,109,127,252,172,246,102,7,252,196,159,248,41,46, + 191,124,145,94,191,26,233,27,19,209,234,86,255,45,124,244,86,78,79,54, + 104,208,224,217,199,55,181,136,224,34,185,22,74,133,252,228,143,183,249,185, + 159,255,18,201,190,58,113,57,222,235,35,15,192,195,126,165,227,40,174,140, + 162,158,146,163,87,136,56,246,166,135,16,49,173,160,42,236,144,246,61,0, + 150,201,8,189,239,33,175,3,39,18,203,2,43,39,88,17,187,212,96,214, + 10,0,199,169,57,182,153,32,197,171,14,125,127,88,199,178,83,214,201,255, + 71,206,229,164,140,233,62,4,181,200,133,57,122,223,131,78,219,165,4,135, + 198,69,112,7,56,114,240,199,59,164,84,211,155,194,182,143,196,38,224,212, + 142,190,198,103,119,197,190,180,214,238,203,19,105,38,6,241,234,72,43,139, + 107,86,173,53,90,107,103,221,37,38,121,84,232,118,228,72,99,16,42,116, + 78,132,153,152,68,15,88,92,184,12,128,49,197,115,202,233,198,176,213,167, + 252,62,118,2,247,254,120,7,147,67,84,133,37,142,161,29,185,77,179,207, + 207,140,66,88,226,90,2,44,51,226,221,138,93,92,253,44,92,154,124,129, + 47,190,249,5,46,93,25,147,154,57,97,171,93,107,205,21,170,128,110,77, + 57,182,17,152,52,104,240,241,192,55,189,74,30,134,97,190,0,252,252,95, + 188,206,235,175,158,63,218,38,10,61,233,85,103,115,85,235,36,135,67,218, + 106,142,213,106,51,53,93,210,205,121,116,111,92,145,152,215,65,125,61,59, + 206,90,145,94,29,23,130,12,227,66,151,72,89,23,85,249,177,47,157,234, + 194,40,162,86,30,17,217,17,69,243,118,188,119,17,92,38,189,247,4,152, + 134,110,227,161,138,177,139,9,90,235,74,157,202,137,90,64,236,31,84,142, + 19,41,155,55,132,67,33,132,49,140,157,228,95,41,216,74,132,109,99,119, + 153,210,113,91,255,86,122,181,99,56,13,29,177,102,100,164,148,66,107,93, + 17,154,0,176,117,163,111,210,141,139,208,60,41,203,129,75,21,46,186,237, + 156,20,237,90,177,76,70,108,140,96,153,140,176,27,133,213,3,140,25,97, + 204,152,7,243,107,172,182,19,244,254,132,245,162,154,166,116,55,62,197,107, + 177,77,159,103,122,86,35,181,141,75,195,82,75,227,147,196,22,203,14,195, + 29,10,59,174,130,220,132,88,130,184,87,73,79,182,218,67,126,236,71,190, + 228,132,37,122,159,139,75,58,29,75,168,90,4,97,136,10,66,66,21,160, + 194,0,99,11,113,137,123,221,68,211,251,214,160,193,199,4,31,153,12,172, + 27,8,190,237,101,193,127,245,247,222,224,210,73,102,96,156,69,0,113,226, + 102,185,249,158,36,203,236,40,170,171,226,56,77,181,88,187,91,107,127,231, + 109,55,229,122,136,91,180,92,31,92,177,136,154,11,159,197,110,92,196,17, + 244,12,226,58,108,15,36,234,98,114,252,152,135,21,241,113,243,54,133,149, + 85,93,212,85,17,94,232,33,147,153,35,113,61,15,28,1,150,253,42,71, + 85,107,43,247,88,225,3,41,70,89,15,90,230,210,111,119,46,26,244,253, + 106,62,5,154,167,93,39,130,52,156,144,46,11,162,66,45,42,169,71,209, + 211,85,53,103,167,93,73,147,106,173,143,172,187,192,145,155,214,67,87,103, + 91,142,49,203,113,78,110,235,100,200,86,27,130,104,136,102,196,3,211,175, + 60,183,152,38,80,141,196,15,163,168,226,9,209,81,107,128,96,154,9,157, + 238,148,218,2,170,205,220,199,39,125,129,63,254,230,127,194,143,255,185,47, + 3,228,228,230,143,235,157,75,192,77,238,110,9,125,208,26,224,136,205,152, + 179,93,86,26,52,104,240,236,224,155,74,112,78,77,89,200,244,237,94,243, + 133,31,120,145,191,245,11,111,114,114,238,42,134,59,89,244,22,149,200,173, + 100,155,116,240,187,67,253,200,156,157,124,238,232,49,221,29,149,220,234,189, + 91,134,155,72,224,107,112,29,221,99,171,199,44,212,61,196,68,210,233,59, + 178,136,181,139,130,196,80,18,61,127,236,207,232,77,138,245,73,38,189,159, + 23,245,50,47,70,177,34,174,119,3,201,8,197,174,21,211,82,205,79,12, + 167,149,134,239,179,96,18,133,88,72,150,73,150,214,140,247,78,12,178,119, + 66,159,60,138,243,219,15,103,44,186,109,228,216,17,24,144,111,187,208,145, + 35,167,125,175,32,223,137,192,48,102,182,237,161,231,238,92,146,137,123,31, + 149,82,8,219,198,44,71,48,113,31,151,100,228,110,84,54,70,228,117,54, + 99,70,44,119,151,89,39,67,244,254,4,203,132,211,120,200,78,95,168,184, + 148,84,225,109,217,92,52,222,183,142,192,85,230,78,18,117,206,48,7,245, + 150,111,220,194,145,218,157,236,107,158,221,44,197,71,162,18,107,7,124,254, + 213,159,206,123,222,252,49,189,247,100,186,203,94,75,19,209,107,183,208,166, + 75,171,55,58,106,13,128,102,122,64,131,6,31,23,124,211,107,112,229,244, + 77,187,239,22,175,191,240,87,126,152,159,251,249,47,241,220,73,64,156,164, + 88,38,121,3,120,209,8,62,59,104,31,40,23,63,202,17,156,75,107,46, + 14,186,0,146,232,18,198,68,121,157,167,42,50,217,113,127,235,22,165,13, + 146,246,42,147,234,79,38,121,154,210,195,167,21,235,16,107,81,144,85,185, + 65,58,155,42,240,56,24,132,78,82,239,78,96,120,68,136,158,136,192,73, + 241,203,125,122,131,139,123,215,224,221,178,71,82,254,184,101,243,115,19,11, + 201,32,220,97,101,145,74,204,197,53,25,42,191,139,99,47,207,237,233,224, + 232,124,42,231,153,69,111,64,30,181,121,60,48,125,78,227,172,85,66,12, + 142,4,64,117,104,71,42,127,15,31,138,220,199,244,110,118,35,244,62,78, + 49,57,63,147,216,176,23,248,236,167,126,132,159,251,11,63,200,107,223,115, + 129,7,127,176,169,212,221,218,237,54,173,174,36,234,116,232,118,45,42,12, + 232,117,143,155,243,155,244,100,131,6,31,47,124,36,41,202,48,12,105,181, + 156,170,178,215,27,208,13,4,255,229,223,249,20,63,251,115,127,137,86,235, + 229,18,145,109,75,95,14,15,155,221,229,16,17,181,143,213,140,190,111,201, + 55,122,139,78,82,177,234,186,16,189,11,128,236,149,148,129,3,23,149,204, + 182,61,162,164,88,228,115,49,69,77,143,155,26,185,116,235,50,105,163,252, + 84,160,210,118,214,51,86,137,52,202,86,85,101,213,161,106,173,153,13,199, + 199,70,199,249,190,118,21,51,228,69,187,87,241,148,44,163,220,126,160,135, + 67,196,28,68,118,25,65,226,106,140,11,246,48,59,176,161,82,11,196,68, + 34,153,49,220,21,119,13,67,21,187,116,166,90,84,90,23,250,237,30,65, + 207,176,49,2,217,233,99,76,149,28,245,222,21,14,39,145,34,178,207,209, + 205,110,32,226,232,83,217,22,59,194,221,35,39,155,146,166,15,155,245,198, + 129,99,73,53,106,171,54,115,71,124,199,167,190,196,95,254,171,63,195,171, + 223,121,194,106,126,135,115,47,84,107,125,113,44,81,178,95,17,150,4,129, + 170,68,111,13,185,53,104,240,241,195,71,86,131,179,54,102,159,165,11,181, + 78,8,90,115,254,211,255,226,69,254,206,223,250,15,177,68,116,218,239,226, + 162,177,78,246,53,205,191,220,194,181,165,16,154,120,183,147,227,148,85,40, + 187,44,249,4,105,146,176,23,39,32,23,64,27,187,219,102,150,97,17,112, + 9,128,25,47,98,214,11,148,88,16,189,235,220,86,212,231,221,126,124,106, + 14,64,140,102,248,225,224,115,178,20,164,79,1,110,119,69,221,236,162,66, + 108,58,108,219,177,139,160,166,29,228,96,238,8,210,58,81,198,32,171,21, + 106,61,68,235,33,93,57,97,99,166,44,102,46,58,26,132,42,183,14,179, + 242,156,35,21,143,184,237,172,182,178,17,60,147,231,29,1,69,123,225,234, + 109,25,1,65,169,214,39,70,168,197,130,69,183,77,154,145,237,116,28,185, + 99,47,46,209,149,19,150,137,102,153,140,24,172,59,216,197,4,49,206,196, + 35,98,4,58,35,44,95,167,211,195,194,213,100,106,144,215,97,177,204,212, + 160,89,173,114,157,12,177,76,72,121,9,219,26,17,217,231,216,110,47,16, + 203,107,108,244,28,221,27,163,130,203,72,113,19,107,71,44,226,89,37,13, + 61,28,8,244,190,143,73,20,82,198,116,100,54,33,96,59,43,245,191,185, + 186,155,16,91,224,119,129,27,192,77,200,234,183,199,125,110,23,192,94,200, + 201,237,51,175,4,164,102,126,52,14,167,221,110,51,158,180,9,90,217,141, + 135,26,34,85,255,136,220,14,93,75,180,62,219,72,160,65,131,6,207,6, + 62,50,130,19,34,202,22,134,34,186,185,216,83,252,232,159,90,242,55,254, + 250,95,193,218,215,128,9,46,197,244,62,5,153,57,225,64,33,249,62,70, + 188,43,234,124,50,212,68,81,54,117,186,52,244,114,187,77,179,69,212,203, + 198,29,210,244,42,155,233,183,177,85,110,129,74,75,57,194,92,92,49,17, + 174,29,64,182,43,253,109,157,76,66,47,199,206,249,3,170,141,217,144,73, + 248,39,242,192,139,241,16,78,10,239,83,149,131,112,119,60,179,13,220,248, + 27,56,50,112,174,244,202,233,97,81,139,203,210,142,118,104,24,92,220,99, + 135,214,17,214,172,197,198,8,196,162,184,150,174,44,82,112,169,152,20,227, + 111,212,188,226,135,89,222,6,32,221,21,74,213,195,212,36,192,118,123,129, + 180,223,39,237,247,17,93,141,102,146,75,255,221,188,64,87,63,139,90,10, + 47,0,154,207,111,2,208,233,15,145,106,192,131,133,161,159,93,98,46,46, + 177,243,108,212,210,93,12,51,224,22,197,141,79,125,90,243,59,62,245,37, + 254,218,95,120,157,207,188,18,16,200,17,201,126,151,15,50,133,204,181,38, + 139,202,90,129,204,39,6,212,65,235,106,148,93,55,185,190,65,131,6,207, + 22,62,66,51,61,39,103,247,234,189,145,154,209,234,238,248,228,103,94,230, + 231,255,226,117,254,254,127,251,179,124,215,171,175,0,99,162,208,247,68,149, + 149,148,101,179,220,50,218,248,59,250,64,142,136,99,73,28,187,203,24,116, + 67,231,75,104,231,88,238,208,9,143,157,76,22,107,193,118,240,28,189,247, + 44,102,225,22,179,241,11,173,163,26,21,20,81,157,94,7,232,117,224,132, + 38,157,170,162,83,216,54,209,94,84,29,74,252,243,75,106,197,245,42,168, + 16,204,32,84,40,181,112,34,144,115,69,100,234,201,37,214,162,226,7,105, + 71,48,27,22,219,45,116,4,122,136,154,21,17,159,136,74,106,197,131,186, + 154,39,180,242,57,248,116,169,29,218,234,246,217,113,203,10,208,192,78,97, + 34,9,218,247,233,74,139,221,40,130,65,166,230,100,130,102,194,52,214,116, + 178,243,239,170,98,127,190,113,219,205,106,115,131,77,227,253,109,220,123,220, + 102,52,186,6,192,124,238,110,80,78,46,14,216,154,62,157,118,154,183,7, + 184,200,237,46,134,59,8,126,39,219,243,29,16,111,129,184,87,188,78,118, + 0,246,50,127,233,103,126,138,191,252,87,127,134,235,223,253,25,0,182,241, + 7,132,45,119,93,253,238,128,118,187,77,167,61,170,56,150,104,211,205,83, + 147,126,98,55,56,207,201,195,244,100,35,52,105,208,224,217,199,195,229,123, + 79,9,99,138,187,93,173,53,157,78,135,249,106,12,218,32,152,113,249,133, + 17,127,242,167,174,114,245,202,27,252,195,255,225,42,255,219,63,254,39,128, + 95,13,246,252,158,0,0,28,120,73,68,65,84,164,102,148,165,253,157,118, + 192,246,64,80,225,107,112,110,209,35,247,14,180,38,202,38,59,223,195,114, + 147,56,241,105,80,183,176,69,246,57,198,151,52,139,223,254,167,180,94,206, + 4,25,82,209,55,19,214,201,3,208,17,3,112,209,87,214,27,87,38,174, + 112,26,162,117,128,156,0,179,172,54,182,131,233,190,207,164,149,56,101,34, + 123,6,99,3,72,176,99,150,73,65,40,43,169,96,229,198,246,44,19,205, + 32,204,134,155,102,234,68,49,114,199,140,181,112,41,209,104,135,29,9,252, + 30,60,191,169,251,48,28,187,20,91,26,78,96,13,195,94,139,116,45,81, + 100,253,114,217,62,23,203,57,112,142,141,1,43,149,27,25,180,185,192,166, + 91,47,117,183,107,133,206,134,141,14,85,12,218,25,40,15,206,73,192,160, + 39,19,54,6,100,167,79,178,168,214,40,39,145,98,153,21,254,150,90,146, + 114,142,97,59,19,171,164,239,18,181,238,177,219,151,223,223,204,12,89,223, + 0,46,16,69,6,163,55,44,87,78,73,185,221,5,8,49,207,90,2,238, + 98,185,131,224,125,224,22,136,119,243,227,182,218,67,246,187,5,214,14,248, + 236,167,126,132,31,253,177,159,230,245,87,13,23,47,159,144,154,57,201,126, + 151,139,74,18,189,103,183,219,209,235,247,115,114,243,24,13,229,145,106,178, + 213,106,136,172,65,131,143,43,62,18,130,147,82,230,36,167,148,98,191,79, + 233,119,206,161,181,101,189,94,34,197,154,182,136,121,245,245,14,191,112,253, + 135,248,129,55,175,241,139,255,253,47,243,27,191,249,111,136,194,62,113,114, + 27,191,8,110,119,41,229,168,13,118,121,138,210,167,155,194,164,75,74,194, + 70,200,220,89,222,213,241,220,44,176,139,147,23,249,242,15,253,16,176,97, + 181,88,51,124,233,121,140,1,41,231,88,61,64,99,232,173,96,205,3,200, + 248,108,182,237,49,92,43,68,73,148,178,96,207,144,76,72,34,12,90,47, + 65,15,25,2,122,239,8,103,72,139,180,123,30,49,49,108,178,58,156,111, + 128,238,98,216,32,97,179,68,116,207,177,76,30,48,164,16,131,32,70,16, + 111,136,124,196,25,183,97,146,0,182,18,229,165,225,132,37,219,188,190,7, + 78,200,210,149,176,104,165,12,8,208,147,137,123,94,150,30,244,174,254,118, + 9,66,45,49,203,49,66,41,116,63,101,99,4,195,137,204,39,0,4,90, + 99,215,10,49,116,132,55,236,181,208,211,17,118,29,176,150,22,129,70,175, + 68,94,123,211,76,48,123,144,145,75,99,106,38,244,213,8,208,24,160,213, + 27,241,210,75,17,63,246,163,154,95,249,213,95,230,238,253,59,217,123,51, + 118,223,213,245,163,207,80,208,210,116,218,41,130,41,38,139,200,5,55,128, + 57,173,104,206,126,231,136,109,23,91,164,61,33,106,189,204,143,252,224,15, + 240,197,55,221,108,183,118,247,61,182,241,7,238,243,209,106,19,200,17,125, + 251,62,72,208,157,144,32,8,80,153,191,100,217,111,178,26,185,101,67,92, + 155,104,173,65,131,143,37,62,18,130,43,67,74,73,171,21,160,181,70,41, + 65,175,231,238,232,101,152,34,87,146,180,125,155,63,250,71,67,174,94,121, + 131,95,250,95,174,241,191,255,31,255,140,248,254,138,34,61,121,88,235,40, + 238,184,253,157,121,171,43,105,71,61,88,222,167,219,219,179,221,221,2,98, + 46,78,6,252,201,31,254,44,111,254,240,23,249,252,119,36,8,35,73,54, + 19,102,241,130,97,207,50,91,78,24,15,166,172,128,190,116,105,188,101,34, + 232,77,128,19,133,214,41,106,189,64,235,204,76,152,14,22,208,98,132,228, + 62,11,29,49,200,82,155,90,15,217,152,41,140,247,116,1,123,71,98,46, + 13,17,106,153,55,64,175,112,164,10,142,244,68,247,28,139,217,3,70,64, + 167,111,49,184,136,215,47,167,90,107,16,35,182,237,37,209,68,226,8,43, + 195,236,57,180,44,215,139,68,214,187,240,193,209,123,80,150,243,131,203,75, + 27,51,66,169,165,75,157,118,53,233,238,4,197,61,54,70,48,200,154,184, + 55,122,75,87,15,9,112,145,229,237,231,4,39,157,30,150,185,83,163,150, + 34,107,25,77,216,174,3,186,163,17,54,155,162,103,2,71,170,42,12,120, + 245,187,47,241,183,94,8,120,245,151,44,255,235,47,189,195,111,255,238,239, + 102,17,182,123,127,71,35,247,28,109,86,40,217,71,167,69,106,58,106,221, + 35,222,251,27,150,45,187,216,34,184,192,62,142,232,180,3,62,243,233,31, + 225,203,63,248,37,94,123,245,50,231,95,184,71,178,191,65,49,244,214,145, + 155,16,91,86,140,233,245,251,12,3,72,130,48,175,187,69,81,39,119,42, + 17,45,85,17,150,52,228,214,160,193,199,23,31,57,193,121,248,72,174,12, + 169,250,140,38,184,175,193,140,43,127,243,58,63,254,211,215,248,218,111,124, + 131,127,240,15,254,39,150,155,128,237,206,219,122,141,41,200,206,45,156,190, + 166,2,176,94,46,88,109,150,4,226,109,46,157,192,159,255,249,63,207,15, + 124,241,37,94,255,206,136,253,246,247,216,175,92,212,39,163,9,38,6,187, + 155,51,236,77,115,175,196,21,32,231,146,46,6,13,116,52,136,197,2,61, + 28,186,177,47,102,196,32,44,68,44,128,147,220,135,142,220,196,66,64,255, + 92,94,70,92,93,202,250,229,50,114,11,23,17,187,190,59,255,169,90,115, + 89,119,136,51,207,202,100,52,70,94,5,129,139,122,245,218,13,62,13,186, + 138,227,241,170,85,136,133,64,78,230,96,52,8,75,47,248,4,166,37,89, + 75,235,46,170,116,14,101,132,139,136,15,78,36,231,49,206,141,228,82,15, + 117,227,94,101,155,193,186,131,198,69,113,171,210,66,111,55,10,157,28,183, + 80,164,253,62,59,45,233,43,152,105,197,73,95,146,210,65,39,41,138,251, + 92,185,114,194,207,254,199,255,1,95,126,243,77,254,237,111,222,224,159,255, + 211,95,230,31,255,95,255,152,197,210,50,159,207,57,185,208,39,160,67,186, + 39,143,174,172,189,203,118,191,206,106,119,153,147,11,17,81,251,114,30,177, + 189,252,105,77,216,106,147,236,111,3,237,252,115,209,237,12,232,219,25,59, + 53,70,134,46,141,173,100,31,17,89,122,153,21,87,153,220,14,85,147,13, + 185,53,104,240,241,198,71,78,112,101,91,163,48,116,203,181,78,55,244,59, + 231,216,171,61,139,249,251,0,244,6,3,80,130,151,63,245,128,23,46,95, + 225,143,255,248,127,195,175,252,139,111,240,7,183,83,110,190,245,14,55,110, + 221,96,23,159,114,255,193,133,124,127,237,206,4,149,90,246,27,67,171,27, + 242,185,87,62,197,47,252,215,159,224,11,95,122,153,81,255,14,58,73,145, + 233,148,174,208,116,7,17,179,37,25,133,184,136,100,163,71,8,166,140,183, + 123,32,66,143,231,108,144,12,70,35,244,220,109,35,22,2,155,45,116,203, + 174,166,43,39,172,165,162,215,189,0,156,178,76,70,244,86,89,125,109,3, + 162,123,143,197,133,207,35,153,99,204,40,143,216,238,137,14,23,86,91,146, + 33,156,232,30,96,48,203,49,242,242,29,88,128,89,95,64,141,239,2,153, + 79,228,26,130,46,133,219,202,24,230,89,31,219,32,203,162,109,140,160,135, + 23,179,8,54,6,186,0,159,50,200,206,0,179,93,149,156,70,198,108,181, + 161,23,46,80,179,75,36,195,152,19,221,67,246,45,102,187,66,222,93,101, + 115,242,234,123,242,58,186,199,148,45,214,142,56,101,131,215,136,234,236,39, + 95,123,235,103,226,146,147,44,34,11,85,64,167,37,72,2,131,209,43,148, + 132,111,127,245,28,151,94,188,200,143,254,241,63,203,207,255,246,27,160,174, + 115,114,225,38,219,245,7,174,102,215,234,16,166,174,190,26,182,2,38,131, + 128,231,159,127,133,235,87,255,20,215,94,190,194,11,47,6,188,244,210,21, + 158,127,33,96,21,47,193,46,216,197,186,82,103,243,109,0,75,62,65,11, + 104,183,39,89,43,128,38,108,157,71,201,77,150,150,172,78,10,168,107,9, + 40,127,150,27,210,107,208,224,227,3,97,173,173,215,69,127,4,112,117,57, + 119,184,114,143,92,28,199,164,105,66,154,106,226,108,216,104,28,199,236,83, + 131,78,19,226,173,123,108,183,59,182,236,10,101,151,86,87,86,28,224,189, + 143,32,128,76,51,225,70,114,143,253,202,181,6,8,51,103,183,92,209,86, + 46,98,25,102,36,36,218,110,91,41,11,53,167,39,40,15,95,71,19,202, + 245,93,117,116,207,213,213,14,176,220,57,55,253,142,146,108,181,33,74,79, + 242,253,183,87,49,201,48,166,47,179,227,141,230,132,243,25,243,129,101,16, + 42,68,79,147,156,191,79,120,247,37,196,123,11,230,255,106,77,239,143,190, + 232,212,142,25,252,88,26,127,14,249,249,222,93,113,123,169,24,191,220,203, + 94,243,44,93,152,17,92,39,91,188,219,171,152,93,63,202,175,213,95,167, + 80,75,122,253,20,177,16,172,251,16,45,135,108,213,58,39,74,191,207,114, + 253,13,57,97,41,198,121,237,109,166,21,157,222,69,186,193,142,32,154,228, + 142,252,82,21,42,207,52,117,239,79,28,111,209,73,74,162,143,91,19,194, + 82,148,117,184,237,54,118,159,133,120,187,173,124,46,172,237,228,67,75,193, + 25,0,248,122,91,57,37,9,245,205,220,192,55,45,122,147,178,153,248,221, + 160,193,183,18,127,104,41,74,15,41,21,73,146,160,148,64,107,183,96,71, + 81,68,156,149,92,162,168,195,122,35,8,85,10,164,108,83,142,166,43,239, + 118,59,172,237,48,224,125,146,176,77,16,148,220,57,212,16,109,32,232,109, + 72,99,141,9,38,7,81,92,140,149,35,218,3,144,198,45,170,43,3,189, + 96,134,101,140,180,51,140,25,211,94,249,26,80,68,50,140,9,23,238,251, + 10,24,222,123,55,79,65,110,178,173,60,145,172,147,161,139,8,179,69,125, + 177,22,128,66,75,232,103,191,95,192,165,8,25,195,86,173,233,47,4,51, + 117,158,241,242,20,147,77,139,217,158,14,8,129,204,158,145,192,78,73,178, + 212,236,122,21,96,245,32,39,89,79,176,93,12,171,75,67,94,100,193,138, + 42,185,129,147,243,111,52,164,241,130,97,150,46,53,102,140,148,179,74,180, + 105,230,35,54,72,186,75,195,174,47,176,171,42,185,249,125,29,98,160,12, + 22,24,43,141,13,36,34,107,15,48,214,189,24,126,185,247,195,67,61,201, + 169,208,17,89,156,125,8,66,85,24,30,119,59,96,50,94,215,166,139,10, + 55,168,208,253,125,27,239,142,62,27,46,2,45,38,114,151,149,146,161,10, + 206,36,55,143,38,53,217,160,193,255,127,240,135,26,193,29,34,73,18,180, + 182,104,237,82,151,126,129,75,211,132,213,106,85,121,204,223,177,31,90,56, + 121,247,247,114,244,230,23,49,0,147,213,240,124,36,39,211,59,76,151,29, + 164,185,153,111,35,51,219,18,19,79,153,156,223,163,31,28,15,228,244,16, + 237,105,137,252,92,234,17,96,16,20,42,199,101,58,99,16,140,89,215,100, + 251,122,217,42,31,37,239,231,81,156,18,69,47,155,156,100,145,212,112,74, + 58,189,10,191,167,88,167,239,211,127,241,18,235,44,0,242,138,200,67,228, + 34,18,57,175,144,219,98,45,242,243,145,45,119,82,157,84,98,35,203,106, + 53,103,152,205,211,243,209,156,143,44,61,113,150,235,119,158,44,55,122,148, + 71,111,70,142,177,114,196,82,75,250,106,132,234,59,150,246,209,155,119,6, + 169,131,127,127,125,228,94,134,54,93,122,93,155,167,17,15,35,124,168,255, + 92,148,39,17,28,126,46,60,177,1,31,89,228,230,209,68,112,13,26,124, + 107,241,45,39,56,15,79,116,101,146,171,91,208,160,88,212,60,234,22,49, + 15,31,37,152,221,42,39,185,233,82,112,210,121,63,223,102,182,140,57,223, + 47,212,135,211,89,105,177,205,250,225,196,190,154,170,148,45,67,39,149,71, + 36,166,51,5,161,204,130,74,47,159,223,174,3,218,234,94,158,14,133,42, + 201,121,40,177,192,14,45,27,51,117,245,190,85,224,154,210,47,245,137,7, + 139,202,204,181,67,248,200,211,139,89,22,107,65,191,239,182,139,83,91,200, + 249,91,238,188,134,114,142,141,44,34,22,21,226,246,169,203,34,186,171,18, + 234,98,45,16,209,213,236,133,112,233,201,174,26,97,153,228,228,38,212,128, + 160,43,233,4,242,136,224,92,196,94,188,207,238,251,113,95,94,249,125,12, + 130,240,204,207,132,255,60,168,32,68,167,73,165,183,173,156,146,44,139,73, + 128,10,185,125,20,62,147,13,193,53,104,240,173,197,31,122,138,242,16,126, + 240,102,171,165,216,239,33,91,123,136,99,42,139,162,54,93,148,220,212,238, + 163,88,184,138,200,205,63,55,95,24,233,231,242,137,209,4,76,90,240,186, + 101,78,90,178,94,210,65,140,74,111,185,95,164,107,250,182,173,42,161,36, + 123,208,165,204,168,39,142,221,246,2,109,117,143,237,182,16,195,164,155,1, + 189,129,69,154,148,21,19,76,60,101,40,231,196,225,39,16,102,74,121,230, + 121,95,130,180,2,16,152,249,48,203,116,174,80,163,9,233,116,82,137,206, + 214,201,144,36,86,12,123,150,197,90,48,236,89,238,137,14,125,49,34,78, + 45,65,4,235,180,68,78,114,130,204,47,115,202,194,140,96,227,206,187,39, + 44,113,40,176,81,230,78,178,45,122,218,68,123,138,241,13,220,155,49,72, + 16,217,164,2,35,199,116,243,232,173,56,148,39,55,99,59,68,29,1,164, + 132,186,131,56,104,156,62,124,159,14,113,24,249,5,129,34,138,58,196,241, + 54,127,223,203,8,219,189,60,133,121,72,108,254,103,159,146,252,40,201,173, + 65,131,6,223,122,124,75,35,56,168,10,79,180,54,181,41,75,168,222,233, + 31,166,179,202,117,21,247,189,218,176,187,51,73,190,15,163,87,72,213,103, + 191,118,145,148,143,234,220,207,119,42,251,157,207,239,114,50,220,113,127,209, + 206,211,152,117,216,174,131,220,162,42,191,46,57,102,189,18,116,135,67,54, + 139,5,221,225,16,97,230,149,253,140,250,119,73,55,27,164,157,209,235,238, + 217,198,142,192,125,45,172,139,97,101,38,12,239,189,203,226,130,19,173,120, + 239,199,36,206,38,109,203,49,178,101,48,251,34,90,144,45,147,171,27,145, + 89,244,56,232,179,91,174,232,244,82,140,116,100,117,120,77,163,254,93,230, + 11,199,218,189,96,198,58,29,211,79,231,172,130,42,185,111,183,23,242,253, + 172,45,121,244,102,130,49,97,228,206,35,28,140,142,162,183,182,12,243,62, + 51,255,30,123,148,223,235,199,129,143,230,220,115,139,207,67,221,103,193,61, + 94,68,109,238,123,209,230,240,81,17,92,19,193,53,104,240,173,197,183,156, + 224,202,48,198,160,181,206,197,39,126,17,180,123,157,147,20,240,200,59,125, + 191,144,150,97,75,131,80,119,38,225,255,107,239,110,67,44,187,239,2,142, + 255,206,189,51,179,243,180,187,73,19,130,45,73,77,101,9,169,164,248,80, + 76,125,145,66,82,33,37,144,23,213,162,129,32,146,23,37,40,137,121,33, + 130,175,106,27,95,85,16,181,138,160,81,106,170,105,72,104,213,90,10,34, + 164,197,80,65,169,37,69,8,113,83,182,36,164,88,155,37,117,159,102,103, + 102,239,157,123,143,47,238,61,247,158,251,48,51,103,155,93,239,230,183,159, + 207,155,185,119,238,127,238,222,217,217,189,223,57,231,252,255,231,116,46,141, + 195,182,183,219,139,99,27,187,177,117,110,252,70,89,143,221,118,217,158,152, + 129,57,79,217,58,30,69,255,92,148,173,217,93,135,131,235,223,157,153,249, + 250,86,255,108,108,118,94,31,221,175,118,89,86,214,86,7,151,117,217,59, + 221,31,237,118,140,136,232,23,55,68,177,59,255,170,227,163,24,213,182,176, + 14,122,189,117,7,69,188,174,122,206,234,123,173,38,156,212,119,79,30,61, + 54,216,138,170,2,87,143,219,180,122,236,202,78,111,230,103,87,127,172,254, + 239,32,98,246,223,194,244,22,223,116,216,6,183,199,75,1,174,230,132,18, + 129,131,197,186,166,2,23,49,142,92,68,76,108,205,69,204,127,131,155,54, + 111,183,85,68,196,242,210,118,116,182,107,103,65,105,15,143,227,108,93,136, + 245,246,228,165,79,234,161,139,24,44,49,88,31,46,59,216,46,7,111,136, + 151,182,38,175,171,86,5,172,122,179,47,226,76,172,108,110,140,198,29,217, + 28,156,86,172,179,117,49,110,222,60,29,111,109,221,50,58,238,215,61,253, + 95,113,211,109,55,196,15,191,119,54,138,35,103,98,99,189,19,23,183,87, + 98,99,189,19,123,167,199,7,249,118,142,254,216,76,216,206,247,199,199,252, + 234,167,203,170,76,199,104,63,55,111,158,142,31,158,63,18,55,29,187,52, + 113,12,242,198,27,214,70,91,176,245,88,54,137,91,68,196,234,230,209,137, + 93,147,245,227,94,17,49,250,101,166,174,215,235,206,132,176,250,220,188,173, + 251,105,71,90,203,113,169,223,157,51,67,242,234,76,38,217,143,192,193,98, + 93,115,129,171,155,142,221,224,227,120,171,46,34,38,222,56,235,198,231,17, + 236,68,191,191,50,243,70,186,183,51,249,6,89,223,141,25,17,163,93,152, + 149,157,78,25,101,111,242,154,99,221,221,249,139,162,35,34,150,87,91,209, + 221,237,143,118,217,77,235,238,246,163,181,55,216,98,186,241,232,78,156,189, + 176,27,219,231,207,199,198,102,25,23,183,230,111,157,77,188,254,226,166,3, + 31,239,173,31,143,27,218,227,173,214,254,210,252,45,185,234,245,205,251,94, + 170,215,119,225,194,86,108,220,120,235,232,126,253,249,186,75,107,177,178,212, + 26,77,242,137,136,88,41,122,177,126,252,230,209,216,233,73,29,237,118,107, + 230,242,51,211,63,159,122,4,231,141,155,222,197,57,109,101,101,101,52,126, + 81,103,38,17,56,88,172,107,58,112,149,106,182,101,253,77,112,222,111,249, + 17,147,191,165,215,85,111,168,213,27,94,245,92,211,161,171,92,236,140,39, + 180,236,237,245,70,203,13,42,59,157,201,191,182,181,149,98,20,193,245,181, + 99,19,99,214,86,138,209,253,234,118,196,228,241,191,202,185,51,243,119,129, + 94,184,176,53,243,185,75,237,247,196,145,222,247,71,241,217,47,98,17,49, + 19,218,106,141,218,198,112,105,64,181,94,112,171,219,142,245,181,99,163,215, + 182,213,109,143,226,87,69,59,34,162,88,221,136,165,216,137,189,88,155,88, + 92,223,58,178,25,173,98,39,86,142,12,182,236,234,187,139,167,3,183,188, + 188,60,113,166,155,74,175,215,31,253,252,166,67,56,30,51,14,221,65,255, + 14,6,183,23,179,182,77,224,96,177,222,17,129,171,171,47,45,136,24,7, + 43,98,60,89,160,219,237,206,157,56,80,125,126,176,208,188,53,17,189,193, + 199,249,199,252,34,246,159,206,62,152,205,183,54,250,24,49,92,146,112,100, + 51,154,232,117,106,87,18,31,174,234,174,194,88,157,221,163,220,189,24,221, + 165,181,216,235,180,163,104,237,70,123,105,57,246,58,195,73,20,43,147,175, + 167,218,154,170,159,25,164,190,112,122,98,108,209,139,178,24,71,177,40,207, + 142,94,119,61,232,157,178,29,189,238,236,153,70,214,86,138,232,148,237,81, + 216,42,211,107,205,34,102,39,119,92,206,196,142,250,207,109,244,61,77,221, + 175,171,130,86,157,90,107,81,167,216,18,56,88,172,119,92,224,42,213,155, + 94,181,5,112,185,111,96,253,126,127,120,89,159,222,232,180,97,149,38,199, + 253,166,39,55,84,225,171,47,74,174,175,227,26,60,54,126,83,63,183,211, + 138,163,195,32,238,92,24,111,181,237,238,245,70,203,33,170,168,84,177,234, + 236,237,191,75,180,30,182,229,149,119,141,159,99,184,88,250,226,118,17,27, + 235,229,40,168,237,149,250,194,232,217,191,187,121,235,210,46,110,23,113,116, + 99,59,182,119,98,38,106,213,243,76,175,119,139,152,157,224,113,165,103,45, + 94,171,231,136,20,56,88,172,119,108,224,174,132,234,154,117,131,75,249,180, + 38,66,87,143,220,165,114,16,133,114,184,85,211,47,55,162,85,92,156,185, + 93,217,219,235,238,123,230,142,74,53,17,162,250,88,125,93,61,44,173,98, + 39,46,92,28,172,255,171,111,65,181,151,151,70,247,235,91,101,43,69,47, + 118,122,71,7,227,251,235,177,90,11,87,21,180,121,49,219,239,181,78,111, + 181,246,58,75,209,94,217,27,125,28,127,253,228,148,252,106,137,70,253,210, + 51,243,182,180,179,19,56,88,172,235,58,112,17,245,171,143,151,163,192,13, + 22,157,207,59,54,52,59,157,189,236,244,162,179,60,152,157,185,210,29,156, + 81,99,167,183,18,107,237,206,232,118,123,117,240,198,126,164,24,68,225,82, + 185,20,155,203,231,39,102,117,70,140,143,251,77,111,61,181,138,157,216,219, + 157,127,5,238,136,136,165,213,118,236,237,246,98,105,181,29,253,114,45,90, + 197,78,244,203,193,25,93,14,219,146,172,204,91,55,56,173,10,222,65,241, + 158,142,91,196,228,113,209,234,216,219,245,64,224,96,177,4,174,63,187,219, + 175,218,162,27,220,30,47,62,175,166,169,175,174,70,204,155,165,190,188,180, + 29,221,189,245,153,207,215,191,174,219,29,220,174,198,78,175,207,155,54,189, + 21,85,223,5,90,191,95,119,216,214,99,125,41,197,188,117,103,229,84,220, + 187,237,157,88,238,173,141,94,223,116,12,167,151,102,236,23,182,235,237,68, + 198,2,7,139,117,221,7,174,82,133,110,112,92,174,31,101,185,51,245,248, + 96,169,65,117,77,187,136,249,145,171,212,79,57,86,191,31,49,136,220,60, + 189,94,119,180,59,52,98,176,69,184,211,91,153,217,29,58,111,183,104,245, + 248,90,187,19,151,250,221,104,45,239,141,162,180,223,218,192,203,181,223,34, + 236,195,102,179,86,81,219,111,242,79,86,2,7,139,37,112,251,24,79,98, + 153,222,194,27,159,86,172,110,222,218,174,105,243,198,180,90,157,137,224,213, + 119,143,238,183,214,107,122,13,224,116,120,170,45,198,253,194,83,63,30,86, + 191,93,215,100,73,70,245,124,251,169,38,1,93,79,91,109,117,2,7,139, + 37,112,135,152,31,184,218,90,182,225,76,204,177,121,111,248,245,88,244,39, + 150,51,84,187,66,15,59,254,55,248,218,217,224,29,20,179,186,229,229,110, + 20,197,234,156,48,183,71,139,233,231,255,153,229,112,220,252,8,78,127,190, + 254,189,213,239,95,143,4,14,22,75,224,174,144,250,114,133,253,150,46,76, + 239,162,171,223,223,111,77,215,60,7,69,231,32,243,254,236,195,62,206,91, + 136,61,120,13,227,80,214,199,51,38,112,176,88,2,247,14,209,239,247,70, + 19,53,170,184,84,199,183,230,197,229,74,6,103,222,110,198,235,121,215,99, + 83,2,7,139,181,240,235,193,209,92,181,59,179,201,108,196,43,185,53,53, + 239,207,18,55,224,90,103,11,14,174,18,91,112,176,88,254,7,2,144,146, + 192,1,144,210,82,204,159,215,254,182,180,90,45,187,61,1,88,168,203,154, + 100,82,20,197,209,136,248,197,136,120,48,6,97,252,231,178,44,255,234,106, + 188,48,0,120,59,138,38,115,76,138,162,104,69,196,189,17,241,181,136,248, + 143,136,248,185,218,195,255,80,150,229,47,213,199,219,130,3,96,209,154,6, + 238,145,136,248,235,225,221,149,136,56,21,17,239,29,222,191,80,150,229,177, + 250,120,129,3,96,209,14,157,100,82,20,197,157,49,142,219,191,150,101,217, + 141,136,15,69,196,139,17,241,157,136,248,240,213,123,121,0,240,163,105,114, + 12,238,243,181,219,255,24,17,81,150,229,15,98,176,203,18,0,174,73,7, + 238,162,44,138,226,230,136,120,35,34,214,134,159,250,137,178,44,95,59,236, + 73,237,162,4,96,209,230,110,193,21,69,241,116,68,172,71,196,241,24,199, + 45,34,226,207,138,162,216,138,193,233,241,159,40,203,242,205,171,254,10,1, + 224,71,48,115,12,174,40,138,35,17,81,157,104,112,179,246,208,110,68,108, + 199,96,121,64,39,34,102,175,184,9,0,215,136,195,118,81,126,41,34,62, + 62,188,251,131,136,184,181,44,203,253,47,30,54,100,23,37,0,139,118,216, + 36,147,143,213,110,127,175,44,203,94,241,124,220,17,101,252,106,252,231,63, + 125,50,126,234,163,207,199,171,173,135,227,206,56,17,167,95,123,53,110,121, + 95,196,201,184,204,171,148,1,192,149,183,239,50,129,225,4,147,250,53,81, + 254,62,34,34,78,198,169,120,53,62,29,63,253,192,83,241,111,95,124,40, + 34,34,202,242,223,227,150,247,189,20,209,255,205,171,249,98,1,160,169,131, + 182,224,238,158,186,255,149,137,123,39,227,55,34,226,209,184,51,222,136,189, + 238,61,113,106,229,164,115,55,3,112,173,56,168,72,31,170,223,41,203,242, + 149,153,17,239,190,35,34,162,59,136,27,0,92,59,14,10,220,93,181,219, + 95,158,59,98,235,127,35,118,47,222,126,37,95,16,0,92,9,163,192,21, + 69,241,158,98,104,248,169,247,215,198,125,126,56,166,136,19,195,165,3,119, + 198,119,227,3,191,240,169,120,249,133,136,31,143,137,115,81,2,192,162,181, + 34,70,11,187,255,59,34,250,49,88,224,29,49,14,220,201,24,159,162,171, + 140,111,62,127,46,206,126,177,23,59,241,51,81,196,215,162,179,27,177,86, + 190,30,239,143,223,249,127,126,237,0,176,175,162,44,203,40,138,162,190,110, + 237,165,136,248,211,24,156,96,249,141,136,56,49,60,193,242,224,11,190,16, + 183,198,169,248,254,196,179,220,17,247,198,119,226,95,70,99,158,108,29,186, + 86,14,0,174,166,42,112,191,23,17,159,156,122,236,15,35,226,119,203,178, + 188,236,51,150,88,232,13,192,162,141,206,100,82,20,197,221,49,216,101,121, + 169,44,203,111,191,157,39,21,56,0,22,173,120,229,149,87,26,197,232,244, + 233,211,141,158,240,229,151,155,141,251,220,231,222,123,248,160,203,240,210,75, + 63,223,104,220,103,62,243,199,141,198,157,58,245,96,163,113,39,78,124,181, + 209,184,205,205,38,87,38,138,120,236,177,199,26,141,27,207,5,186,50,30, + 125,180,217,239,36,15,63,252,98,163,113,175,191,254,122,163,113,119,61,251, + 108,163,113,77,125,240,246,219,155,13,252,118,195,223,225,62,241,137,70,195, + 158,122,230,153,70,227,254,238,143,214,14,31,116,25,110,255,224,237,141,198, + 253,197,221,205,190,223,167,190,217,236,251,125,230,11,205,190,223,135,206,54, + 59,247,195,227,143,255,114,163,113,79,60,241,221,70,227,254,228,179,39,26, + 141,251,131,15,127,189,209,184,123,182,155,173,132,122,246,158,251,27,141,251, + 217,123,182,27,141,187,121,253,127,26,141,123,240,193,143,54,26,247,229,184, + 181,209,184,223,126,228,93,141,198,61,245,190,143,31,62,40,34,126,237,39, + 191,114,248,160,136,120,238,221,159,109,52,238,133,23,94,104,52,206,202,108, + 0,82,18,56,0,82,18,56,0,82,18,56,0,82,18,56,0,82,18,56, + 0,82,18,56,0,82,18,56,0,82,18,56,0,82,42,166,78,180,12,0, + 41,20,95,127,242,201,70,129,59,255,169,191,108,244,132,31,139,63,111,52, + 238,233,167,223,106,52,238,145,71,30,105,52,238,252,249,102,157,254,214,183, + 206,53,26,119,223,125,199,27,141,123,241,197,102,167,174,106,122,10,179,187, + 238,186,229,138,62,223,227,143,255,74,163,113,101,249,233,70,227,78,158,92, + 63,124,80,68,188,241,70,179,83,147,221,127,255,111,53,26,119,223,125,247, + 54,26,119,91,113,91,163,113,175,117,95,107,52,238,204,153,51,141,198,189, + 249,230,155,141,198,61,240,129,7,26,141,139,102,63,222,136,102,127,108,252, + 205,91,127,219,104,220,239,55,60,149,221,87,127,253,75,141,198,125,227,248, + 55,26,141,107,250,255,232,185,231,94,110,52,238,35,31,185,235,240,65,17, + 241,208,67,247,53,26,199,59,147,93,148,0,164,36,112,0,164,36,112,0, + 164,36,112,0,164,36,112,0,164,36,112,0,164,36,112,0,164,36,112,0, + 164,36,112,0,164,228,84,93,0,164,100,11,14,128,148,4,14,128,148,4, 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, - 14,128,148,4,14,128,148,4,14,128,148,92,170,11,128,148,204,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72,73,224,0,72, - 233,119,92,218,30,201,66,60,10,93,0,0,0,0,73,69,78,68,174,66, - 96,130, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,4, + 14,128,148,4,14,128,148,4,14,128,148,4,14,128,148,254,15,226,42,214, + 217,151,186,226,7,0,0,0,0,73,69,78,68,174,66,96,130, diff --git a/src/commands/CommandManager.cpp b/src/commands/CommandManager.cpp index 015022748..8c644405c 100644 --- a/src/commands/CommandManager.cpp +++ b/src/commands/CommandManager.cpp @@ -91,6 +91,7 @@ CommandManager. It holds the callback for one command. #include "CommandManager.h" #include "Keyboard.h" +#include "../PluginManager.h" #include "../effects/EffectManager.h" // On wxGTK, there may be many many many plugins, but the menus don't automatically @@ -1072,7 +1073,8 @@ bool CommandManager::HandleTextualCommand(wxString & Str, wxUint32 flags, wxUint unsigned int i; // Linear search for now... - for(i=0; imulti) { if( Str.IsSameAs( mCommandList[i]->name )) @@ -1086,23 +1088,23 @@ bool CommandManager::HandleTextualCommand(wxString & Str, wxUint32 flags, wxUint // instead we only try the effects. AudacityProject * proj = GetActiveProject(); if( !proj ) + { return false; - - bool result = false; - int effectFlags = ALL_EFFECTS | CONFIGURED_EFFECT; - EffectArray *effects = EffectManager::Get().GetEffects(effectFlags); - if (effects) { - for(i=0; iGetCount(); i++) { - wxString effectName = (*effects)[i]->GetEffectName(); - if( Str.IsSameAs( effectName )) - { - result = proj->OnEffect( effectFlags, (*effects)[i] ); - break; - } - } - delete effects; } - return result; + + PluginManager & pm = PluginManager::Get(); + EffectManager & em = EffectManager::Get(); + const PluginDescriptor *plug = pm.GetFirstPlugin(PluginTypeEffect); + while (plug) + { + if (em.GetEffectName(plug->GetID()).IsSameAs(Str)) + { + return proj->OnEffect( ALL_EFFECTS | CONFIGURED_EFFECT, plug->GetID()); + } + plug = pm.GetNextPlugin(PluginTypeEffect); + } + + return false; } void CommandManager::GetCategories(wxArrayString &cats) diff --git a/src/commands/CommandManager.h b/src/commands/CommandManager.h index 9fefe36fe..d1c61d0fb 100644 --- a/src/commands/CommandManager.h +++ b/src/commands/CommandManager.h @@ -20,6 +20,8 @@ #include "../AudacityApp.h" #include "../xml/XMLTagHandler.h" +#include "audacity/Types.h" + class AUDACITY_DLL_API CommandFunctor { public: diff --git a/src/commands/ScriptCommandRelay.cpp b/src/commands/ScriptCommandRelay.cpp index 01b4152d3..b326c8773 100644 --- a/src/commands/ScriptCommandRelay.cpp +++ b/src/commands/ScriptCommandRelay.cpp @@ -15,7 +15,7 @@ \class ScriptCommandRelay \brief ScriptCommandRelay is just a way to move some of the scripting-specific -code out of LoadModules. +code out of ModuleManager. *//*******************************************************************/ diff --git a/src/effects/Effect.cpp b/src/effects/Effect.cpp index 9b330e86e..2502af84b 100644 --- a/src/effects/Effect.cpp +++ b/src/effects/Effect.cpp @@ -30,6 +30,8 @@ greater use in future. #include #include +#include "audacity/ConfigInterface.h" + #include "Effect.h" #include "../AudioIO.h" #include "../Mix.h" @@ -63,24 +65,388 @@ wxString Effect::StripAmpersand(const wxString& str) // public methods // +// Legacy (or full blown effect) Effect::Effect() - : mWarper(NULL) { + CommonInit(); +} + +// Effect hosting an effect client +Effect::Effect(EffectClientInterface *client) +{ + CommonInit(); + + mClient = client; + mClient->SetHost(this); + mClient->Startup(); + + mNumAudioIn = mClient->GetAudioInCount(); + mNumAudioOut = mClient->GetAudioOutCount(); + + mInBuffer = NULL; + mOutBuffer = NULL; + mInBufPos = NULL; + mOutBufPos = NULL; + + mBufferSize = 0; + mBlockSize = 0; + mNumChannels = 0; + + int flags = PLUGIN_EFFECT; + switch (mClient->GetType()) + { + case EffectTypeGenerate: + flags |= INSERT_EFFECT; + break; + + case EffectTypeProcess: + flags |= PROCESS_EFFECT; + break; + + case EffectTypeAnalyze: + flags |= INSERT_EFFECT; + break; + } + + SetEffectFlags(flags); +} + +Effect::~Effect() +{ + if (mClient) + { + mClient->Shutdown(); + delete mClient; + } + + if (mWarper != NULL) + { + delete mWarper; + } +} + +void Effect::CommonInit() +{ + mClient = NULL; + + mWarper = NULL; + mTracks = NULL; mOutputTracks = NULL; mOutputTracksType = Track::None; mLength = 0; mNumTracks = 0; mNumGroups = 0; + mProgress = NULL; // Can change effect flags later (this is the new way) // OR using the old way, over-ride GetEffectFlags(). mFlags = BUILTIN_EFFECT | PROCESS_EFFECT | ADVANCED_EFFECT; } -Effect::~Effect() { - if (mWarper != NULL) - delete mWarper; +// EffectIdentInterface implementation + +EffectType Effect::GetType() +{ + if (mClient) + { + return mClient->GetType(); + } + + if (mFlags & HIDDEN_EFFECT) + { + return EffectTypeNone; + } + + if (mFlags & INSERT_EFFECT) + { + return EffectTypeGenerate; + } + + if (mFlags & PROCESS_EFFECT) + { + return EffectTypeProcess; + } + + if (mFlags & ANALYZE_EFFECT) + { + return EffectTypeAnalyze; + } + + wxASSERT( true ); + + return EffectTypeNone; +} + +PluginID Effect::GetID() +{ + if (mClient) + { + return mClient->GetID(); + } + + return wxString::Format(wxT("LEGACY_EFFECT_ID_%d"), GetEffectID()); +} + +wxString Effect::GetPath() +{ + if (mClient) + { + return mClient->GetPath(); + } + + return wxEmptyString; +} + +wxString Effect::GetName() +{ + if (mClient) + { + return mClient->GetName(); + } + + return GetEffectName(); +} + +wxString Effect::GetVendor() +{ + if (mClient) + { + return mClient->GetVendor(); + } + + return wxEmptyString; +} + +wxString Effect::GetVersion() +{ + if (mClient) + { + return mClient->GetVersion(); + } + + return wxT("Various"); +} + +wxString Effect::GetDescription() +{ + if (mClient) + { + return mClient->GetDescription(); + } + + return GetEffectIdentifier(); +} + +wxString Effect::GetFamily() +{ + if (mClient) + { + return mClient->GetFamily(); + } + + return wxT("Legacy"); +} + +bool Effect::IsDefault() +{ + if (mClient) + { + return mClient->IsDefault(); + } + + return (mFlags & BUILTIN_EFFECT) != 0; +} + +bool Effect::IsLegacy() +{ + if (mClient) + { + return false; + } + + return true; +} + +bool Effect::IsInteractive() +{ + if (mClient) + { + return mClient->IsInteractive(); + } + + return GetEffectName().EndsWith(wxT("...")); +} + +// EffectHostInterface implementation + +bool Effect::Apply() +{ + GetActiveProject()->OnEffect(GetID(), true); + + return true; +} + +void Effect::Preview() +{ + Preview(false); +} + +// ConfigClientInterface implementation + +bool Effect::GetSharedConfig(const wxString & group, const wxString & key, wxString & value, const wxString & defval) +{ + return PluginManager::Get().GetSharedConfig(GetID(), group, key, value, defval); +} + +bool Effect::GetSharedConfig(const wxString & group, const wxString & key, int & value, int defval) +{ + return PluginManager::Get().GetSharedConfig(GetID(), group, key, value, defval); +} + +bool Effect::GetSharedConfig(const wxString & group, const wxString & key, bool & value, bool defval) +{ + return PluginManager::Get().GetSharedConfig(GetID(), group, key, value, defval); +} + +bool Effect::GetSharedConfig(const wxString & group, const wxString & key, float & value, float defval) +{ + return PluginManager::Get().GetSharedConfig(GetID(), group, key, value, defval); +} + +bool Effect::GetSharedConfig(const wxString & group, const wxString & key, double & value, double defval) +{ + return PluginManager::Get().GetSharedConfig(GetID(), group, key, value, defval); +} + +bool Effect::GetSharedConfig(const wxString & group, const wxString & key, sampleCount & value, sampleCount defval) +{ + return PluginManager::Get().GetSharedConfig(GetID(), group, key, value, defval); +} + +bool Effect::SetSharedConfig(const wxString & group, const wxString & key, const wxString & value) +{ + return PluginManager::Get().SetSharedConfig(GetID(), group, key, value); +} + +bool Effect::SetSharedConfig(const wxString & group, const wxString & key, const int & value) +{ + return PluginManager::Get().SetSharedConfig(GetID(), group, key, value); +} + +bool Effect::SetSharedConfig(const wxString & group, const wxString & key, const bool & value) +{ + return PluginManager::Get().SetSharedConfig(GetID(), group, key, value); +} + +bool Effect::SetSharedConfig(const wxString & group, const wxString & key, const float & value) +{ + return PluginManager::Get().SetSharedConfig(GetID(), group, key, value); +} + +bool Effect::SetSharedConfig(const wxString & group, const wxString & key, const double & value) +{ + return PluginManager::Get().SetSharedConfig(GetID(), group, key, value); +} + +bool Effect::SetSharedConfig(const wxString & group, const wxString & key, const sampleCount & value) +{ + return PluginManager::Get().SetSharedConfig(GetID(), group, key, value); +} + +bool Effect::GetPrivateConfig(const wxString & group, const wxString & key, wxString & value, const wxString & defval) +{ + return PluginManager::Get().GetPrivateConfig(GetID(), group, key, value, defval); +} + +bool Effect::GetPrivateConfig(const wxString & group, const wxString & key, int & value, int defval) +{ + return PluginManager::Get().GetPrivateConfig(GetID(), group, key, value, defval); +} + +bool Effect::GetPrivateConfig(const wxString & group, const wxString & key, bool & value, bool defval) +{ + return PluginManager::Get().GetPrivateConfig(GetID(), group, key, value, defval); +} + +bool Effect::GetPrivateConfig(const wxString & group, const wxString & key, float & value, float defval) +{ + return PluginManager::Get().GetPrivateConfig(GetID(), group, key, value, defval); +} + +bool Effect::GetPrivateConfig(const wxString & group, const wxString & key, double & value, double defval) +{ + return PluginManager::Get().GetPrivateConfig(GetID(), group, key, value, defval); +} + +bool Effect::GetPrivateConfig(const wxString & group, const wxString & key, sampleCount & value, sampleCount defval) +{ + return PluginManager::Get().GetPrivateConfig(GetID(), group, key, value, defval); +} + +bool Effect::SetPrivateConfig(const wxString & group, const wxString & key, const wxString & value) +{ + return PluginManager::Get().SetPrivateConfig(GetID(), group, key, value); +} + +bool Effect::SetPrivateConfig(const wxString & group, const wxString & key, const int & value) +{ + return PluginManager::Get().SetPrivateConfig(GetID(), group, key, value); +} + +bool Effect::SetPrivateConfig(const wxString & group, const wxString & key, const bool & value) +{ + return PluginManager::Get().SetPrivateConfig(GetID(), group, key, value); +} + +bool Effect::SetPrivateConfig(const wxString & group, const wxString & key, const float & value) +{ + return PluginManager::Get().SetPrivateConfig(GetID(), group, key, value); +} + +bool Effect::SetPrivateConfig(const wxString & group, const wxString & key, const double & value) +{ + return PluginManager::Get().SetPrivateConfig(GetID(), group, key, value); +} + +bool Effect::SetPrivateConfig(const wxString & group, const wxString & key, const sampleCount & value) +{ + return PluginManager::Get().SetPrivateConfig(GetID(), group, key, value); +} + +// Effect implementation + +// All legacy effects should have this overridden +wxString Effect::GetEffectName() +{ + if (mClient) + { + return mClient->GetName(); + } + + return wxT("DummyIdentifier"); +} + +// All legacy effects should have this overridden +wxString Effect::GetEffectIdentifier() +{ + if (mClient) + { + return mClient->GetName(); + } + + return wxT("DummyIdentifier"); +} + +// All legacy effects should have this overridden +wxString Effect::GetEffectAction() +{ + if (mClient) + { + return _("Applying ") + mClient->GetName(); + } + + return wxT("DummyName"); } bool Effect::DoEffect(wxWindow *parent, int flags, @@ -93,7 +459,8 @@ bool Effect::DoEffect(wxWindow *parent, int flags, double t1 = selectedRegion->t1(); wxASSERT(t0 <= t1); - if (mOutputTracks) { + if (mOutputTracks) + { delete mOutputTracks; mOutputTracks = NULL; } @@ -119,7 +486,9 @@ bool Effect::DoEffect(wxWindow *parent, int flags, // Note: Init may read parameters from preferences if (!Init()) + { return false; + } // If a parameter string was provided, it overrides any remembered settings // (but if the user is to be prompted, that takes priority) @@ -144,51 +513,529 @@ bool Effect::DoEffect(wxWindow *parent, int flags, // Don't prompt user if we are dealing with a // effect that is already configured, e.g. repeating // the last effect on a different selection. - if( (flags & CONFIGURED_EFFECT) == 0) + if ((flags & CONFIGURED_EFFECT) == 0) { if (!PromptUser()) + { return false; + } } bool returnVal = true; bool skipFlag = CheckWhetherSkipEffect(); - if (skipFlag == false) { + if (skipFlag == false) + { mProgress = new ProgressDialog(StripAmpersand(GetEffectName()), GetEffectAction(), pdlgHideStopButton); returnVal = Process(); delete mProgress; + mProgress = NULL; } End(); - if (mOutputTracks) { + if (mOutputTracks) + { delete mOutputTracks; mOutputTracks = NULL; } - if (returnVal) { + if (returnVal) + { selectedRegion->setTimes(mT0, mT1); } return returnVal; } +// All legacy effects should have this overridden +bool Effect::Init() +{ + return true; +} + +bool Effect::PromptUser() +{ + return PromptUser(mParent); +} + +bool Effect::PromptUser(wxWindow *parent) +{ + if (mClient) + { +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + if (IsRealtimeCapable()) + { + mClient->ShowInterface(parent); + return false; + } +#endif + + return mClient->ShowInterface(parent); + } + + return true; +} + +// All legacy effects should have this overridden +bool Effect::Process() +{ + if (!mClient) + { + return false; + } + + CopyInputTracks(); + bool bGoodResult = true; + + mInBuffer = NULL; + mOutBuffer = NULL; + + sampleCount prevBufferSize = 0; + mBufferSize = 0; + mBlockSize = 0; + + TrackListIterator iter(mOutputTracks); + int count = 0; + bool clear = false; + WaveTrack *left = (WaveTrack *) iter.First(); + while (left) + { + WaveTrack *right; + sampleCount len; + sampleCount leftStart; + sampleCount rightStart; + + GetSamples(left, &leftStart, &len); + + mNumChannels = 1; + + right = NULL; + rightStart = 0; + if (left->GetLinked() && mNumAudioIn > 1) + { + right = (WaveTrack *) iter.Next(); + GetSamples(right, &rightStart, &len); + clear = false; + mNumChannels = 2; + } + + // Let the client know the sample rate + mClient->SetSampleRate(left->GetRate()); + + // Get the block size the client wants to use + sampleCount max = left->GetMaxBlockSize() * 2; + mBlockSize = mClient->GetBlockSize(max); + + // Calculate the buffer size to be at least the max rounded up to the clients + // selected block size. + prevBufferSize = mBufferSize; + mBufferSize = ((max + (mBlockSize - 1)) / mBlockSize) * mBlockSize; + + // If the buffer size has changed, then (re)allocate the buffers + if (prevBufferSize != mBufferSize) + { + // Get rid of any previous buffers + if (mInBuffer) + { + for (int i = 0; i < mNumAudioIn; i++) + { + if (mInBuffer[i]) + { + delete [] mInBuffer[i]; + } + } + delete [] mInBuffer; + delete [] mInBufPos; + } + + // Always create the number of input buffers the client expects even if we don't have + // the same number of channels. + mInBufPos = new float *[mNumAudioIn]; + mInBuffer = new float *[mNumAudioIn]; + for (int i = 0; i < mNumAudioIn; i++) + { + mInBuffer[i] = new float[mBufferSize]; + } + + // We won't be using more than the first 2 buffers, so clear the rest (if any) + for (int i = 2; i < mNumAudioIn; i++) + { + for (int j = 0; j < mBufferSize; j++) + { + mInBuffer[i][j] = 0.0; + } + } + + // Get rid of any previous buffers + if (mOutBuffer) + { + for (int i = 0; i < mNumAudioOut; i++) + { + if (mOutBuffer[i]) + { + delete [] mOutBuffer[i]; + } + } + delete [] mOutBuffer; + delete [] mOutBufPos; + } + + // Always create the number of output buffers the client expects even if we don't have + // the same number of channels. + mOutBufPos = new float *[mNumAudioOut]; + mOutBuffer = new float *[mNumAudioOut]; + for (int i = 0; i < mNumAudioOut; i++) + { + // Output buffers get an extra mBlockSize worth to give extra room if + // the plugin adds latency + mOutBuffer[i] = new float[mBufferSize + mBlockSize]; + } + } + + // (Re)Set the input buffer positions + for (int i = 0; i < mNumAudioIn; i++) + { + mInBufPos[i] = mInBuffer[i]; + } + + // (Re)Set the output buffer positions + for (int i = 0; i < mNumAudioOut; i++) + { + mOutBufPos[i] = mOutBuffer[i]; + } + + // Clear unused input buffers + if (!right && !clear && mNumAudioIn > 1) + { + for (int j = 0; j < mBufferSize; j++) + { + mInBuffer[1][j] = 0.0; + } + clear = true; + } + + // Go process the track(s) + bGoodResult = ProcessTrack(count, left, right, leftStart, rightStart, len); + if (!bGoodResult) + { + break; + } + + left = (WaveTrack *) iter.Next(); + count++; + } + + if (mOutBuffer) + { + for (int i = 0; i < mNumAudioOut; i++) + { + delete [] mOutBuffer[i]; + } + delete [] mOutBuffer; + delete [] mOutBufPos; + mOutBuffer = NULL; + mOutBufPos = NULL; + } + + if (mInBuffer) + { + for (int i = 0; i < mNumAudioIn; i++) + { + delete [] mInBuffer[i]; + } + delete [] mInBuffer; + delete [] mInBufPos; + mInBuffer = NULL; + mInBufPos = NULL; + } + + ReplaceProcessedTracks(bGoodResult); + + return bGoodResult; +} + +bool Effect::ProcessTrack(int count, + WaveTrack *left, + WaveTrack *right, + sampleCount leftStart, + sampleCount rightStart, + sampleCount len) +{ + bool rc = true; + + // Give the plugin a chance to initialize + mClient->ProcessInitialize(); + + // For each input block of samples, we pass it to the effect along with a + // variable output location. This output location is simply a pointer into a + // much larger buffer. This reduces the number of calls required to add the + // samples to the output track. + // + // Upon return from the effect, the output samples are "moved to the left" by + // the number of samples in the current latency setting, effectively removing the + // delay introduced by the effect. + // + // At the same time the total number of delayed samples are gathered and when the + // there is no further input data to process, the loop continues to call the + // effect with an empty input buffer until the effect has had a chance to + // return all of the remaining delayed samples. + sampleCount inLeftPos = leftStart; + sampleCount inRightPos = rightStart; + sampleCount outLeftPos = leftStart; + sampleCount outRightPos = rightStart; + + sampleCount inputRemaining = len; + sampleCount delayRemaining = 0; + sampleCount curBlockSize = 0; + sampleCount curDelay = 0; + + sampleCount inputBufferCnt = 0; + sampleCount outputBufferCnt = 0; + bool cleared = false; + + // Call the effect until we run out of input or delayed samples + while (inputRemaining || delayRemaining) + { + // Still working on the input samples + if (inputRemaining) + { + // Need to refill the input buffers + if (inputBufferCnt == 0) + { + // Calculate the number of samples to get + inputBufferCnt = mBufferSize; + if (inputBufferCnt > inputRemaining) + { + inputBufferCnt = inputRemaining; + } + + // Fill the input buffers + left->Get((samplePtr) mInBuffer[0], floatSample, inLeftPos, inputBufferCnt); + if (right) + { + right->Get((samplePtr) mInBuffer[1], floatSample, inRightPos, inputBufferCnt); + } + + // Reset the input buffer positions + for (int i = 0; i < mNumChannels; i++) + { + mInBufPos[i] = mInBuffer[i]; + } + } + + // Calculate the number of samples to process + curBlockSize = mBlockSize; + if (curBlockSize > inputRemaining) + { + // We've reached the last block...set current block size to what's left + curBlockSize = inputRemaining; + inputRemaining = 0; + + // Clear the remainder of the buffers so that a full block can be passed + // to the effect + sampleCount cnt = mBlockSize - curBlockSize; + for (int i = 0; i < mNumChannels; i++) + { + for (int j = 0 ; j < cnt; j++) + { + mInBufPos[i][j + curBlockSize] = 0.0; + } + } + + // Might be able to use up some of the delayed samples + if (delayRemaining) + { + // Don't use more than needed + if (delayRemaining < cnt) + { + cnt = delayRemaining; + } + delayRemaining -= cnt; + curBlockSize += cnt; + } + } + } + // We've exhausted the input samples and are now working on the delay + else if (delayRemaining) + { + // Calculate the number of samples to process + curBlockSize = mBlockSize; + if (curBlockSize > delayRemaining) + { + curBlockSize = delayRemaining; + } + delayRemaining -= curBlockSize; + + // From this point on, we only want to feed zeros to the plugin + if (!cleared) + { + // Reset the input buffer positions + for (int i = 0; i < mNumChannels; i++) + { + mInBufPos[i] = mInBuffer[i]; + + // And clear + for (int j = 0; j < mBlockSize; j++) + { + mInBuffer[i][j] = 0.0; + } + } + cleared = true; + } + } + + // Finally call the plugin to process the block + try + { + mClient->ProcessBlock(mInBufPos, mOutBufPos, curBlockSize); + } + catch(...) + { + return false; + } + + // Bump to next input buffer position + if (inputRemaining) + { + for (int i = 0; i < mNumChannels; i++) + { + mInBufPos[i] += curBlockSize; + } + inputRemaining -= curBlockSize; + inputBufferCnt -= curBlockSize; + } + + // Get the current number of delayed samples and accumulate + sampleCount delay = mClient->GetLatency(); + curDelay += delay; + delayRemaining += delay; + + // If the plugin has delayed the output by more samples than our current + // block size, then we leave the output pointers alone. This effectively + // removes those delayed samples from the output buffer. + if (curDelay >= curBlockSize) + { + curDelay -= curBlockSize; + curBlockSize = 0; + } + // We have some delayed samples, at the beginning of the output samples, + // so overlay them by shifting the remaining output samples. + else if (curDelay > 0) + { + curBlockSize -= curDelay; + for (int i = 0; i < mNumChannels; i++) + { + memmove(mOutBufPos[i], mOutBufPos[i] + curDelay, SAMPLE_SIZE(floatSample) * curBlockSize); + } + curDelay = 0; + } + + // + outputBufferCnt += curBlockSize; + + // + if (outputBufferCnt < mBufferSize) + { + // Bump to next output buffer position + for (int i = 0; i < mNumChannels; i++) + { + mOutBufPos[i] += curBlockSize; + } + } + // Output buffers have filled + else + { + // Write them out + left->Set((samplePtr) mOutBuffer[0], floatSample, outLeftPos, outputBufferCnt); + if (right) + { + right->Set((samplePtr) mOutBuffer[1], floatSample, outRightPos, outputBufferCnt); + } + + // Reset the output buffer positions + for (int i = 0; i < mNumChannels; i++) + { + mOutBufPos[i] = mOutBuffer[i]; + } + + // Bump to the next track position + outLeftPos += outputBufferCnt; + outRightPos += outputBufferCnt; + outputBufferCnt = 0; + } + + // "ls" and "rs" serve as the input sample index for the left and + // right channels when processing the input samples. If we flip + // over to processing delayed samples, the simply become counters + // for the progress display. + inLeftPos += curBlockSize; + inRightPos += curBlockSize; + + if (mNumChannels > 1) + { + if (TrackGroupProgress(count, (inLeftPos - leftStart) / (double) len)) + { + rc = false; + break; + } + } + else + { + if (TrackProgress(count, (inLeftPos - leftStart) / (double) len)) + { + rc = false; + break; + } + } + } + + // Put any remaining output + if (outputBufferCnt) + { + left->Set((samplePtr) mOutBuffer[0], floatSample, outLeftPos, outputBufferCnt); + if (right) + { + right->Set((samplePtr) mOutBuffer[1], floatSample, outRightPos, outputBufferCnt); + } + } + + // Allow the plugin to cleanup + mClient->ProcessFinalize(); + + return rc; +} + +void Effect::End() +{ + if (mClient) + { + mClient->Shutdown(); + } +} + bool Effect::TotalProgress(double frac) { - int updateResult = mProgress->Update(frac); + int updateResult = (mProgress ? + mProgress->Update(frac) : + eProgressSuccess); return (updateResult != eProgressSuccess); } bool Effect::TrackProgress(int whichTrack, double frac, wxString msg) { - int updateResult = mProgress->Update(whichTrack + frac, (double) mNumTracks, msg); + int updateResult = (mProgress ? + mProgress->Update(whichTrack + frac, (double) mNumTracks, msg) : + eProgressSuccess); return (updateResult != eProgressSuccess); } bool Effect::TrackGroupProgress(int whichGroup, double frac) { - int updateResult = mProgress->Update(whichGroup + frac, (double) mNumGroups); + int updateResult = (mProgress ? + mProgress->Update(whichGroup + frac, (double) mNumGroups) : + eProgressSuccess); return (updateResult != eProgressSuccess); } @@ -199,7 +1046,7 @@ void Effect::GetSamples(WaveTrack *track, sampleCount *start, sampleCount *len) double t0 = mT0 < trackStart ? trackStart : mT0; double t1 = mT1 > trackEnd ? trackEnd : mT1; - if (mFlags & INSERT_EFFECT) { + if (GetType() & INSERT_EFFECT) { t1 = t0 + mLength; if (mT0 == mT1) { // Not really part of the calculation, but convenient to put here @@ -256,8 +1103,8 @@ void Effect::CopyInputTracks(int trackType) TrackListOfKindIterator aIt(trackType, mTracks); t2bHash added; - for (Track *aTrack = aIt.First(); aTrack; aTrack = aIt.Next()) { - + for (Track *aTrack = aIt.First(); aTrack; aTrack = aIt.Next()) + { // Include selected tracks, plus sync-lock selected tracks for Track::All. if (aTrack->GetSelected() || (trackType == Track::All && aTrack->IsSyncLockSelected())) @@ -427,6 +1274,119 @@ wxString Effect::GetPreviewName() return _("Pre&view"); } +bool Effect::IsRealtimeCapable() +{ +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + if (mClient) + { + return mClient->IsRealtimeCapable(); + } +#endif + + return false; +} + +bool Effect::RealtimeInitialize(int numChannels, float sampleRate) +{ +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + if (mClient) + { + mNumChannels = numChannels; + return mClient->RealtimeInitialize(numChannels, sampleRate); + } +#endif + + return false; +} + +bool Effect::RealtimeFinalize() +{ +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + if (mClient) + { + return mClient->RealtimeFinalize(); + } +#endif + + return false; +} + +bool Effect::RealtimeSuspend() +{ +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + if (mClient) + { + return mClient->RealtimeSuspend(); + } +#endif + + return false; +} + +bool Effect::RealtimeResume() +{ +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + if (mClient) + { + return mClient->RealtimeResume(); + } +#endif + + return false; +} + +sampleCount Effect::RealtimeProcess(float **inbuf, float **outbuf, sampleCount size) +{ +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + float **tin = inbuf; + if (mNumAudioIn > mNumChannels) + { + float *dummybuf = (float *) alloca(size * sizeof(float)); + tin = (float **) alloca(mNumAudioIn * sizeof(float *)); + for (int i = 0; i < mNumChannels; i++) + { + tin[i] = inbuf[i]; + } + for (int i = mNumChannels; i < mNumAudioIn; i++) + { + tin[i] = dummybuf; + } + for (int i = 0; i < size; i++) + { + dummybuf[i] = 0.0; + } + } + + float **tout = outbuf; + if (mNumAudioOut > mNumChannels) + { + float *dummybuf = (float *) alloca(size * sizeof(float)); + tout = (float **) alloca(mNumAudioOut * sizeof(float *)); + for (int i = 0; i < mNumChannels; i++) + { + tout[i] = outbuf[i]; + } + for (int i = mNumChannels; i < mNumAudioOut; i++) + { + tout[i] = dummybuf; + } + for (int i = 0; i < size; i++) + { + dummybuf[i] = 0.0; + } + } + + // Finally call the plugin to process the block + // LLL FIXME + // If the number of channels is greater than the number of in/out the effect + // can handle, then call RealtimeProcess for each "set" of tracks over its + // capabilities. + return mClient->RealtimeProcess(tin, tout, size); +#else + return 0; +#endif +} + void Effect::Preview(bool dryOnly) { if (mNumTracks==0) // nothing to preview @@ -495,6 +1455,7 @@ void Effect::Preview(bool dryOnly) pdlgHideCancelButton); // Have only "Stop" button. bSuccess = Process(); delete mProgress; + mProgress = NULL; End(); Init(); } @@ -545,6 +1506,7 @@ void Effect::Preview(bool dryOnly) } delete mProgress; + mProgress = NULL; } else { wxMessageBox(_("Error while opening sound device. Please check the playback device settings and the project sample rate."), diff --git a/src/effects/Effect.h b/src/effects/Effect.h index 4684c034e..67aa36fa0 100644 --- a/src/effects/Effect.h +++ b/src/effects/Effect.h @@ -21,6 +21,9 @@ class wxDialog; class wxWindow; +#include "audacity/ConfigInterface.h" +#include "audacity/EffectInterface.h" + #include "../Experimental.h" #include "../WaveTrack.h" #include "../Shuttle.h" @@ -59,7 +62,8 @@ class TimeWarper; //and so can just drop the steps we don't want? #define SKIP_EFFECT_MILLISECOND 99999 -class AUDACITY_DLL_API Effect { +class AUDACITY_DLL_API Effect : public EffectHostInterface +{ // // public methods // @@ -67,10 +71,71 @@ class AUDACITY_DLL_API Effect { // apply the effect to one or more tracks. // public: + // The constructor is called once by each subclass at the beginning of the program. + // Avoid allocating memory or doing time-consuming processing here. + Effect(); + Effect(EffectClientInterface *client); + virtual ~Effect(); + + // IdentInterface implementation + + virtual PluginID GetID(); + virtual wxString GetPath(); + virtual wxString GetName(); + virtual wxString GetVendor(); + virtual wxString GetVersion(); + virtual wxString GetDescription(); + + // EffectIdentInterface implementation + + virtual EffectType GetType(); + virtual wxString GetFamily(); + virtual bool IsInteractive(); + virtual bool IsDefault(); + virtual bool IsLegacy(); + virtual bool IsRealtimeCapable(); + + // EffectHostInterface implementation + + virtual bool Apply(); + virtual void Preview(); + + // ConfigClientInterface implementation + + virtual bool GetSharedConfig(const wxString & group, const wxString & key, wxString & value, const wxString & defval = wxEmptyString); + virtual bool GetSharedConfig(const wxString & group, const wxString & key, int & value, int defval = 0); + virtual bool GetSharedConfig(const wxString & group, const wxString & key, bool & value, bool defval = false); + virtual bool GetSharedConfig(const wxString & group, const wxString & key, float & value, float defval = 0.0); + virtual bool GetSharedConfig(const wxString & group, const wxString & key, double & value, double defval = 0.0); + virtual bool GetSharedConfig(const wxString & group, const wxString & key, sampleCount & value, sampleCount defval = 0); + + virtual bool SetSharedConfig(const wxString & group, const wxString & key, const wxString & value); + virtual bool SetSharedConfig(const wxString & group, const wxString & key, const int & value); + virtual bool SetSharedConfig(const wxString & group, const wxString & key, const bool & value); + virtual bool SetSharedConfig(const wxString & group, const wxString & key, const float & value); + virtual bool SetSharedConfig(const wxString & group, const wxString & key, const double & value); + virtual bool SetSharedConfig(const wxString & group, const wxString & key, const sampleCount & value); + + virtual bool GetPrivateConfig(const wxString & group, const wxString & key, wxString & value, const wxString & defval = wxEmptyString); + virtual bool GetPrivateConfig(const wxString & group, const wxString & key, int & value, int defval = 0); + virtual bool GetPrivateConfig(const wxString & group, const wxString & key, bool & value, bool defval = false); + virtual bool GetPrivateConfig(const wxString & group, const wxString & key, float & value, float defval = 0.0); + virtual bool GetPrivateConfig(const wxString & group, const wxString & key, double & value, double defval = 0.0); + virtual bool GetPrivateConfig(const wxString & group, const wxString & key, sampleCount & value, sampleCount defval = 0); + + virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const wxString & value); + virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const int & value); + virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const bool & value); + virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const float & value); + virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const double & value); + virtual bool SetPrivateConfig(const wxString & group, const wxString & key, const sampleCount & value); + + // Effect implementation + // Each subclass of Effect should override this method. // This name will go in the menu bar; // append "..." if your effect pops up a dialog - virtual wxString GetEffectName() = 0; + virtual wxString GetEffectName(); // Each subclass of Effect should override this method. // This should return the category of this effect, which @@ -82,7 +147,7 @@ class AUDACITY_DLL_API Effect { // Previously optional. Now required to identify effects for Chain support. // Each subclass of Effect should override this method. // This should be human-readable, but should NOT be translated. Use wxT(""), not _(""). - virtual wxString GetEffectIdentifier() = 0; + virtual wxString GetEffectIdentifier(); // Each subclass of Effect should override this method. // This name will go in the progress dialog, but can be used @@ -90,7 +155,7 @@ class AUDACITY_DLL_API Effect { // For example, if the effect is "Filter", the action is // "Filtering", or if the effect is "Bass Boost", the action // is "Boosting Bass Frequencies". - virtual wxString GetEffectAction() = 0; + virtual wxString GetEffectAction(); // Each subclass of Effect should override this method. // This description will go in the History state. @@ -133,7 +198,7 @@ class AUDACITY_DLL_API Effect { // The Effect class fully implements the Preview method for you. // Only override it if you need to do preprocessing or cleanup. - virtual void Preview(bool dryOnly = false); + virtual void Preview(bool dryOnly); // Most effects just use the previewLength, but time-stretching/compressing // effects need to use a different input length, so override this method. @@ -141,8 +206,13 @@ class AUDACITY_DLL_API Effect { // Get an unique ID assigned to each registered effect. // The first effect will have ID zero. - int GetID() { - return mID; + int GetEffectID() { + return mEffectID; + } + + // Set an unique ID assigned to each registered effect. + void SetEffectID(int id) { + mEffectID = id; } // Returns true on success. Will only operate on tracks that @@ -163,6 +233,13 @@ class AUDACITY_DLL_API Effect { // important for sorting. static wxString StripAmpersand(const wxString& str); + // Realtime Effect Processing + bool RealtimeInitialize(int numChannels, float sampleRate); + bool RealtimeFinalize(); + bool RealtimeSuspend(); + bool RealtimeResume(); + sampleCount RealtimeProcess(float **inbuf, float **outbuf, sampleCount size); + // // protected virtual methods // @@ -170,26 +247,18 @@ class AUDACITY_DLL_API Effect { // do its processing. // protected: - // The constructor is called once by each subclass at the beginning of the program. - // Avoid allocating memory or doing time-consuming processing here. - Effect(); - - virtual ~Effect(); - // Called once each time an effect is called. Perform any initialization; // make sure that the effect can be performed on the selected tracks and // return false otherwise - virtual bool Init() { - return true; - } + virtual bool Init(); // If necessary, open a dialog to get parameters from the user. // This method will not always be called (for example if a user // repeats an effect) but if it is called, it will be called // after Init. - virtual bool PromptUser() { - return true; - } + virtual bool PromptUser(); + virtual bool PromptUser(wxWindow *parent); + // Check whether effect should be skipped // Typically this is only useful in automation, for example // detecting that zero noise reduction is to be done, @@ -198,12 +267,10 @@ class AUDACITY_DLL_API Effect { virtual bool CheckWhetherSkipEffect() { return false; } // Actually do the effect here. - virtual bool Process() = 0; + virtual bool Process(); // clean up any temporary memory - virtual void End() { - } - + virtual void End(); // // protected data @@ -293,8 +360,17 @@ class AUDACITY_DLL_API Effect { // Used only by the base Effect class // private: + void CommonInit(); void CountWaveTracks(); + // Driver for client effects + bool ProcessTrack(int count, + WaveTrack *left, + WaveTrack *right, + sampleCount leftStart, + sampleCount rightStart, + sampleCount len); + // // private data // @@ -307,14 +383,26 @@ class AUDACITY_DLL_API Effect { int mNumTracks; //v This is really mNumWaveTracks, per CountWaveTracks() and GetNumWaveTracks(). int mNumGroups; - int mID; + int mEffectID; - friend class BatchCommands;// so can call PromptUser. - friend class EffectManager;// so it can delete effects and access mID. + // For client driver + EffectClientInterface *mClient; + int mNumAudioIn; + int mNumAudioOut; + float **mInBuffer; + float **mOutBuffer; + float **mInBufPos; + float **mOutBufPos; + + sampleCount mBufferSize; + sampleCount mBlockSize; + int mNumChannels; + + friend class EffectManager;// so it can call PromptUser in support of batch commands. + friend class EffectRack; }; - // Base dialog for generate effect #define ID_EFFECT_PREVIEW ePreviewID @@ -350,4 +438,3 @@ double TrapDouble(double x, double min, double max); long TrapLong(long x, long min, long max); #endif - diff --git a/src/effects/EffectManager.cpp b/src/effects/EffectManager.cpp index 995afa329..51b3dc154 100644 --- a/src/effects/EffectManager.cpp +++ b/src/effects/EffectManager.cpp @@ -9,28 +9,183 @@ **********************************************************************/ -#include +#include +#include + +#include "../Experimental.h" + +#if defined(EXPERIMENTAL_EFFECTS_RACK) +#include "EffectRack.h" +#endif #include "EffectManager.h" - +// ============================================================================ // -// Initialisations for static class members +// Create singleton and return reference // - -EffectManager& EffectManager::Get() { +// (Thread-safe...no active threading during construction or after destruction) +// ============================================================================ +EffectManager & EffectManager::Get() +{ static EffectManager em; return em; } - EffectManager::EffectManager() -: mNumEffects(0) { #ifdef EFFECT_CATEGORIES mCategories = new CategoryMap(); mRootCategories = new CategorySet(); mUnsorted = new EffectSet(); + + // Create effect category graph. These categories and relationships + // are taken from revision 2 of lv2.ttl, loaders for other plugin systems + // (such as LADSPA/LRDF) should map their categories to these ones when + // applicable. Individual LADSPA/LRDF and LV2 plugins can add new + // categories and make them subcategories of the existing ones, but not + // add subcategory relationships between these categories. + // + // We need some persistent, global identifiers for categories - LRDF + // and LV2 uses URI strings so we do that too. The URIs here are the + // same ones as in lv2.ttl. Category identifiers in other plugin systems + // must be mapped to URIs by their loaders. + +#define LV2PREFIX "http://lv2plug.in/ns/lv2core#" + + typedef EffectCategory* CatPtr; + + CatPtr gen = AddCategory(wxT(LV2PREFIX) wxT("GeneratorPlugin"), + _("Generator")); + CatPtr inst = AddCategory(wxT(LV2PREFIX) wxT("InstrumentPlugin"), + /* i18n-hint: (noun).*/ + _("Instrument")); + CatPtr osc = AddCategory(wxT(LV2PREFIX) wxT("OscillatorPlugin"), + _("Oscillator")); + CatPtr util = AddCategory(wxT(LV2PREFIX) wxT("UtilityPlugin"), + _("Utility")); + CatPtr conv = AddCategory(wxT(LV2PREFIX) wxT("ConverterPlugin"), + _("Converter")); + CatPtr anal = AddCategory(wxT(LV2PREFIX) wxT("AnalyserPlugin"), + _("Analyser")); + CatPtr mix = AddCategory(wxT(LV2PREFIX) wxT("MixerPlugin"), + _("Mixer")); + CatPtr sim = AddCategory(wxT(LV2PREFIX) wxT("SimulatorPlugin"), + _("Simulator")); + CatPtr del = AddCategory(wxT(LV2PREFIX) wxT("DelayPlugin"), + _("Delay")); + CatPtr mod = AddCategory(wxT(LV2PREFIX) wxT("ModulatorPlugin"), + _("Modulator")); + CatPtr rev = AddCategory(wxT(LV2PREFIX) wxT("ReverbPlugin"), + _("Reverb")); + CatPtr phas = AddCategory(wxT(LV2PREFIX) wxT("PhaserPlugin"), + _("Phaser")); + CatPtr flng = AddCategory(wxT(LV2PREFIX) wxT("FlangerPlugin"), + _("Flanger")); + CatPtr chor = AddCategory(wxT(LV2PREFIX) wxT("ChorusPlugin"), + _("Chorus")); + CatPtr flt = AddCategory(wxT(LV2PREFIX) wxT("FilterPlugin"), + _("Filter")); + CatPtr lp = AddCategory(wxT(LV2PREFIX) wxT("LowpassPlugin"), + _("Lowpass")); + CatPtr bp = AddCategory(wxT(LV2PREFIX) wxT("BandpassPlugin"), + _("Bandpass")); + CatPtr hp = AddCategory(wxT(LV2PREFIX) wxT("HighpassPlugin"), + _("Highpass")); + CatPtr comb = AddCategory(wxT(LV2PREFIX) wxT("CombPlugin"), + _("Comb")); + CatPtr alp = AddCategory(wxT(LV2PREFIX) wxT("AllpassPlugin"), + _("Allpass")); + CatPtr eq = AddCategory(wxT(LV2PREFIX) wxT("EQPlugin"), + _("Equaliser")); + CatPtr peq = AddCategory(wxT(LV2PREFIX) wxT("ParaEQPlugin"), + _("Parametric")); + CatPtr meq = AddCategory(wxT(LV2PREFIX) wxT("MultiEQPlugin"), + _("Multiband")); + CatPtr spec = AddCategory(wxT(LV2PREFIX) wxT("SpectralPlugin"), + _("Spectral Processor")); + CatPtr ptch = AddCategory(wxT(LV2PREFIX) wxT("PitchPlugin"), + _("Pitch Shifter")); + CatPtr amp = AddCategory(wxT(LV2PREFIX) wxT("AmplifierPlugin"), + _("Amplifier")); + CatPtr dist = AddCategory(wxT(LV2PREFIX) wxT("DistortionPlugin"), + _("Distortion")); + CatPtr shp = AddCategory(wxT(LV2PREFIX) wxT("WaveshaperPlugin"), + _("Waveshaper")); + CatPtr dyn = AddCategory(wxT(LV2PREFIX) wxT("DynamicsPlugin"), + _("Dynamics Processor")); + CatPtr cmp = AddCategory(wxT(LV2PREFIX) wxT("CompressorPlugin"), + _("Compressor")); + CatPtr exp = AddCategory(wxT(LV2PREFIX) wxT("ExpanderPlugin"), + _("Expander")); + CatPtr lim = AddCategory(wxT(LV2PREFIX) wxT("LimiterPlugin"), + _("Limiter")); + CatPtr gate = AddCategory(wxT(LV2PREFIX) wxT("GatePlugin"), + _("Gate")); + + AddCategoryParent(inst, gen); + AddCategoryParent(osc, gen); + AddCategoryParent(conv, util); + AddCategoryParent(anal, util); + AddCategoryParent(mix, util); + AddCategoryParent(rev, sim); + AddCategoryParent(rev, del); + AddCategoryParent(phas, mod); + AddCategoryParent(flng, mod); + AddCategoryParent(chor, mod); + AddCategoryParent(lp, flt); + AddCategoryParent(bp, flt); + AddCategoryParent(hp, flt); + AddCategoryParent(comb, flt); + AddCategoryParent(alp, flt); + AddCategoryParent(eq, flt); + AddCategoryParent(peq, eq); + AddCategoryParent(meq, eq); + AddCategoryParent(ptch, spec); + AddCategoryParent(shp, dist); + AddCategoryParent(cmp, dyn); + AddCategoryParent(exp, dyn); + AddCategoryParent(lim, dyn); + AddCategoryParent(gate, dyn); + // We also add a couple of categories for internal use. These are not + // in lv2.ttl. + +#define ATEAM "http://audacityteam.org/namespace#" + + CatPtr nrm = AddCategory(wxT(ATEAM) wxT("NoiseRemoval"), + _("Noise Removal")); + CatPtr pnt = AddCategory(wxT(ATEAM) wxT("PitchAndTempo"), + _("Pitch and Tempo")); + CatPtr tim = AddCategory(wxT(ATEAM) wxT("TimelineChanger"), + _("Timeline Changer")); + CatPtr aTim = AddCategory(wxT(ATEAM) wxT("TimeAnalyser"), + _("Time")); + CatPtr onst = AddCategory(wxT(ATEAM) wxT("OnsetDetector"), + _("Onsets")); + AddCategoryParent(nrm, util); + AddCategoryParent(tim, util); + AddCategoryParent(aTim, anal); + AddCategoryParent(onst, aTim); + + // We freeze the internal subcategory relations between the categories + // added so far so LADSPA/LRDF or other category systems don't ruin + // our hierarchy. + FreezeCategories(); + +#endif + +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + mRealtimeMutex.Lock(); + mRealtimeEffects = NULL; + mRealtimeCount = 0; + mRealtimeActive = false; + mRealtimeSuspended = false; + mRealtimeMutex.Unlock(); + mRealtimeLatency = 0; +#endif + +#if defined(EXPERIMENTAL_EFFECTS_RACK) + mRack = NULL; #endif } @@ -45,28 +200,31 @@ EffectManager::~EffectManager() delete mRootCategories; delete mCategories; #endif + +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + if (mRealtimeEffects) + { + delete [] mRealtimeEffects; + } +#endif + +#if defined(EXPERIMENTAL_EFFECTS_RACK) + // wxWidgets has already destroyed the rack since it was derived from wxFrame. So + // no need to delete it here. +#endif } void EffectManager::RegisterEffect(Effect *f, int NewFlags) { - f->mID = mNumEffects; - mNumEffects++; - if( NewFlags != 0) - f->SetEffectFlags( NewFlags ); + f->SetEffectID(mNumEffects++); - // Insert the effect into the list in alphabetical order - // A linear search is good enough as long as there are - // only a few dozen or even a few hundred effects. - wxString name = Effect::StripAmpersand(f->GetEffectName()); - int len = mEffects.GetCount(); - int i; - for(i=0; iGetEffectName())) < 0) { - mEffects.Insert(f, i); - break; - } - if (i==len) - mEffects.Add(f); + if( NewFlags != 0) + { + f->SetEffectFlags( NewFlags ); + } + + // This will go away after all effects have been converted + mEffectPlugins.Add(PluginManager::Get().RegisterLegacyEffectPlugin(f)); #ifdef EFFECT_CATEGORIES // Add the effect in the right categories @@ -88,11 +246,6 @@ void EffectManager::RegisterEffect(Effect *f, int NewFlags) void EffectManager::UnregisterEffects() { - for(int i=0; iclear(); @@ -102,47 +255,352 @@ void EffectManager::UnregisterEffects() #endif } -int EffectManager::GetNumEffects() +bool EffectManager::DoEffect(const PluginID & ID, + wxWindow *parent, + int flags, + double projectRate, + TrackList *list, + TrackFactory *factory, + SelectedRegion *selectedRegion, + wxString params) { - return mNumEffects; -} - -Effect *EffectManager::GetEffect(int ID) -{ - for(int i=0; imID == ID) - return mEffects[i]; - - return NULL; -} - -Effect* EffectManager::GetEffectByIdentifier(const wxString strTarget, const int kFlags /*= ALL_EFFECTS*/) -{ - if( strTarget == wxT("") ) // set GetEffectIdentifier to wxT("") to not show an effect in Batch mode - return NULL; - for (unsigned int i = 0; i < mEffects.GetCount(); i++) + Effect *effect = GetEffect(ID); + + if (!effect) { - int nFlags = mEffects[i]->GetEffectFlags(); - if (((nFlags & kFlags) == nFlags) && strTarget.IsSameAs(mEffects[i]->GetEffectIdentifier())) - return mEffects[i]; + return false; } - return NULL; + +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) && defined(EXPERIMENTAL_EFFECTS_RACK) + if (effect->IsRealtimeCapable()) + { + GetRack()->Add(effect); + } +#endif + + return effect->DoEffect(parent, + flags, + projectRate, + list, + factory, + selectedRegion, + params); } -EffectArray *EffectManager::GetEffects(int flags /* = ALL_EFFECTS */) +wxString EffectManager::GetEffectName(const PluginID & ID) { - EffectArray *results = new EffectArray(); - - int len = mEffects.GetCount(); - for(int i=0; iGetEffectFlags(); - if ((flags & g) == g) - results->Add(mEffects[i]); - } - - return results; + return PluginManager::Get().GetName(ID); } +wxString EffectManager::GetEffectIdentifier(const PluginID & ID) +{ + wxString name = (PluginManager::Get().GetName(ID)); + + // Get rid of leading and trailing white space + name.Trim(true).Trim(false); + + if (name == wxEmptyString) + { + return name; + } + + wxStringTokenizer st(name, wxT(" ")); + wxString id; + + // CamelCase the name + while (st.HasMoreTokens()) + { + wxString tok = st.GetNextToken(); + + id += tok.Left(1).MakeUpper() + tok.Mid(1).MakeLower(); + } + + return id; +} + +wxString EffectManager::GetEffectDescription(const PluginID & ID) +{ + Effect *effect = GetEffect(ID); + + if (effect) + { + return effect->GetEffectDescription(); + } + + return wxEmptyString; +} + +wxString EffectManager::GetEffectParameters(const PluginID & ID) +{ + Effect *effect = GetEffect(ID); + + if (effect) + { + ShuttleCli shuttle; + shuttle.mbStoreInClient = false; + effect->TransferParameters(shuttle); + return shuttle.mParams; + } + + return wxEmptyString; +} + +bool EffectManager::SetEffectParameters(const PluginID & ID, const wxString & params) +{ + Effect *effect = GetEffect(ID); + + if (effect) + { + ShuttleCli shuttle; + shuttle.mParams = params; + shuttle.mbStoreInClient=true; + return effect->TransferParameters(shuttle); + } + + return false; +} + +bool EffectManager::PromptUser(const PluginID & ID, wxWindow *parent) +{ + Effect *effect = GetEffect(ID); + bool result = false; + + if (effect) + { + result = effect->PromptUser(parent); + } + + return result; +} + +#if defined(EXPERIMENTAL_EFFECTS_RACK) +EffectRack *EffectManager::GetRack() +{ + if (!mRack) + { + mRack = new EffectRack(); + } + + return mRack; +} + +void EffectManager::ShowRack() +{ + GetRack()->Show(); +} +#endif + +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) +void EffectManager::RealtimeInitialize(int numChannels, float sampleRate) +{ + mRealtimeMutex.Lock(); + for (int i = 0; i < mRealtimeCount; i++) + { + mRealtimeEffects[i]->RealtimeInitialize(numChannels, sampleRate); + } + mRealtimeMutex.Unlock(); + + mRealtimeActive = true; + + RealtimeResume(); +} + +void EffectManager::RealtimeFinalize() +{ + RealtimeSuspend(); + + mRealtimeActive = false; + mRealtimeLatency = 0; + + mRealtimeMutex.Lock(); + for (int i = 0; i < mRealtimeCount; i++) + { + mRealtimeEffects[i]->RealtimeFinalize(); + } + mRealtimeMutex.Unlock(); +} + +void EffectManager::RealtimeSuspend() +{ + mRealtimeSuspended = true; + + mRealtimeMutex.Lock(); + for (int i = 0; i < mRealtimeCount; i++) + { + mRealtimeEffects[i]->RealtimeSuspend(); + } + mRealtimeMutex.Unlock(); +} + +void EffectManager::RealtimeResume() +{ + mRealtimeMutex.Lock(); + for (int i = 0; i < mRealtimeCount; i++) + { + mRealtimeEffects[i]->RealtimeResume(); + } + mRealtimeMutex.Unlock(); + + mRealtimeSuspended = false; +} + +void EffectManager::RealtimeProcessMono(float *buffer, sampleCount numSamples) +{ + // Can be suspended because of the audio stream being paused or because effects + // have been suspended. + if (mRealtimeSuspended) + { + return; + } + + wxMilliClock_t start = wxGetLocalTimeMillis(); + + float *ib = (float *) alloca(sizeof(float) * numSamples); + float *ob = (float *) alloca(sizeof(float) * numSamples); + + memcpy(ib, buffer, sizeof(float) * numSamples); + + float *ibuf[1] = {ib}; + float *obuf[1] = {ob}; + + mRealtimeMutex.Lock(); + for (int i = 0; i < mRealtimeCount; i++) + { + mRealtimeEffects[i]->RealtimeProcess(ibuf, obuf, numSamples); + + float *tbuf[1] = {ibuf[0]}; + ibuf[0] = obuf[0]; + obuf[0] = tbuf[0]; + } + mRealtimeMutex.Unlock(); + + memcpy(buffer, ibuf[0], sizeof(float) * numSamples); + + mRealtimeLatency = (int) (wxGetLocalTimeMillis() - start).GetValue(); +} + +void EffectManager::RealtimeProcessStereo(float *buffer, sampleCount numSamples) +{ + // Can be suspended because of the audio stream being paused or because effects + // have been suspended. + if (mRealtimeSuspended) + { + return; + } + + wxMilliClock_t start = wxGetLocalTimeMillis(); + + float *ilc = (float *) alloca(sizeof(float) * numSamples); + float *irc = (float *) alloca(sizeof(float) * numSamples); + float *olc = (float *) alloca(sizeof(float) * numSamples); + float *orc = (float *) alloca(sizeof(float) * numSamples); + + for (int opos = 0, ipos = 0; opos < numSamples; opos++, ipos += 2) + { + ilc[opos] = buffer[ipos]; + irc[opos] = buffer[ipos+1]; + } + + float *ibuf[2] = {ilc, irc}; + float *obuf[2] = {olc, orc}; + + mRealtimeMutex.Lock(); + for (int i = 0; i < mRealtimeCount; i++) + { + mRealtimeEffects[i]->RealtimeProcess(ibuf, obuf, numSamples); + + float *tbuf[2] = {ibuf[0], ibuf[1]}; + ibuf[0] = obuf[0]; + ibuf[1] = obuf[1]; + obuf[0] = tbuf[0]; + obuf[1] = tbuf[1]; + } + mRealtimeMutex.Unlock(); + + for (int opos = 0, ipos = 0; ipos < numSamples; ipos++, opos += 2) + { + buffer[opos] = ibuf[0][ipos] > 1.0 ? 1.0 : ibuf[0][ipos]; + buffer[opos+1] = ibuf[1][ipos] > 1.0 ? 1.0 : ibuf[1][ipos]; + } + + mRealtimeLatency = (int) (wxGetLocalTimeMillis() - start).GetValue(); +} + +int EffectManager::GetRealtimeLatency() +{ + return mRealtimeLatency; +} + +void EffectManager::SetRealtime(const EffectArray & effects) +{ + Effect **rteffects = new Effect *[effects.GetCount()]; + if (rteffects) + { + for (int i = 0, cnt = effects.GetCount(); i < cnt; i++) + { + rteffects[i] = effects[i]; + } + + mRealtimeMutex.Lock(); + Effect **rtold = mRealtimeEffects; + mRealtimeEffects = rteffects; + mRealtimeCount = effects.GetCount(); + mRealtimeMutex.Unlock(); + if (rtold) + { + delete [] rtold; + } + } +} +#endif + +Effect *EffectManager::GetEffect(const PluginID & ID) +{ + Effect *effect; + + // TODO: This is temporary and should be redone when all effects are converted + if (mEffectPlugins.Index(wxString(ID)) == wxNOT_FOUND) + { + // This will instantiate the effect client if it hasn't already been done + EffectClientInterface *client = static_cast(PluginManager::Get().GetInstance(ID)); + if (client) + { + effect = new Effect(client); + if (effect) + { + effect->SetEffectID(mNumEffects++); + PluginManager::Get().SetInstance(ID, effect); + mEffectPlugins.Add(ID); + } + + return effect; + } + return NULL; + } + + return static_cast(PluginManager::Get().GetInstance(ID)); +} + +const PluginID & EffectManager::GetEffectByIdentifier(const wxString & strTarget) +{ + if (strTarget == wxEmptyString) // set GetEffectIdentifier to wxT("") to not show an effect in Batch mode + { + return PluginID(wxEmptyString); + } + + PluginManager & pm = PluginManager::Get(); + const PluginDescriptor *plug = pm.GetFirstPlugin(PluginTypeEffect); + while (plug) + { + if (GetEffectIdentifier(plug->GetID()).IsSameAs(strTarget)) + { + return plug->GetID(); + } + plug = pm.GetNextPlugin(PluginTypeEffect); + } + + return PluginID(wxEmptyString); +} #ifdef EFFECT_CATEGORIES diff --git a/src/effects/EffectManager.h b/src/effects/EffectManager.h index 7927bb04c..da7cf0b88 100644 --- a/src/effects/EffectManager.h +++ b/src/effects/EffectManager.h @@ -18,12 +18,15 @@ effects. *//*******************************************************************/ - #ifndef __AUDACITY_EFFECTMANAGER__ #define __AUDACITY_EFFECTMANAGER__ #include +#include +#include +#include "audacity/EffectInterface.h" +#include "../PluginManager.h" #include "Effect.h" #ifdef EFFECT_CATEGORIES @@ -32,8 +35,15 @@ effects. WX_DEFINE_USER_EXPORTED_ARRAY(Effect *, EffectArray, class AUDACITY_DLL_API); +#if defined(EXPERIMENTAL_EFFECTS_RACK) +class EffectRack; +#endif -class AUDACITY_DLL_API EffectManager { +class AUDACITY_DLL_API EffectManager +{ +#if defined(EXPERIMENTAL_EFFECTS_RACK) + friend class EffectRack; +#endif public: @@ -60,18 +70,45 @@ class AUDACITY_DLL_API EffectManager { /** Unregister all effects. */ void UnregisterEffects(); - /** Return an effect by its numerical ID. */ - Effect *GetEffect(int ID); + /** Run an effect given the plugin ID */ + // Returns true on success. Will only operate on tracks that + // have the "selected" flag set to true, which is consistent with + // Audacity's standard UI. + bool DoEffect(const PluginID & ID, + wxWindow *parent, + int flags, + double projectRate, + TrackList *list, + TrackFactory *factory, + SelectedRegion *selectedRegion, + wxString params); - Effect* GetEffectByIdentifier(const wxString strTarget, const int kFlags = ALL_EFFECTS); + wxString GetEffectName(const PluginID & ID); + wxString GetEffectIdentifier(const PluginID & ID); + wxString GetEffectDescription(const PluginID & ID); - /** Return the number of registered effects. */ - int GetNumEffects(); + /** Support for batch commands */ + wxString GetEffectParameters(const PluginID & ID); + bool SetEffectParameters(const PluginID & ID, const wxString & params); + bool PromptUser(const PluginID & ID, wxWindow *parent); - /** Returns a sorted array of effects, which may be filtered - using the flags parameter. The caller should dispose - of the array when done. */ - EffectArray *GetEffects(int flags = ALL_EFFECTS); +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + // Realtime effect processing + void RealtimeInitialize(int numChannels, float sampleRate); + void RealtimeFinalize(); + void RealtimeSuspend(); + void RealtimeResume(); + void RealtimeProcessMono(float *buffer, sampleCount numSamples); + void RealtimeProcessStereo(float *buffer, sampleCount numSamples); + void SetRealtime(const EffectArray & mActive); + int GetRealtimeLatency(); +#endif + +#if defined(EXPERIMENTAL_EFFECTS_RACK) + void ShowRack(); +#endif + + const PluginID & GetEffectByIdentifier(const wxString & strTarget); #ifdef EFFECT_CATEGORIES @@ -104,10 +141,31 @@ class AUDACITY_DLL_API EffectManager { #endif private: + /** Return an effect by its ID. */ + Effect *GetEffect(const PluginID & ID); + +#if defined(EXPERIMENTAL_EFFECTS_RACK) + EffectRack *GetRack(); +#endif + +private: + wxArrayString mEffectPlugins; - EffectArray mEffects; int mNumEffects; +#if defined(EXPERIMENTAL_EFFECTS_RACK) + EffectRack *mRack; +#endif + +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + wxMutex mRealtimeMutex; + Effect **mRealtimeEffects; + int mRealtimeCount; + int mRealtimeLatency; + bool mRealtimeActive; + bool mRealtimeSuspended; +#endif + #ifdef EFFECT_CATEGORIES // This maps URIs to EffectCategory pointers for all added categories. // It is needed for fast lookup and easy deletion. @@ -121,7 +179,6 @@ class AUDACITY_DLL_API EffectManager { // are placed in. EffectSet *mUnsorted; #endif - }; diff --git a/src/effects/EffectRack.cpp b/src/effects/EffectRack.cpp new file mode 100644 index 000000000..4e7262173 --- /dev/null +++ b/src/effects/EffectRack.cpp @@ -0,0 +1,537 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + EffectRack.cpp + + Leland Lucius + + Audacity(R) is copyright (c) 1999-2008 Audacity Team. + License: GPL v2. See License.txt. + +**********************************************************************/ + +#include "../Experimental.h" + +#if defined(EXPERIMENTAL_EFFECTS_RACK) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "EffectManager.h" +#include "EffectRack.h" +#include "../Prefs.h" +#include "../Project.h" +#include "../widgets/AButton.h" + +#include "../../images/EffectRack/EffectRack.h" + +#define COL_POWER 0 +#define COL_EDITOR 1 +#define COL_UP 2 +#define COL_DOWN 3 +#define COL_FAV 4 +#define COL_REMOVE 5 +#define COL_NAME 6 +#define NUMCOLS 7 + +#define ID_BASE 20000 +#define ID_RANGE 100 +#define ID_POWER (ID_BASE + (COL_POWER * ID_RANGE)) +#define ID_EDITOR (ID_BASE + (COL_EDITOR * ID_RANGE)) +#define ID_UP (ID_BASE + (COL_UP * ID_RANGE)) +#define ID_DOWN (ID_BASE + (COL_DOWN * ID_RANGE)) +#define ID_FAV (ID_BASE + (COL_FAV * ID_RANGE)) +#define ID_REMOVE (ID_BASE + (COL_REMOVE * ID_RANGE)) +#define ID_NAME (ID_BASE + (COL_NAME * ID_RANGE)) + +BEGIN_EVENT_TABLE(EffectRack, wxFrame) + EVT_CLOSE(EffectRack::OnClose) + EVT_TIMER(wxID_ANY, EffectRack::OnTimer) + + EVT_BUTTON(wxID_APPLY, EffectRack::OnApply) + EVT_TOGGLEBUTTON(wxID_CLEAR, EffectRack::OnBypass) + + EVT_COMMAND_RANGE(ID_REMOVE, ID_REMOVE + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnRemove) + EVT_COMMAND_RANGE(ID_POWER, ID_POWER + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnPower) + EVT_COMMAND_RANGE(ID_EDITOR, ID_EDITOR + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnEditor) + EVT_COMMAND_RANGE(ID_UP, ID_UP + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnUp) + EVT_COMMAND_RANGE(ID_DOWN, ID_DOWN + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnDown) + EVT_COMMAND_RANGE(ID_FAV, ID_FAV + 99, wxEVT_COMMAND_BUTTON_CLICKED, EffectRack::OnFav) +END_EVENT_TABLE() + +EffectRack::EffectRack() +: wxFrame(GetActiveProject(), + wxID_ANY, + _("Effects Rack"), + wxDefaultPosition, + wxDefaultSize, + wxSYSTEM_MENU | + wxCLOSE_BOX | + wxCAPTION | +// wxSIMPLE_BORDER | + wxFRAME_NO_TASKBAR | + wxFRAME_FLOAT_ON_PARENT) +{ + mBypassing = false; + mNumEffects = 0; + mLastLatency = 0; + mTimer.SetOwner(this); + + mRemovePushed = CreateImage(remove_16x16_xpm, false, true); + mRemoveRaised = CreateImage(remove_16x16_xpm, true, true); + mPowerPushed = CreateImage(power_on_16x16_xpm, false, false); + mPowerRaised = CreateImage(power_off_16x16_xpm, true, false); + mFavPushed = CreateImage(fav_down_16x16_xpm, false, false); + mFavRaised = CreateImage(fav_up_16x16_xpm, true, false); + mSettingsPushed = CreateImage(settings_up_16x16_xpm, false, true); + mSettingsRaised = CreateImage(settings_down_16x16_xpm, true, true); + mUpDisabled = CreateImage(up_9x16_xpm, true, true); + mUpPushed = CreateImage(up_9x16_xpm, false, true); + mUpRaised = CreateImage(up_9x16_xpm, true, true); + mDownDisabled = CreateImage(down_9x16_xpm, true, true); + mDownPushed = CreateImage(down_9x16_xpm, false, true); + mDownRaised = CreateImage(down_9x16_xpm, true, true); + + wxBoxSizer *bs = new wxBoxSizer(wxVERTICAL); + mPanel = new wxPanel(this, wxID_ANY); + bs->Add(mPanel, 1, wxEXPAND); + SetSizer(bs); + + wxBoxSizer *hs = new wxBoxSizer(wxHORIZONTAL); + hs->Add(new wxButton(mPanel, wxID_APPLY, _("&Apply")), 0, wxALIGN_LEFT); + hs->AddStretchSpacer(); + mLatency = new wxStaticText(mPanel, wxID_ANY, _("Latency: 0")); + hs->Add(mLatency, 0, wxALIGN_CENTER); + hs->AddStretchSpacer(); + hs->Add(new wxToggleButton(mPanel, wxID_CLEAR, _("&Bypass")), 0, wxALIGN_RIGHT); + + bs = new wxBoxSizer(wxVERTICAL); + bs->Add(hs, 0, wxEXPAND); + bs->Add(new wxStaticLine(mPanel, wxID_ANY), 0, wxEXPAND); + + mMainSizer = new wxFlexGridSizer(7); + mMainSizer->AddGrowableCol(6); + mMainSizer->SetHGap(0); + mMainSizer->SetVGap(0); + bs->Add(mMainSizer, 1, wxEXPAND); + + mPanel->SetSizer(bs); + + wxString oldPath = gPrefs->GetPath(); + gPrefs->SetPath(wxT("/EffectsRack")); + size_t cnt = gPrefs->GetNumberOfEntries(); + gPrefs->SetPath(oldPath); + + EffectManager & em = EffectManager::Get(); + for (size_t i = 0; i < cnt; i++) + { + wxString slot; + gPrefs->Read(wxString::Format(wxT("/EffectsRack/Slot%02d"), i), &slot); + + Effect *effect = em.GetEffect(slot.AfterFirst(wxT(',')).c_str()); + if (effect) + { + Add(effect, slot.BeforeFirst(wxT(',')) == wxT("1"), true); + } + } + + Fit(); +} + +EffectRack::~EffectRack() +{ + gPrefs->DeleteGroup(wxT("/EffectsRack")); + + for (size_t i = 0, cnt = mEffects.GetCount(); i < cnt; i++) + { + wxSizerItem *si; + + si = mMainSizer->GetItem(i * NUMCOLS + COL_FAV); + AButton *fav = static_cast(si->GetWindow()); + + if (fav && fav->IsDown()) + { + si = mMainSizer->GetItem(i * NUMCOLS + COL_POWER); + AButton *power = static_cast(si->GetWindow()); + + Effect *effect = mEffects[i]; + gPrefs->Write(wxString::Format(wxT("/EffectsRack/Slot%02d"), i), + wxString::Format(wxT("%d,%s"), + power->IsDown(), + effect->GetID().c_str())); + } + } +} + +void EffectRack::Add(Effect *effect, bool active, bool favorite) +{ + if (mEffects.Index(effect) != wxNOT_FOUND) + { + return; + } + + AButton *ab; + + ab = new AButton(mPanel, + ID_POWER + mNumEffects, + wxDefaultPosition, + wxDefaultSize, + mPowerRaised, + mPowerRaised, + mPowerPushed, + mPowerPushed, + true); + ab->SetToolTip(_("Set effect active state")); + if (active) + { + ab->PushDown(); + } + else + { + ab->PopUp(); + } + mMainSizer->Add(ab, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + + ab = new AButton(mPanel, + ID_EDITOR + mNumEffects, + wxDefaultPosition, + wxDefaultSize, + mSettingsRaised, + mSettingsRaised, + mSettingsPushed, + mSettingsPushed, + false); + ab->SetToolTip(_("Open/close effect editor")); + ab->PopUp(); + mMainSizer->Add(ab, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + + ab = new AButton(mPanel, + ID_UP + mNumEffects, + wxDefaultPosition, + wxDefaultSize, + mUpRaised, + mUpRaised, + mUpPushed, + mUpDisabled, + false); + ab->SetToolTip(_("Move effect up in the rack")); + ab->PopUp(); + mMainSizer->Add(ab, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + + ab = new AButton(mPanel, + ID_DOWN + mNumEffects, + wxDefaultPosition, + wxDefaultSize, + mDownRaised, + mDownRaised, + mDownPushed, + mDownDisabled, + false); + ab->SetToolTip(_("Move effect down in the rack")); + ab->PopUp(); + mMainSizer->Add(ab, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + + ab = new AButton(mPanel, + ID_FAV + mNumEffects, + wxDefaultPosition, + wxDefaultSize, + mFavRaised, + mFavRaised, + mFavPushed, + mFavPushed, + true); + ab->SetToolTip(_("Mark effect as a favorite")); + if (favorite) + { + ab->PushDown(); + } + else + { + ab->PopUp(); + } + mMainSizer->Add(ab, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + + ab = new AButton(mPanel, + ID_REMOVE + mNumEffects, + wxDefaultPosition, + wxDefaultSize, + mRemoveRaised, + mRemoveRaised, + mRemovePushed, + mRemovePushed, + false); + ab->SetToolTip(_("Remove effect from the rack")); + ab->PopUp(); + mMainSizer->Add(ab, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); + + wxStaticText *text = new wxStaticText(mPanel, ID_NAME + mNumEffects, effect->GetName()); + text->SetToolTip(_("Name of the effect")); + mMainSizer->Add(text, 0, wxEXPAND | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 5); + + mMainSizer->Layout(); + SetSize(GetMinSize()); + Fit(); + Update(); + + mEffects.Add(effect); + mNumEffects++; + + if (!mTimer.IsRunning()) + { + mTimer.Start(1000); + } + + if (active) + { + UpdateActive(); + } +} + +void EffectRack::OnClose(wxCloseEvent & evt) +{ + Show(false); + evt.Veto(); +} + +void EffectRack::OnTimer(wxTimerEvent & AUNUSED(evt)) +{ + int latency = EffectManager::Get().GetRealtimeLatency(); + if (latency != mLastLatency) + { + mLatency->SetLabel(wxString::Format(_("Latency: %4d"), latency)); + mLatency->Refresh(); + mLastLatency = latency; + } +} + +void EffectRack::OnApply(wxCommandEvent & AUNUSED(evt)) +{ + AudacityProject *project = GetActiveProject(); + + for (size_t i = 0, cnt = mEffects.GetCount(); i < cnt; i++) + { + AButton *btn = static_cast(FindWindowById(ID_POWER + i)); + if (btn->IsDown()) + { + project->OnEffect(mEffects[i]->GetID(), true); + + btn->PopUp(); + btn->Refresh(); + } + } + + UpdateActive(); +} + +void EffectRack::OnBypass(wxCommandEvent & evt) +{ + mBypassing = evt.GetInt() != 0; + UpdateActive(); +} + +void EffectRack::OnPower(wxCommandEvent & evt) +{ + evt.Skip(); + + UpdateActive(); +} + +void EffectRack::OnEditor(wxCommandEvent & evt) +{ + AButton *btn = static_cast(evt.GetEventObject()); + + btn->PopUp(); + evt.Skip(); + + int index = GetEffectIndex(btn); + if (index < 0) + { + return; + } + + mEffects[index]->PromptUser(GetParent()); +} + +void EffectRack::OnUp(wxCommandEvent & evt) +{ + AButton *btn = static_cast(evt.GetEventObject()); + + btn->PopUp(); + evt.Skip(); + + int index = GetEffectIndex(btn); + if (index <= 0) + { + return; + } + + MoveRowUp(index); +} + +void EffectRack::OnDown(wxCommandEvent & evt) +{ + AButton *btn = static_cast(evt.GetEventObject()); + + btn->PopUp(); + evt.Skip(); + + size_t index = GetEffectIndex(btn); + if (index < 0 || index == (mMainSizer->GetChildren().GetCount() / NUMCOLS) - 1) + { + return; + } + + MoveRowUp(index + 1); +} + +void EffectRack::OnFav(wxCommandEvent & evt) +{ + evt.Skip(); +} + +void EffectRack::OnRemove(wxCommandEvent & evt) +{ + AButton *btn = static_cast(evt.GetEventObject()); + + btn->PopUp(); + evt.Skip(); + + int index = GetEffectIndex(btn); + if (index < 0) + { + return; + } + + mEffects.RemoveAt(index); + + if (mEffects.GetCount() == 0) + { + if (mTimer.IsRunning()) + { + mTimer.Stop(); + } + } + + index *= NUMCOLS; + + for (int i = 0; i < NUMCOLS; i++) + { + delete mMainSizer->GetItem(index)->GetWindow(); + } + + mMainSizer->Layout(); + Fit(); + + UpdateActive(); +} + +wxImage EffectRack::CreateImage(const char *xpm[], bool up, bool pusher) +{ + wxMemoryDC dc; + wxBitmap pic(xpm); + + wxBitmap mod(pic.GetWidth() + 6, pic.GetHeight() + 6); + dc.SelectObject(mod); +#if defined( __WXGTK__ ) + wxColour newColour = wxSystemSettings::GetColour( wxSYS_COLOUR_BACKGROUND ); +#else + wxColour newColour = wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ); +#endif + dc.SetBackground(wxBrush(newColour)); + dc.Clear(); + + int offset = 3; + if (pusher) + { + if (!up) + { + offset += 1; + } + } + dc.DrawBitmap(pic, offset, offset, true); + + dc.SelectObject(wxNullBitmap); + + return mod.ConvertToImage(); +} + +int EffectRack::GetEffectIndex(wxWindow *win) +{ + int col = (win->GetId() - ID_BASE) / ID_RANGE; + int row; + int cnt = mMainSizer->GetChildren().GetCount() / NUMCOLS; + for (row = 0; row < cnt; row++) + { + wxSizerItem *si = mMainSizer->GetItem((row * NUMCOLS) + col); + if (si->GetWindow() == win) + { + break; + } + } + + if (row == cnt) + { + return -1; + } + + return row; +} + +void EffectRack::MoveRowUp(int row) +{ + Effect *effect = mEffects[row]; + mEffects.RemoveAt(row); + mEffects.Insert(effect, row - 1); + + row *= NUMCOLS; + + for (int i = 0; i < NUMCOLS; i++) + { + wxSizerItem *si = mMainSizer->GetItem(row + NUMCOLS - 1); + wxWindow *w = si->GetWindow(); + int flags = si->GetFlag(); + int border = si->GetBorder(); + int prop = si->GetProportion(); + mMainSizer->Detach(row + NUMCOLS - 1); + mMainSizer->Insert(row - NUMCOLS, w, prop, flags, border); + } + + mMainSizer->Layout(); + Refresh(); + + UpdateActive(); +} + +void EffectRack::UpdateActive() +{ + mActive.clear(); + + if (!mBypassing) + { + for (size_t i = 0, cnt = mEffects.GetCount(); i < cnt; i++) + { + wxSizerItem *si = mMainSizer->GetItem(i * NUMCOLS + COL_POWER); + AButton *power = static_cast(si->GetWindow()); + if (power && power->IsDown()) + { + mActive.Add(mEffects[i]); + } + } + } + + EffectManager::Get().SetRealtime(mActive); +} + +#endif diff --git a/src/effects/EffectRack.h b/src/effects/EffectRack.h new file mode 100644 index 000000000..f4fb1b8bf --- /dev/null +++ b/src/effects/EffectRack.h @@ -0,0 +1,94 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + EffectRack.h + + Leland Lucius + + Audacity(R) is copyright (c) 1999-2008 Audacity Team. + License: GPL v2. See License.txt. + +**********************************************************************/ + +#ifndef __AUDACITY_EFFECTRACK_H__ +#define __AUDACITY_EFFECTRACK_H__ + +#include "../Experimental.h" + +#if defined(EXPERIMENTAL_EFFECTS_RACK) + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "EffectManager.h" + +class EffectRack : public wxFrame +{ +public: + EffectRack(); + virtual ~EffectRack(); + + void Add(Effect *effect, bool active = true, bool favorite = false); + +private: + + wxImage CreateImage(const char *xpm[], bool up, bool pusher); + int GetEffectIndex(wxWindow *win); + void MoveRowUp(int row); + void UpdateActive(); + + void OnClose(wxCloseEvent & evt); + void OnTimer(wxTimerEvent & evt); + void OnApply(wxCommandEvent & evt); + void OnBypass(wxCommandEvent & evt); + + void OnPower(wxCommandEvent & evt); + void OnEditor(wxCommandEvent & evt); + void OnUp(wxCommandEvent & evt); + void OnDown(wxCommandEvent & evt); + void OnFav(wxCommandEvent & evt); + void OnRemove(wxCommandEvent & evt); + +private: + wxStaticText *mLatency; + int mLastLatency; + + wxImage mRemovePushed; + wxImage mRemoveRaised; + wxImage mPowerPushed; + wxImage mPowerRaised; + wxImage mFavPushed; + wxImage mFavRaised; + wxImage mSettingsPushed; + wxImage mSettingsRaised; + wxImage mUpPushed; + wxImage mUpRaised; + wxImage mUpDisabled; + wxImage mDownPushed; + wxImage mDownRaised; + wxImage mDownDisabled; + + int mNumEffects; + + wxTimer mTimer; + + wxPanel *mPanel; + wxFlexGridSizer *mMainSizer; + + EffectArray mEffects; + EffectArray mActive; + bool mBypassing; + + DECLARE_EVENT_TABLE() +}; + +#endif + +#endif // __AUDACITY_EFFECTRACK_H__ diff --git a/src/effects/LoadEffects.cpp b/src/effects/LoadEffects.cpp index 3e2871f2e..db5d4ac64 100644 --- a/src/effects/LoadEffects.cpp +++ b/src/effects/LoadEffects.cpp @@ -62,10 +62,6 @@ #include "audiounits/LoadAudioUnits.h" #endif -#ifdef USE_VST -#include "VST/VSTEffect.h" -#endif - #ifdef USE_LADSPA #include "ladspa/LoadLadspa.h" #endif @@ -289,12 +285,6 @@ void LoadEffects() } #endif -#ifdef USE_VST - if (gPrefs->Read(wxT("/VST/Enable"), true)) { - RegisterVSTEffects(); - } -#endif - #ifdef USE_LV2 if (gPrefs->Read(wxT("/LV2/Enable"), true)) { LoadLV2Plugins(); diff --git a/src/effects/VST/VSTEffect.cpp b/src/effects/VST/VSTEffect.cpp index 9b4c6aa22..c8c721e7f 100644 --- a/src/effects/VST/VSTEffect.cpp +++ b/src/effects/VST/VSTEffect.cpp @@ -8,9 +8,7 @@ This class implements a VST Plug-in effect. The plug-in must be loaded in a platform-specific way and passed into the constructor, - but from here this class handles the interfacing. VST plug-ins - are used in Cubase and other Steinberg products, and all of those - files and the information within is copyrighted by Steinberg. + but from here this class handles the interfacing. **********************************************************************/ @@ -18,739 +16,565 @@ // WARNING: This is NOT 64-bit safe // ******************************************************************* +#if defined(BUILDING_AUDACITY) #include "../../Audacity.h" +#include "../../PlatformCompatibility.h" + +// Make the main function private +#define MODULEMAIN_SCOPE static +#else +#define MODULEMAIN_SCOPE +#define USE_VST 1 +#endif #if USE_VST +#include #include +#include #include #include +#include #include #include #include +#include +#include +#include +#include #include #include +#include #include #include #include -#include +#include #include -#include +#include +#include +#include #include -#include -#include -#include + +#include #if defined(__WXMAC__) #include #include #elif defined(__WXMSW__) #include +#include +#include +#pragma comment(lib, "shlwapi") #else -#include -#include +// Includes for GTK are later since they cause conflicts with our class names #endif -#if defined(__WXMSW__) - #include - #include - #pragma comment(lib, "shlwapi") -#endif +// TODO: Unfortunately we have some dependencies on Audacity provided +// dialogs, widgets and other stuff. This will need to be cleaned up. #include "FileDialog.h" - -#include "../../AudacityApp.h" #include "../../FileNames.h" #include "../../Internat.h" #include "../../PlatformCompatibility.h" -#include "../../PluginManager.h" #include "../../Prefs.h" +#include "../../ShuttleGui.h" +#include "../../effects/Effect.h" +#include "../../widgets/valnum.h" #include "../../xml/XMLFileReader.h" #include "../../xml/XMLWriter.h" -#include "../../Theme.h" -#include "../../widgets/valnum.h" -#include "../EffectManager.h" -#include "../images/Arrow.xpm" + +#include "audacity/ConfigInterface.h" + +// Must include after ours since we have a lot of name collisions +#if defined(__WXGTK__) +#include +#define Region XRegion // Conflicts with Audacity's Region structure +#include +#include +#undef Region +#endif #include "VSTEffect.h" -/////////////////////////////////////////////////////////////////////////////// -// -// RegisterVSTEffects -// -/////////////////////////////////////////////////////////////////////////////// +// NOTE: To debug the subprocess, use wxLogDebug and, on Windows, Debugview +// from TechNet (Sysinternals). -void RegisterVSTEffects() +// ============================================================================ +// +// Module registration entry point +// +// This is the symbol that Audacity looks for when the module is built as a +// dynamic library. +// +// When the module is builtin to Audacity, we use the same function, but it is +// declared static so as not to clash with other builtin modules. +// +// ============================================================================ +MODULEMAIN_SCOPE ModuleInterface *AudacityModule(ModuleManagerInterface *moduleManager, + const wxString *path) { - PluginManager & pm = PluginManager::Get(); - - pm.Open(); - - bool bRescanRequired = false; - if (gPrefs->Read(wxT("/VST/Rescan"), (long)true) != false) { - bRescanRequired = true; - pm.PurgeType(VSTPLUGINTYPE); - } - - if (!pm.HasType(VSTPLUGINTYPE)) { - pm.Close(); - if( bRescanRequired ) { - if( VSTEffect::Scan() != wxID_CANCEL ) { - gPrefs->Write(wxT("/VST/Rescan"), false); - gPrefs->Flush(); - } - } - pm.Open(); - } - - EffectManager & em = EffectManager::Get(); - - wxString path = pm.GetFirstPlugin(VSTPLUGINTYPE); - while (!path.IsEmpty()) { -#if defined(__WXMAC__) - if (wxDirExists(path)) { -#else - if (wxFileExists(path)) { -#endif - em.RegisterEffect(new VSTEffect(path)); - } - - path = pm.GetNextPlugin(VSTPLUGINTYPE); - } - - pm.Close(); + // Create our effects module and register + return new VSTEffectsModule(moduleManager, path); } -#if wxUSE_ACCESSIBILITY +#if defined(BUILDING_AUDACITY) +// ============================================================================ +// +// Register this as a builtin module +// +// We also take advantage of the fact that wxModules are initialized before +// the wxApp::OnInit() method is called. We check to see if Audacity was +// executed to scan a VST effect in a different process. +// +// ============================================================================ +DECLARE_BUILTIN_MODULE(VSTBuiltin); -class CheckListAx: public wxWindowAccessible +class VSTSubEntry : public wxModule { - public: - CheckListAx(wxListCtrl * window); +public: + bool OnInit() + { + // Have we been started to check a plugin? + if (wxTheApp && wxTheApp->argc == 3 && wxStrcmp(wxTheApp->argv[1], VSTCMDKEY) == 0) + { + // NOTE: This can really hide failures, which is what we want for those pesky + // VSTs that are bad or that our support isn't currect. But, it can also + // hide Audacity failures in the subprocess, so if you're having an unruley + // VST or odd Audacity failures, comment it out and you might get more info. + wxHandleFatalExceptions(); + VSTEffectsModule::Check(wxTheApp->argv[2]); - virtual ~ CheckListAx(); + // Returning false causes default processing to display a message box, but we don't + // want that so disable logging. + wxLog::EnableLogging(false); + return false; + } - // Retrieves the address of an IDispatch interface for the specified child. - // All objects must support this property. - virtual wxAccStatus GetChild( int childId, wxAccessible **child ); + return true; + }; - // Gets the number of children. - virtual wxAccStatus GetChildCount( int *childCount ); + void OnExit() {}; - // Gets the default action for this object (0) or > 0 (the action for a child). - // Return wxACC_OK even if there is no action. actionName is the action, or the empty - // string if there is no action. - // The retrieved string describes the action that is performed on an object, - // not what the object does as a result. For example, a toolbar button that prints - // a document has a default action of "Press" rather than "Prints the current document." - virtual wxAccStatus GetDefaultAction( int childId, wxString *actionName ); + DECLARE_DYNAMIC_CLASS(VSTSubEntry); +}; +IMPLEMENT_DYNAMIC_CLASS(VSTSubEntry, wxModule); - // Returns the description for this object or a child. - virtual wxAccStatus GetDescription( int childId, wxString *description ); +#endif - // Gets the window with the keyboard focus. - // If childId is 0 and child is NULL, no object in - // this subhierarchy has the focus. - // If this object has the focus, child should be 'this'. - virtual wxAccStatus GetFocus( int *childId, wxAccessible **child ); +//---------------------------------------------------------------------------- +// VSTSubProcess +//---------------------------------------------------------------------------- +#define OUTPUTKEY L"-" +#define KEY_ID L"ID" +#define KEY_NAME L"Name" +#define KEY_PATH L"Path" +#define KEY_VENDOR L"Vendor" +#define KEY_VERSION L"Version" +#define KEY_DESCRIPTION L"Description" +#define KEY_EFFECTTYPE L"EffectType" +#define KEY_INTERACTIVE L"Interactive" - // Returns help text for this object or a child, similar to tooltip text. - virtual wxAccStatus GetHelpText( int childId, wxString *helpText ); +class VSTSubProcess : public wxProcess, + public EffectIdentInterface +{ +public: + VSTSubProcess() + { + Redirect(); + } - // Returns the keyboard shortcut for this object or child. - // Return e.g. ALT+K - virtual wxAccStatus GetKeyboardShortcut( int childId, wxString *shortcut ); + // EffectClientInterface implementation - // Returns the rectangle for this object (id = 0) or a child element (id > 0). - // rect is in screen coordinates. - virtual wxAccStatus GetLocation( wxRect& rect, int elementId ); + PluginID GetID() + { + return mID; + } - // Gets the name of the specified object. - virtual wxAccStatus GetName( int childId, wxString *name ); + wxString GetPath() + { + return mPath; + } - // Returns a role constant. - virtual wxAccStatus GetRole( int childId, wxAccRole *role ); + wxString GetName() + { + return mName; + } - // Gets a variant representing the selected children - // of this object. - // Acceptable values: - // - a null variant (IsNull() returns TRUE) - // - a list variant (GetType() == wxT("list")) - // - an integer representing the selected child element, - // or 0 if this object is selected (GetType() == wxT("long")) - // - a "void*" pointer to a wxAccessible child object - virtual wxAccStatus GetSelections( wxVariant *selections ); + wxString GetVendor() + { + return mVendor; + } - // Returns a state constant. - virtual wxAccStatus GetState( int childId, long* state ); + wxString GetVersion() + { + return mVersion; + } - // Returns a localized string representing the value for the object - // or child. - virtual wxAccStatus GetValue( int childId, wxString *strValue ); + wxString GetDescription() + { + return mDescription; + } - void SetSelected( int item ); - private: - wxListCtrl *mParent; - int mLastId; + wxString GetFamily() + { + return VSTPLUGINTYPE; + } + + EffectType GetType() + { + return mType; + } + + bool IsInteractive() + { + return mInteractive; + } + + bool IsDefault() + { + return false; + } + + bool IsLegacy() + { + return false; + } + + bool IsRealtimeCapable() + { + return false; + return mType == EffectTypeProcess; + } + + +public: + PluginID mID; + wxString mPath; + wxString mName; + wxString mVendor; + wxString mVersion; + wxString mDescription; + EffectType mType; + bool mInteractive; }; -CheckListAx::CheckListAx( wxListCtrl * window ): - wxWindowAccessible( window ) +// ============================================================================ +// +// VSTEffectsModule +// +// ============================================================================ +VSTEffectsModule::VSTEffectsModule(ModuleManagerInterface *moduleManager, + const wxString *path) { - mParent = window; - mLastId = -1; -} - -CheckListAx::~CheckListAx() -{ -} - -void CheckListAx::SetSelected( int item ) -{ -#if 0 - NotifyEvent(wxACC_EVENT_OBJECT_REORDER, - mParent, - wxOBJID_CLIENT, - 0); -#endif -#if 1 - if (mLastId != -1) { - NotifyEvent(wxACC_EVENT_OBJECT_SELECTIONREMOVE, - mParent, - wxOBJID_CLIENT, - mLastId); - mLastId = -1; - } - - if (item != -1) + mModMan = moduleManager; + if (path) { - NotifyEvent(wxACC_EVENT_OBJECT_FOCUS, - mParent, - wxOBJID_CLIENT, - item + 1); - - NotifyEvent(wxACC_EVENT_OBJECT_SELECTION, - mParent, - wxOBJID_CLIENT, - item + 1); - - mLastId = item + 1; + mPath = *path; } -#endif } -// Retrieves the address of an IDispatch interface for the specified child. -// All objects must support this property. -wxAccStatus CheckListAx::GetChild( int childId, wxAccessible** child ) +VSTEffectsModule::~VSTEffectsModule() { - if( childId == wxACC_SELF ) +} + +// ============================================================================ +// IdentInterface implementation +// ============================================================================ + +wxString VSTEffectsModule::GetID() +{ + // Can be anything, but this is a v4 UUID + return wxT("c5520489-0253-418e-bdcd-daba3a227b28"); +} + +wxString VSTEffectsModule::GetPath() +{ + return mPath; +} + +wxString VSTEffectsModule::GetName() +{ + return _("VST Effects"); +} + +wxString VSTEffectsModule::GetVendor() +{ + return _("The Audacity Team"); +} + +wxString VSTEffectsModule::GetVersion() +{ + // This "may" be different if this were to be maintained as a separate DLL + return AUDACITY_VERSION_STRING; +} + +wxString VSTEffectsModule::GetDescription() +{ + return _("Adds the ability to use VST effects in Audacity."); +} + +// ============================================================================ +// ModuleInterface implementation +// ============================================================================ + +bool VSTEffectsModule::Initialize() +{ + // Nothing to do here + return true; +} + +void VSTEffectsModule::Terminate() +{ + // Nothing to do here + return; +} + +bool VSTEffectsModule::AutoRegisterPlugins(PluginManagerInterface & pm) +{ + // We don't auto-register + return true; +} + +wxArrayString VSTEffectsModule::FindPlugins(PluginManagerInterface & pm) +{ + wxArrayString pathList; + wxArrayString files; + + // Check for the VST_PATH environment variable + wxString vstpath = wxString::FromUTF8(getenv("VST_PATH")); + if (!vstpath.empty()) { - *child = this; - } - else - { - *child = NULL; - } - - return wxACC_OK; -} - -// Gets the number of children. -wxAccStatus CheckListAx::GetChildCount( int *childCount ) -{ - *childCount = mParent->GetItemCount(); - - return wxACC_OK; -} - -// Gets the default action for this object (0) or > 0 (the action for a child). -// Return wxACC_OK even if there is no action. actionName is the action, or the empty -// string if there is no action. -// The retrieved string describes the action that is performed on an object, -// not what the object does as a result. For example, a toolbar button that prints -// a document has a default action of "Press" rather than "Prints the current document." -wxAccStatus CheckListAx::GetDefaultAction( int WXUNUSED(childId), wxString *actionName ) -{ - actionName->Clear(); - - return wxACC_OK; -} - -// Returns the description for this object or a child. -wxAccStatus CheckListAx::GetDescription( int WXUNUSED(childId), wxString *description ) -{ - description->Clear(); - - return wxACC_OK; -} - -// Gets the window with the keyboard focus. -// If childId is 0 and child is NULL, no object in -// this subhierarchy has the focus. -// If this object has the focus, child should be 'this'. -wxAccStatus CheckListAx::GetFocus( int *childId, wxAccessible **child ) -{ - *childId = 0; - *child = this; - - return wxACC_OK; -} - -// Returns help text for this object or a child, similar to tooltip text. -wxAccStatus CheckListAx::GetHelpText( int WXUNUSED(childId), wxString *helpText ) -{ - helpText->Clear(); - - return wxACC_OK; -} - -// Returns the keyboard shortcut for this object or child. -// Return e.g. ALT+K -wxAccStatus CheckListAx::GetKeyboardShortcut( int WXUNUSED(childId), wxString *shortcut ) -{ - shortcut->Clear(); - - return wxACC_OK; -} - -// Returns the rectangle for this object (id = 0) or a child element (id > 0). -// rect is in screen coordinates. -wxAccStatus CheckListAx::GetLocation( wxRect& rect, int elementId ) -{ - if( elementId == wxACC_SELF ) - { - rect = mParent->GetRect(); - rect.SetPosition( mParent->GetParent()->ClientToScreen( rect.GetPosition() ) ); - } - else - { - if( elementId <= mParent->GetItemCount() ) + wxStringTokenizer tok(vstpath); + while (tok.HasMoreTokens()) { - mParent->GetItemRect( elementId - 1, rect, wxLIST_RECT_LABEL ); - rect.SetPosition( mParent->ClientToScreen( rect.GetPosition() ) ); + pathList.push_back(wxString(tok.GetNextToken())); } } - return wxACC_OK; -} +#if defined(__WXMAC__) +#define VSTPATH wxT("/Library/Audio/Plug-Ins/VST") -// Gets the name of the specified object. -wxAccStatus CheckListAx::GetName( int WXUNUSED(childId), wxString *name ) -{ - *name = mParent->GetName(); + // Look in /Library/Audio/Plug-Ins/VST and $HOME/Library/Audio/Plug-Ins/VST + pathList.push_back(VSTPATH); + pathList.push_back(wxString::FromUTF8(getenv("HOME")) + VSTPATH); - return wxACC_OK; -} + // Recursively search all paths for Info.plist files. This will identify all + // bundles. + pm.FindFilesInPathList(wxT("Info.plist"), pathList, files, true); -// Returns a role constant. -wxAccStatus CheckListAx::GetRole( int childId, wxAccRole *role ) -{ - if( childId == wxACC_SELF ) + // Remove the 'Contents/Info.plist' portion of the names + for (size_t i = 0; i < files.GetCount(); i++) { - *role = wxROLE_SYSTEM_LIST; - } - else - { - *role = wxROLE_SYSTEM_LISTITEM; - } - - return wxACC_OK; -} - -// Gets a variant representing the selected children -// of this object. -// Acceptable values: -// - a null variant (IsNull() returns TRUE) -// - a list variant (GetType() == wxT("list")) -// - an integer representing the selected child element, -// or 0 if this object is selected (GetType() == wxT("long")) -// - a "void*" pointer to a wxAccessible child object -wxAccStatus CheckListAx::GetSelections( wxVariant * WXUNUSED(selections) ) -{ - return wxACC_NOT_IMPLEMENTED; -} - -// Returns a state constant. -wxAccStatus CheckListAx::GetState( int childId, long *state ) -{ - int flag = wxACC_STATE_SYSTEM_FOCUSABLE; - - if( childId == wxACC_SELF ) - { - flag |= wxACC_STATE_SYSTEM_FOCUSED; - } - else - { - wxListItem item; - - item.SetId( childId - 1 ); - item.SetState( wxLIST_STATE_FOCUSED | wxLIST_STATE_SELECTED ); - item.SetMask( wxLIST_MASK_IMAGE | wxLIST_MASK_STATE ); - - if( mParent->GetItem( item ) ) + files[i] = wxPathOnly(wxPathOnly(files[i])); + if (!files[i].EndsWith(wxT(".vst"))) { - flag |= wxACC_STATE_SYSTEM_SELECTABLE; - - long state = item.GetState(); - - if( state & wxLIST_STATE_FOCUSED ) - { - flag |= wxACC_STATE_SYSTEM_FOCUSED; - } - - if( state & wxLIST_STATE_SELECTED ) - { - flag |= wxACC_STATE_SYSTEM_SELECTED; - } - - if( item.GetImage() != 0 ) - { - flag |= wxACC_STATE_SYSTEM_CHECKED; - } + files.RemoveAt(i--); } } - *state = flag; +#elif defined(__WXMSW__) - return wxACC_OK; -} + TCHAR dpath[MAX_PATH]; + TCHAR tpath[MAX_PATH]; + DWORD len; -// Returns a localized string representing the value for the object -// or child. -wxAccStatus CheckListAx::GetValue( int childId, wxString *strValue ) -{ - if( childId == 0 ) + // Try HKEY_CURRENT_USER registry key first + len = WXSIZEOF(tpath); + if (SHRegGetUSValue(wxT("Software\\VST"), + wxT("VSTPluginsPath"), + NULL, + tpath, + &len, + FALSE, + NULL, + 0) == ERROR_SUCCESS) { - return wxACC_OK; - } - else - { - *strValue = mParent->GetItemText( childId - 1 ); + tpath[len] = 0; + dpath[0] = 0; + ExpandEnvironmentStrings(tpath, dpath, WXSIZEOF(dpath)); + pathList.push_back(dpath); } - return wxACC_OK; -} - -#endif - -class PluginRegistrationDialog:public wxDialog { - public: - // constructors and destructors - PluginRegistrationDialog(wxWindow * parent, const wxArrayString & files); - virtual ~PluginRegistrationDialog(); - public: - void Populate(); - void PopulateOrExchange( ShuttleGui & S ); - - void OnApply(wxCommandEvent & event); - void OnCancel(wxCommandEvent & event); - void OnListChar(wxKeyEvent & event); - void OnListMouseDown(wxMouseEvent & event); - void OnSelectAll(wxCommandEvent & event); - void OnClearAll(wxCommandEvent & event); - - void SetBoldOrRegular( int i ); - void SetState(int i, int state); - void ToggleItem(int i); - -#if wxUSE_ACCESSIBILITY - CheckListAx *mAx; -#endif - - wxListCtrl *mPlugins; - wxArrayString mFiles; - wxArrayInt miState; - - bool mCancelClicked; - - DECLARE_EVENT_TABLE() -}; - - -#define PluginListID 7001 -#define PluginClearAllID 7002 -#define PluginSelectAllID 7003 - -BEGIN_EVENT_TABLE(PluginRegistrationDialog, wxDialog) - EVT_BUTTON(wxID_OK, PluginRegistrationDialog::OnApply) - EVT_BUTTON(wxID_CANCEL, PluginRegistrationDialog::OnCancel) - EVT_BUTTON(PluginClearAllID, PluginRegistrationDialog::OnClearAll) - EVT_BUTTON(PluginSelectAllID, PluginRegistrationDialog::OnSelectAll) -END_EVENT_TABLE() - -PluginRegistrationDialog::PluginRegistrationDialog(wxWindow * parent, const wxArrayString & files): - mFiles( files ), - wxDialog(parent, wxID_ANY, _("Install VST Effects"), - wxDefaultPosition, wxDefaultSize, - wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) -{ - mPlugins = NULL; - SetLabel(_("Install VST Effects")); // Provide visual label - SetName(_("Install VST Effects")); // Provide audible label - Populate(); - SetReturnCode( wxID_OK); -} - -PluginRegistrationDialog::~PluginRegistrationDialog() -{ - mPlugins->Disconnect(wxEVT_LEFT_DOWN, - wxMouseEventHandler(PluginRegistrationDialog::OnListMouseDown), - NULL, - this); - mPlugins->Disconnect(wxEVT_KEY_DOWN, - wxKeyEventHandler(PluginRegistrationDialog::OnListChar), - NULL, - this); -} - -void PluginRegistrationDialog::Populate() -{ - //------------------------- Main section -------------------- - ShuttleGui S(this, eIsCreating); - PopulateOrExchange(S); - // ----------------------- End of main section -------------- -} - -/// Defines the dialog and does data exchange with it. -void PluginRegistrationDialog::PopulateOrExchange(ShuttleGui &S) -{ - wxImageList * pImageList = new wxImageList( 16, 16 ); - -#define SHOW_UNCHECKED (0) -#define SHOW_CHECKED (1) -#define SHOW_ARROW (2) - -#define COL_NAME (0) -#define COL_PATH (1) - - pImageList->Add(wxIcon(unchecked_xpm)); - pImageList->Add(wxIcon(checked_xpm)); - pImageList->Add(wxIcon(arrow15x15_xpm)); - - S.StartVerticalLay(true); + // Then try HKEY_LOCAL_MACHINE registry key + len = WXSIZEOF(tpath); + if (SHRegGetUSValue(wxT("Software\\VST"), + wxT("VSTPluginsPath"), + NULL, + tpath, + &len, + TRUE, + NULL, + 0) == ERROR_SUCCESS) { - /*i18n-hint: The dialog shows a list of plugins with check-boxes - beside each one.*/ - S.StartStatic(_("&Select Plug-ins to Install or press ENTER to Install All"), true); - { - S.SetStyle(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_HRULES | wxLC_VRULES ); - mPlugins = S.Id(PluginListID).AddListControlReportMode(); - mPlugins->Connect(wxEVT_LEFT_DOWN, - wxMouseEventHandler(PluginRegistrationDialog::OnListMouseDown), - NULL, - this); - mPlugins->Connect(wxEVT_KEY_DOWN, - wxKeyEventHandler(PluginRegistrationDialog::OnListChar), - NULL, - this); -#if wxUSE_ACCESSIBILITY - mAx = new CheckListAx(mPlugins); - mPlugins->SetAccessible(mAx); -#endif - mPlugins->AssignImageList( pImageList, wxIMAGE_LIST_SMALL ); - mPlugins->InsertColumn(COL_NAME, _("Plug-in Name")); - mPlugins->InsertColumn(COL_PATH, _("Path")); - } - S.EndStatic(); - - S.StartHorizontalLay(wxALIGN_LEFT | wxEXPAND, false); - { - S.SetBorder(10); - S.StartHorizontalLay(wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); - { - S.AddSpace(12); - S.SetBorder(6); - S.Id(PluginSelectAllID).AddButton(_("Select &All")); - S.Id(PluginClearAllID).AddButton(_("Clea&r All")); - } - S.EndHorizontalLay(); - - S.StartHorizontalLay(wxALIGN_CENTER | wxEXPAND); - { - S.AddSpace(1); - } - S.EndHorizontalLay(); - - S.AddStandardButtons(eOkButton | eCancelButton); - } - S.EndHorizontalLay(); + tpath[len] = 0; + dpath[0] = 0; + ExpandEnvironmentStrings(tpath, dpath, WXSIZEOF(dpath)); + pathList.push_back(dpath); } - S.EndVerticalLay(); - // The dc is used to compute the text width in pixels. - // FIXME: That works fine for PC, but apparently comes out too small for wxMAC. - // iLen is minimum width in pixels shown for the file names. 200 is reasonable. - int iNameLen = 0; - int iPathLen = 0; - int x, y; - wxRect iconrect; - for (int i = 0; i < (int)mFiles.GetCount(); i++) - { - miState.Add( SHOW_CHECKED ); + // Add the default path last + dpath[0] = 0; + ExpandEnvironmentStrings(wxT("%ProgramFiles%\\Steinberg\\VSTPlugins"), + dpath, + WXSIZEOF(dpath)); + pathList.push_back(dpath); - wxFileName fn(mFiles[i]); - wxString name( fn.GetName() ); - wxString path( fn.GetFullPath() ); + // Recursively scan for all DLLs + pm.FindFilesInPathList(wxT("*.dll"), pathList, files); - mPlugins->InsertItem( i, name, SHOW_CHECKED ); - mPlugins->SetItem( i, COL_PATH, path ); - - // Only need to get the icon width once - if (i == 0) - { -#if defined(__WXMAC__) - // wxMac doesn't return the ICON rectangle. It returns the - // rectangle for the first column and that even comes back - // with negative numbers sometimes. - // - // So, just guess. - wxIcon i1(unchecked_xpm); - wxIcon i2(checked_xpm); - wxIcon i3(arrow15x15_xpm); - iconrect.x = 4; - iconrect.width = wxMax(wxMax(i1.GetWidth(), i2.GetWidth()), i3.GetWidth()); #else - mPlugins->GetItemRect( i, iconrect, wxLIST_RECT_ICON ); -#endif - } - mPlugins->GetTextExtent( name, &x, &y ); - iNameLen = wxMax( iNameLen, x + iconrect.width + (iconrect.x * 2) ); - mPlugins->GetTextExtent( path, &x, &y ); - iPathLen = wxMax( iPathLen, x + iconrect.width + (iconrect.x * 2) ); - } - mPlugins->SetColumnWidth(COL_NAME, iNameLen + /* fudge */ 5); - mPlugins->SetColumnWidth(COL_PATH, iPathLen + /* fudge */ 5); - - //SetBoldOrRegular( miSelected ); - mPlugins->SetSizeHints( iNameLen + iPathLen + /* fudge */ 15 , 200 ); - if( mFiles.GetCount() > 0 ) + // Nothing specified in the VST_PATH environment variable...provide defaults + if (vstpath.IsEmpty()) { - // Make sure first item is selected/focused. - mPlugins->SetFocus(); - mPlugins->SetItemState( 0, wxLIST_STATE_FOCUSED|wxLIST_STATE_SELECTED, wxLIST_STATE_FOCUSED|wxLIST_STATE_SELECTED); -#if wxUSE_ACCESSIBILITY - mAx->SetSelected( 0 ); -#endif - } - Layout(); - Fit(); - SetSizeHints(GetSize()); - // Parent window is usually not there yet, so centre on screen rather than on parent. - CenterOnScreen(); + // We add this "non-default" one + pathList.Add(wxT(LIBDIR) wxT("/vst")); + // These are the defaults used by other hosts + pathList.Add(wxT("/usr/lib/vst")); + pathList.Add(wxT("/usr/local/lib/vst")); + pathList.Add(wxString(wxGetHomeDir()) + wxFILE_SEP_PATH + wxT(".vst")); + } + + // Recursively scan for all shared objects + pm.FindFilesInPathList(wxT("*.so"), pathList, files); + +#endif + + return files; } -void PluginRegistrationDialog::OnListMouseDown( wxMouseEvent & event ) +bool VSTEffectsModule::RegisterPlugin(PluginManagerInterface & pm, const wxString & path) { - wxPoint p = event.GetPosition(); - int flags = wxLIST_HITTEST_ONITEM; - int item = mPlugins->HitTest( p, flags ); + // TODO: Fix this for external usage + wxString cmdpath = PlatformCompatibility::GetExecutablePath(); - if( item != wxNOT_FOUND ) + wxString cmd; + cmd.Printf(wxT("\"%s\" %s \"%s\""), cmdpath.c_str(), VSTCMDKEY, path.c_str()); + + VSTSubProcess *proc = new VSTSubProcess(); + try { - ToggleItem( item ); + wxExecute(cmd, wxEXEC_SYNC | wxEXEC_NODISABLE, proc); + } + catch (...) + { + wxLogMessage(_("VST plugin registration failed for %s\n"), path.c_str()); + return false; } - event.Skip(); -} + wxString output; + wxStringOutputStream ss(&output); + proc->GetInputStream()->Read(ss); -void PluginRegistrationDialog::OnListChar( wxKeyEvent & event ) -{ - switch( event.GetKeyCode() ) + int keycount = 0; + wxStringTokenizer tzr(output, wxT("\n")); + while (tzr.HasMoreTokens()) { - case WXK_SPACE: + wxString line = tzr.GetNextToken(); + + // Our output may follow any output the plugin may have written. + if (!line.StartsWith(OUTPUTKEY)) { - int iItem = mPlugins->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED); - - if( iItem != wxNOT_FOUND ) - { - ToggleItem( iItem ); - } + continue; } - break; - case WXK_RETURN: - // Don't know why wxListCtrls prevent default dialog action, - // but they do, so handle it. - EmulateButtonClickIfPresent( GetAffirmativeId() ); - break; + wxString key = line.Mid(wxStrlen(OUTPUTKEY)).BeforeFirst(wxT('=')); + wxString val = line.AfterFirst(wxT('=')).BeforeFirst(wxT('\r')); - default: - event.Skip(); - break; - } -} - -void PluginRegistrationDialog::SetBoldOrRegular( int i ) -{ - wxFont Font = mPlugins->GetItemFont( i ); - Font.SetWeight( (miState[i]==SHOW_CHECKED)? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL ); - mPlugins->SetItemFont( i, Font ); -} - -// We can't capture mouse clicks, only selected and deselected. -// Clicking on a selected item does not generate any event. -// Therefore our workaround solution is to NEVER actually select. -// So whenever the code tries to , we cancel the selection. -// That way we continue to get events. -void PluginRegistrationDialog::SetState(int i, int state) -{ - miState[ i ] = state; - mPlugins->SetItemImage( i, miState[i] ); -#if wxUSE_ACCESSIBILITY - mAx->SetSelected( i ); -#endif -} - -void PluginRegistrationDialog::ToggleItem(int i) -{ - SetState( i, miState[ i ] == SHOW_CHECKED ? SHOW_UNCHECKED : SHOW_CHECKED ); -} - -void PluginRegistrationDialog::OnSelectAll(wxCommandEvent & WXUNUSED(event)) -{ - for( size_t i = 0, cnt = miState.GetCount(); i < cnt; i++ ) - { - SetState(i, SHOW_CHECKED); - } -} - -void PluginRegistrationDialog::OnClearAll(wxCommandEvent & WXUNUSED(event)) -{ - for( size_t i = 0, cnt = miState.GetCount(); i < cnt; i++ ) - { - SetState(i, SHOW_UNCHECKED); - } -} - -void PluginRegistrationDialog::OnApply(wxCommandEvent & WXUNUSED(event)) -{ - mCancelClicked = false; - FindWindowById(wxID_OK)->Disable(); - - size_t cnt = mFiles.GetCount(); - for (size_t i = 0; i < cnt && !mCancelClicked; i++) { - wxString file = mFiles[i]; - - mPlugins->EnsureVisible( i ); - if( miState[ i ] == SHOW_CHECKED ) + if (key.IsSameAs(KEY_ID)) { - mPlugins->SetItemImage( i, SHOW_ARROW ); - VSTEffect::ScanOnePlugin( file ); - mPlugins->SetItemImage( i, SHOW_CHECKED ); + proc->mID = val; + keycount++; + } + else if (key.IsSameAs(KEY_NAME)) + { + proc->mName = val; + keycount++; + } + else if (key.IsSameAs(KEY_PATH)) + { + proc->mPath = val; + keycount++; + } + else if (key.IsSameAs(KEY_VENDOR)) + { + proc->mVendor = val; + keycount++; + } + else if (key.IsSameAs(KEY_VERSION)) + { + proc->mVersion = val; + keycount++; + } + else if (key.IsSameAs(KEY_DESCRIPTION)) + { + proc->mDescription = val; + keycount++; + } + else if (key.IsSameAs(KEY_EFFECTTYPE)) + { + long type; + val.ToLong(&type); + proc->mType = (EffectType) type; + keycount++; + } + else if (key.IsSameAs(KEY_INTERACTIVE)) + { + proc->mInteractive = val.IsSameAs(wxT("1")); + keycount++; } - wxYield(); } - EndModal(mCancelClicked ? wxID_CANCEL : wxID_OK); + bool valid = keycount == 8; + + if (valid) + { + pm.RegisterEffectPlugin(this, proc); + } + + delete proc; + + return valid; } -void PluginRegistrationDialog::OnCancel(wxCommandEvent & WXUNUSED(event)) +void *VSTEffectsModule::CreateInstance(const PluginID & WXUNUSED(ID), + const wxString & path) { - mCancelClicked = true; + // For us, the ID is simply the path to the effect + return new VSTEffect(path); +} - EndModal(mCancelClicked ? wxID_CANCEL : wxID_OK); +// ============================================================================ +// ModuleEffectInterface implementation +// ============================================================================ + +// ============================================================================ +// VSTEffectsModule implementation +// ============================================================================ + +// static +// +// Called from reinvokation of Audacity or DLL to check in a separate process +void VSTEffectsModule::Check(const wxChar *path) +{ + VSTEffect *effect = new VSTEffect(path); + if (effect) + { + if (effect->Startup()) + { + wxPrintf(OUTPUTKEY KEY_ID wxT("=%s\n"), effect->GetID().c_str()); + wxPrintf(OUTPUTKEY KEY_PATH wxT("=%s\n"), effect->GetPath().c_str()); + wxPrintf(OUTPUTKEY KEY_NAME wxT("=%s\n"), effect->GetName().c_str()); + wxPrintf(OUTPUTKEY KEY_VENDOR wxT("=%s\n"), effect->GetVendor().c_str()); + wxPrintf(OUTPUTKEY KEY_VERSION wxT("=%s\n"), effect->GetVersion().c_str()); + wxPrintf(OUTPUTKEY KEY_DESCRIPTION wxT("=%s\n"), effect->GetDescription().c_str()); + wxPrintf(OUTPUTKEY KEY_EFFECTTYPE wxT("=%d\n"), effect->GetType()); + wxPrintf(OUTPUTKEY KEY_INTERACTIVE wxT("=%d\n"), effect->IsInteractive()); + } + + delete effect; + } } /////////////////////////////////////////////////////////////////////////////// @@ -761,30 +585,43 @@ void PluginRegistrationDialog::OnCancel(wxCommandEvent & WXUNUSED(event)) class VSTEffectSettingsDialog:public wxDialog { - public: - VSTEffectSettingsDialog(wxWindow * parent); +public: + VSTEffectSettingsDialog(wxWindow * parent, EffectHostInterface *host); virtual ~VSTEffectSettingsDialog(); void PopulateOrExchange(ShuttleGui & S); void OnOk(wxCommandEvent & evt); - private: - int mBufferSize; +private: + EffectHostInterface *mHost; + int mBufferSize; + bool mUseBufferDelay; + bool mUseGUI; + bool mRescan; - DECLARE_EVENT_TABLE() + DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(VSTEffectSettingsDialog, wxDialog) EVT_BUTTON(wxID_OK, VSTEffectSettingsDialog::OnOk) END_EVENT_TABLE() -VSTEffectSettingsDialog::VSTEffectSettingsDialog(wxWindow * parent) +VSTEffectSettingsDialog::VSTEffectSettingsDialog(wxWindow * parent, EffectHostInterface *host) : wxDialog(parent, wxID_ANY, wxString(_("VST Effect Settings"))) { - gPrefs->Read(wxT("/VST/BufferSize"), &mBufferSize, 8192); +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) && defined(__WXMAC__) + HIWindowChangeClass((WindowRef) MacGetWindowRef(), kMovableModalWindowClass); +#endif - ShuttleGui S(this, eIsCreatingFromPrefs); + mHost = host; + + mHost->GetSharedConfig(wxT("Settings"), wxT("BufferSize"), mBufferSize, 8192); + mHost->GetSharedConfig(wxT("Settings"), wxT("UseBufferDelay"), mUseBufferDelay, true); + mHost->GetSharedConfig(wxT("Settings"), wxT("UseGUI"), mUseGUI, true); + mHost->GetSharedConfig(wxT("Settings"), wxT("Rescan"), mRescan, false); + + ShuttleGui S(this, eIsCreating); PopulateOrExchange(S); } @@ -815,8 +652,8 @@ void VSTEffectSettingsDialog::PopulateOrExchange(ShuttleGui & S) { wxTextCtrl *t; t = S.TieNumericTextBox(_("&Buffer Size (8 to 1048576 samples):"), - wxT("/VST/BufferSize"), - wxT(""), 12); + mBufferSize, + 12); t->SetMinSize(wxSize(100, -1)); t->SetValidator(vld); } @@ -835,7 +672,8 @@ void VSTEffectSettingsDialog::PopulateOrExchange(ShuttleGui & S) S.StartHorizontalLay(wxALIGN_LEFT); { - S.TieCheckBox(_("Enable &compensation"), wxT("/VST/UseBufferDelay"), true); + S.TieCheckBox(_("Enable &compensation"), + mUseBufferDelay); } S.EndHorizontalLay(); } @@ -843,12 +681,12 @@ void VSTEffectSettingsDialog::PopulateOrExchange(ShuttleGui & S) S.StartStatic(_("Graphical Mode")); { - S.AddVariableText( - wxString() + + S.AddVariableText(wxString() + _("Most VST effects have a graphical interface for setting parameter values.") + _(" A basic text-only method is also available. ") + _(" Reopen the effect for this to take effect."))->Wrap(650); - S.TieCheckBox(_("Enable &Graphical Mode"), wxT("/VST/GUI"), true); + S.TieCheckBox(_("Enable &graphical interface"), + mUseGUI); } S.EndStatic(); @@ -859,7 +697,8 @@ void VSTEffectSettingsDialog::PopulateOrExchange(ShuttleGui & S) _("once and relevant information is recorded. When you add VST effects ") + _("to your system, you need to tell Audacity to rescan so the new ") + _("information can be recorded."))->Wrap(650); - S.TieCheckBox(_("&Rescan effects on next launch"), wxT("/VST/Rescan"), false); + S.TieCheckBox(_("&Rescan effects on next launch"), + mRescan); } S.EndStatic(); } @@ -876,13 +715,19 @@ void VSTEffectSettingsDialog::PopulateOrExchange(ShuttleGui & S) void VSTEffectSettingsDialog::OnOk(wxCommandEvent & WXUNUSED(evt)) { - if (!Validate()) { + if (!Validate()) + { return; } - ShuttleGui S(this, eIsSavingToPrefs); + ShuttleGui S(this, eIsGettingFromDialog); PopulateOrExchange(S); + mHost->SetSharedConfig(wxT("Settings"), wxT("BufferSize"), mBufferSize); + mHost->SetSharedConfig(wxT("Settings"), wxT("UseBufferDelay"), mUseBufferDelay); + mHost->SetSharedConfig(wxT("Settings"), wxT("UseGUI"), mUseGUI); + mHost->SetSharedConfig(wxT("Settings"), wxT("Rescan"), mRescan); + EndModal(wxID_OK); } @@ -893,18 +738,23 @@ void VSTEffectSettingsDialog::OnOk(wxCommandEvent & WXUNUSED(evt)) /////////////////////////////////////////////////////////////////////////////// DECLARE_LOCAL_EVENT_TYPE(EVT_SIZEWINDOW, -1); DEFINE_LOCAL_EVENT_TYPE(EVT_SIZEWINDOW); + DECLARE_LOCAL_EVENT_TYPE(EVT_UPDATEDISPLAY, -1); DEFINE_LOCAL_EVENT_TYPE(EVT_UPDATEDISPLAY); class VSTEffectDialog:public wxDialog, XMLTagHandler { - public: +public: VSTEffectDialog(wxWindow * parent, const wxString & title, VSTEffect *effect, AEffect *aeffect); virtual ~VSTEffectDialog(); + void EnableApply(bool enable); + +private: + void RemoveHandler(); void OnProgram(wxCommandEvent & evt); @@ -913,42 +763,50 @@ class VSTEffectDialog:public wxDialog, XMLTagHandler void OnSave(wxCommandEvent & evt); void OnSettings(wxCommandEvent & evt); - void OnSlider(wxCommandEvent &event); + void OnSlider(wxCommandEvent & evt); +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + void OnApply(wxCommandEvent & evt); +#else void OnOk(wxCommandEvent & evt); void OnCancel(wxCommandEvent & evt); - void OnClose(wxCloseEvent & evt); void OnPreview(wxCommandEvent & evt); +#endif + + void OnDefaults(wxCommandEvent & evt); + void OnClose(wxCloseEvent & evt); void OnSizeWindow(wxCommandEvent & evt); void OnUpdateDisplay(wxCommandEvent & evt); -private: - void BuildPlain(); void BuildFancy(); wxSizer *BuildProgramBar(); void RefreshParameters(int skip = -1); + // Program/Bank loading/saving + bool LoadFXB(const wxFileName & fn); + bool LoadFXP(const wxFileName & fn); + bool LoadXML(const wxFileName & fn); + bool LoadFXProgram(unsigned char **bptr, ssize_t & len, int index, bool dryrun); + void SaveFXB(const wxFileName & fn); + void SaveFXP(const wxFileName & fn); + void SaveXML(const wxFileName & fn); + void SaveFXProgram(wxMemoryBuffer & buf, int index); + virtual bool HandleXMLTag(const wxChar *tag, const wxChar **attrs); virtual void HandleXMLEndTag(const wxChar *tag); virtual void HandleXMLContent(const wxString & content); virtual XMLTagHandler *HandleXMLChild(const wxChar *tag); - wxString b64encode(const void *in, int len); - int b64decode(wxString in, void *out); + +private: VSTEffect *mEffect; AEffect *mAEffect; bool mGui; -#if defined(__WXMAC__) wxSizerItem *mContainer; -#elif defined(__WXMSW__) - wxSizerItem *mContainer; -#else - wxSizerItem *mContainer; -#endif wxComboBox *mProgram; wxStaticText **mNames; @@ -968,13 +826,20 @@ private: WindowRef mOverlayRef; EventHandlerUPP mOverlayEventHandlerUPP; EventHandlerRef mOverlayEventHandlerRef; - bool mOverlayEventsBlocked; WindowRef mWindowRef; + WindowRef mPreviousRef; EventHandlerUPP mWindowEventHandlerUPP; EventHandlerRef mWindowEventHandlerRef; - WindowRef mPreviousRef; +#elif defined(__WXMSW__) + + HANDLE mHwnd; + +#else + + Display *mXdisp; + Window mXwin; #endif @@ -991,9 +856,17 @@ enum }; BEGIN_EVENT_TABLE(VSTEffectDialog, wxDialog) + EVT_CLOSE(VSTEffectDialog::OnClose) + +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + EVT_BUTTON(wxID_APPLY, VSTEffectDialog::OnApply) +#else EVT_BUTTON(wxID_OK, VSTEffectDialog::OnOk) EVT_BUTTON(wxID_CANCEL, VSTEffectDialog::OnCancel) EVT_BUTTON(ID_EFFECT_PREVIEW, VSTEffectDialog::OnPreview) +#endif + + EVT_BUTTON(eDefaultsID, VSTEffectDialog::OnDefaults) EVT_COMBOBOX(ID_VST_PROGRAM, VSTEffectDialog::OnProgram) EVT_TEXT(ID_VST_PROGRAM, VSTEffectDialog::OnProgramText) @@ -1010,6 +883,10 @@ END_EVENT_TABLE() #if defined(__WXMAC__) +// To use, change the SDK in the project to at least 10.5 +extern void DebugPrintControlHierarchy(WindowRef inWindow); +extern void DebugPrintWindowList(void); + // ---------------------------------------------------------------------------- // Most of the following is used to deal with VST effects that create an overlay // window on top of ours. This is usually done because Cocoa is being used @@ -1037,9 +914,10 @@ END_EVENT_TABLE() // Events to be captured in the overlay window static const EventTypeSpec OverlayEventList[] = { +#if !defined(EXPERIMENTAL_REALTIME_EFFECTS) { kEventClassWindow, kEventWindowGetClickModality }, - { kEventClassWindow, kEventWindowHandleActivate }, - { kEventClassWindow, kEventWindowActivated }, +#endif +#if 0 { kEventClassMouse, kEventMouseDown }, { kEventClassMouse, kEventMouseUp }, { kEventClassMouse, kEventMouseMoved }, @@ -1047,6 +925,7 @@ static const EventTypeSpec OverlayEventList[] = { kEventClassMouse, kEventMouseEntered }, { kEventClassMouse, kEventMouseExited }, { kEventClassMouse, kEventMouseWheelMoved }, +#endif }; // Overlay window event handler callback thunk @@ -1058,7 +937,7 @@ pascal OSStatus VSTEffectDialog::OverlayEventHandler(EventHandlerCallRef handler // Overlay window event handler OSStatus VSTEffectDialog::OnOverlayEvent(EventHandlerCallRef handler, EventRef event) { - // Get the current window in from of all the rest non-floaters. + // Get the current window in front of all the rest of the non-floaters. WindowRef frontwin = FrontNonFloatingWindow(); // Get the target window of the event @@ -1070,10 +949,10 @@ OSStatus VSTEffectDialog::OnOverlayEvent(EventHandlerCallRef handler, EventRef e sizeof(evtwin), NULL, &evtwin); - +#define DEBUG_VST #if defined(DEBUG_VST) int cls = GetEventClass(event); - printf("WINDOW class %4.4s kind %d ewin %p owin %p mwin %p anf %p fnf %p\n", + printf("OVERLAY class %4.4s kind %d ewin %p owin %p mwin %p anf %p fnf %p\n", &cls, GetEventKind(event), evtwin, @@ -1083,16 +962,53 @@ OSStatus VSTEffectDialog::OnOverlayEvent(EventHandlerCallRef handler, EventRef e frontwin); #endif + bool block = false; + WindowModality kind; + WindowRef ref = NULL; + GetWindowModality(frontwin, &kind, &ref); + + switch (kind) + { + case kWindowModalityNone: + { + // Allow + } + break; + + case kWindowModalityWindowModal: + { + if (ref == mWindowRef || ref == mOverlayRef) + { + block = true; + } + } + break; + + case kWindowModalitySystemModal: + case kWindowModalityAppModal: + { + if (frontwin != mWindowRef && frontwin != mOverlayRef) + { + block = true; + } + } + break; + } + // We must block mouse events because plugins still act on mouse // movement and drag events, even if they are supposed to be disabled // due to other modal dialogs (like when Load or Settings are clicked). - if (GetEventClass(event) == kEventClassMouse) { - if (mOverlayEventsBlocked) { + if (GetEventClass(event) == kEventClassMouse) + { + if (block) + { return noErr; } + + return eventNotHandledErr; } - // Only kEventClassWindow event at this poine + // Only kEventClassWindow events at this point switch (GetEventKind(event)) { // The system is asking if the target of an upcoming event @@ -1100,27 +1016,11 @@ OSStatus VSTEffectDialog::OnOverlayEvent(EventHandlerCallRef handler, EventRef e // // We allow it when the overlay window or our window is the // curret top window. Any other windows would mean that a - // modal dialog box has been open on top and we should block. + // modal dialog box has been opened on top and we should block. case kEventWindowGetClickModality: { - HIModalClickResult res = kHIModalClickIsModal; - WindowRef ref = mWindowRef; - - // Allow it to pass? - if (frontwin == mWindowRef | frontwin == mOverlayRef) { - res |= kHIModalClickAllowEvent; // | kHIModalClickRaiseWindow; - mOverlayEventsBlocked = false; - } - // No, block it - else { - res |= kHIModalClickAnnounce; - ref = frontwin; - mOverlayEventsBlocked = true; - } - - // Get the kind of modal block from the modal window - WindowModality kind; - GetWindowModality(ref, &kind, NULL); + // Announce the event may need blocking + HIModalClickResult res = block ? kHIModalClickIsModal | kHIModalClickAnnounce : 0; // Set the return parameters SetEventParameter(event, @@ -1141,15 +1041,14 @@ OSStatus VSTEffectDialog::OnOverlayEvent(EventHandlerCallRef handler, EventRef e sizeof(res), &res); - return noErr; - } - break; - - // Ignore the activate events to (sort of) keep our window as - // the active one - case kEventWindowHandleActivate: - case kEventWindowActivated: - { +#if !defined(EXPERIMENTAL_REALTIME_EFFECTS) + // If the front window is the overlay, then make our window + // the selected one so that the mouse click goes to it instead. + if (frontwin == mOverlayRef) + { + SelectWindow(mWindowRef); + } +#endif return noErr; } break; @@ -1161,11 +1060,18 @@ OSStatus VSTEffectDialog::OnOverlayEvent(EventHandlerCallRef handler, EventRef e // Events to be captured in the our window static const EventTypeSpec WindowEventList[] = { + { kEventClassWindow, kEventWindowGetClickModality }, { kEventClassWindow, kEventWindowShown }, { kEventClassWindow, kEventWindowClose }, - { kEventClassWindow, kEventWindowGetClickModality }, - { kEventClassWindow, kEventWindowHandleDeactivate }, - { kEventClassWindow, kEventWindowDeactivated }, +#if 0 + { kEventClassMouse, kEventMouseDown }, + { kEventClassMouse, kEventMouseUp }, + { kEventClassMouse, kEventMouseMoved }, + { kEventClassMouse, kEventMouseDragged }, + { kEventClassMouse, kEventMouseEntered }, + { kEventClassMouse, kEventMouseExited }, + { kEventClassMouse, kEventMouseWheelMoved }, +#endif }; // Our window event handler callback thunk @@ -1202,12 +1108,58 @@ OSStatus VSTEffectDialog::OnWindowEvent(EventHandlerCallRef handler, EventRef ev frontwin); #endif - // Only kEventClassWindow event at this poine + bool block = false; + WindowModality kind; + WindowRef ref = NULL; + GetWindowModality(frontwin, &kind, &ref); + + switch (kind) + { + case kWindowModalityNone: + { + // Allow + } + break; + + case kWindowModalityWindowModal: + { + if (ref == mWindowRef || ref == mOverlayRef) + { + block = true; + } + } + break; + + case kWindowModalitySystemModal: + case kWindowModalityAppModal: + { + if (frontwin != mWindowRef && frontwin != mOverlayRef) + { + block = true; + } + } + break; + } + + // We must block mouse events because plugins still act on mouse + // movement and drag events, even if they are supposed to be disabled + // due to other modal dialogs (like when Load or Settings are clicked). + if (GetEventClass(event) == kEventClassMouse) + { + if (block) + { + return noErr; + } + + return eventNotHandledErr; + } + + // Only kEventClassWindow events at this point switch (GetEventKind(event)) { - // If we don't capture the close event Audacity, will crash attermination + // If we don't capture the close event, Audacity will crash at termination // since the window is still on the wxWidgets toplevel window lists, but - // it's already gone. + // it has already been deleted from the system. case kEventWindowClose: { RemoveHandler(); @@ -1224,16 +1176,19 @@ OSStatus VSTEffectDialog::OnWindowEvent(EventHandlerCallRef handler, EventRef ev case kEventWindowShown: { // Have an overlay? - mOverlayRef = GetPreviousWindow(mWindowRef); - if (mOverlayRef == mPreviousRef) { - mOverlayRef = mWindowRef; - } + WindowRef newprev = GetPreviousWindow(mWindowRef); - if (mOverlayRef != mWindowRef) + if (newprev != mPreviousRef) { - // Try again + // We have an overlay + mOverlayRef = newprev; - // Install the handler + // Set our window's activatino scope to make sure it alway + // stays active. + SetWindowActivationScope(mWindowRef, + kWindowActivationScopeIndependent); + + // Install the overlay handler mOverlayEventHandlerUPP = NewEventHandlerUPP(OverlayEventHandler); InstallWindowEventHandler(mOverlayRef, mOverlayEventHandlerUPP, @@ -1241,6 +1196,12 @@ OSStatus VSTEffectDialog::OnWindowEvent(EventHandlerCallRef handler, EventRef ev OverlayEventList, this, &mOverlayEventHandlerRef); + +//#if !defined(EXPERIMENTAL_REALTIME_EFFECTS) + // Since we set the activation scope to independent, + // we need to make sure the overlay gets activated. + ActivateWindow(mOverlayRef, TRUE); +//#endif } } break; @@ -1250,30 +1211,11 @@ OSStatus VSTEffectDialog::OnWindowEvent(EventHandlerCallRef handler, EventRef ev // // We allow it when the overlay window or our window is the // curret top window. Any other windows would mean that a - // modal dialog box has been open on top and we should block. + // modal dialog box has been opened on top and we should block. case kEventWindowGetClickModality: { - // No overlay present, so leave this up to the system - if (mOverlayRef == mWindowRef) { - break; - } - - HIModalClickResult res = kHIModalClickIsModal; - WindowRef ref = mWindowRef; - - // Allow it to pass? - if (frontwin == mWindowRef | frontwin == mOverlayRef) { - res |= kHIModalClickAllowEvent; // | kHIModalClickRaiseWindow; - } - // No, block it - else { - res |= kHIModalClickAnnounce; - ref = frontwin; - } - - // Get the kind of modal block from the modal window - WindowModality kind; - GetWindowModality(ref, &kind, NULL); + // Announce the event may need blocking + HIModalClickResult res = block ? kHIModalClickIsModal | kHIModalClickAnnounce : 0; // Set the return parameters SetEventParameter(event, @@ -1294,27 +1236,17 @@ OSStatus VSTEffectDialog::OnWindowEvent(EventHandlerCallRef handler, EventRef ev sizeof(res), &res); - // The mouse click will activate the our window, but we want any - // control underneath the mouse to get the click instead. Activating - // the main window here will allow the click to pass through to the - // control. - ActivateWindow(ref, TRUE); - - return noErr; - } - break; - - // Instead of deactivating our window, we actually do the opposite by - // activate it. This helps to ensure it says highlighted and raised. - case kEventWindowHandleDeactivate: - case kEventWindowDeactivated: - { - // No overlay present, so leave this up to the system - if (mOverlayRef == mWindowRef) { - break; + if (mOverlayRef) + { + // If the front window is the overlay, then make our window + // the selected one so that the mouse click go to it instead. + WindowRef act = ActiveNonFloatingWindow(); + if (frontwin == mOverlayRef || act == NULL || act == mOverlayRef) + { + SelectWindow(mWindowRef); + } } - ActivateWindow(mWindowRef, TRUE); return noErr; } break; @@ -1324,6 +1256,15 @@ OSStatus VSTEffectDialog::OnWindowEvent(EventHandlerCallRef handler, EventRef ev } #endif +#if defined(__WXGTK__) + +static int trappedErrorCode = 0; +static int X11TrapHandler(Display *, XErrorEvent *err) +{ + return 0; +} +#endif + VSTEffectDialog::VSTEffectDialog(wxWindow *parent, const wxString & title, VSTEffect *effect, @@ -1339,61 +1280,75 @@ VSTEffectDialog::VSTEffectDialog(wxWindow *parent, mContainer = NULL; #if defined(__WXMAC__) + +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + HIWindowChangeClass((WindowRef) MacGetWindowRef(), kFloatingWindowClass); +#endif + mOverlayRef = 0; mOverlayEventHandlerUPP = 0; mOverlayEventHandlerRef = 0; - mOverlayEventsBlocked = true; mWindowRef = 0; mWindowEventHandlerUPP = 0; mWindowEventHandlerRef = 0; +#elif defined(__WXMSW__) + mHwnd = 0; +#else + mXdisp = NULL; + mXwin = NULL; #endif // Determine if the VST editor is supposed to be used or not - mGui = (gPrefs->Read(wxT("/VST/GUI"), (long) true) != 0) && - mAEffect->flags & effFlagsHasEditor; + mEffect->mHost->GetSharedConfig(wxT("Settings"), + wxT("UseGUI"), + mGui, + true); + mGui = mAEffect->flags & effFlagsHasEditor ? mGui : false; // Must use the GUI editor if parameters aren't provided - if (mAEffect->numParams == 0 && mAEffect->flags & effFlagsHasEditor) + if (mAEffect->numParams == 0) { mGui = true; } -#if defined(__WXGTK__) - // Let the user know that a GUI interface is not supported in wxGTK - if (mGui) { - wxMessageBox(_("VST GUI interfaces are currently unsupported on Linux"), - _("VST Effect")); - mGui = false; - } -#endif - // Build the appropriate dialog type - if (mGui) { + if (mGui) + { BuildFancy(); } - else { + else + { BuildPlain(); } } VSTEffectDialog::~VSTEffectDialog() { + mEffect->InterfaceClosed(); + + mEffect->PowerOff(); + mEffect->NeedEditIdle(false); + RemoveHandler(); - if (mNames) { + if (mNames) + { delete [] mNames; } - if (mSliders) { + if (mSliders) + { delete [] mSliders; } - if (mDisplays) { + if (mDisplays) + { delete [] mDisplays; } - if (mLabels) { + if (mLabels) + { delete [] mLabels; } } @@ -1401,26 +1356,49 @@ VSTEffectDialog::~VSTEffectDialog() void VSTEffectDialog::RemoveHandler() { #if defined(__WXMAC__) - if (mOverlayEventHandlerRef) { + if (mWindowRef) + { + mEffect->callDispatcher(effEditClose, 0, 0, mWindowRef, 0.0); + mWindowRef = 0; + } + + if (mOverlayEventHandlerRef) + { ::RemoveEventHandler(mOverlayEventHandlerRef); mOverlayEventHandlerRef = 0; } - if (mOverlayEventHandlerUPP) { + if (mOverlayEventHandlerUPP) + { DisposeEventHandlerUPP(mOverlayEventHandlerUPP); mOverlayEventHandlerUPP = 0; } - if (mWindowEventHandlerRef) { + if (mWindowEventHandlerRef) + { ::RemoveEventHandler(mWindowEventHandlerRef); mWindowEventHandlerRef = 0; MacInstallTopLevelWindowEventHandler(); } - if (mWindowEventHandlerUPP) { + if (mWindowEventHandlerUPP) + { DisposeEventHandlerUPP(mWindowEventHandlerUPP); mWindowEventHandlerUPP = 0; } +#elif defined(__WXMSW__) + if (mHwnd) + { + mEffect->callDispatcher(effEditClose, 0, 0, mHwnd, 0.0); + mHwnd = 0; + } +#else + if (mXwin) + { + mEffect->callDispatcher(effEditClose, 0, (intptr_t)mXdisp, (void *)mXwin, 0.0); + mXdisp = NULL; + mXwin = NULL; + } #endif } @@ -1431,11 +1409,13 @@ void VSTEffectDialog::BuildFancy() short top, left, bottom, right; } *rect; + // Turn the power on...some effects need this when the editor is open + mEffect->PowerOn(); + // Some effects like to have us get their rect before opening them. mEffect->callDispatcher(effEditGetRect, 0, 0, &rect, 0.0); #if defined(__WXMAC__) - // Retrieve the current window and the one above it. The window list // is kept in top-most to bottom-most order, so we'll use that to // determine if another window was opened above ours. @@ -1460,10 +1440,13 @@ void VSTEffectDialog::BuildFancy() // Get the subview it created HIViewRef subview = HIViewGetFirstSubview(view); - if (subview == NULL) { + if (subview == NULL) + { // Doesn't seem the effect created the subview, so switch - // to the plain dialog - mEffect->callDispatcher(effEditClose, 0, 0, mWindowRef, 0.0); + // to the plain dialog. This can happen when an effect + // uses the content view directly. As of this time, we + // will not try to support those and fall back to the + // textual interface. mGui = false; RemoveHandler(); BuildPlain(); @@ -1472,11 +1455,27 @@ void VSTEffectDialog::BuildFancy() #elif defined(__WXMSW__) - wxWindow *w = new wxPanel(this, wxID_ANY); - mEffect->callDispatcher(effEditOpen, 0, 0, w->GetHWND(), 0.0); + wxPanel *w = new wxPanel(this, wxID_ANY); + mHwnd = w->GetHWND(); + mEffect->callDispatcher(effEditOpen, 0, 0, mHwnd, 0.0); #else + // Use a panel to host the plugins GUI + wxPanel *w = new wxPanel(this); + + // Make sure is has a window + if (!GTK_WIDGET(w->m_wxwindow)->window) + { + gtk_widget_realize(GTK_WIDGET(w->m_wxwindow)); + } + + GdkWindow *gwin = GTK_WIDGET(w->m_wxwindow)->window; + mXdisp = GDK_WINDOW_XDISPLAY(gwin); + mXwin = GDK_WINDOW_XWINDOW(gwin); + + mEffect->callDispatcher(effEditOpen, 0, (intptr_t)mXdisp, (void *)mXwin, 0.0); + #endif // Get the final bounds of the effect GUI @@ -1489,30 +1488,40 @@ void VSTEffectDialog::BuildFancy() // Add the program bar at the top vs->Add(BuildProgramBar(), 0, wxCENTER | wxEXPAND); - // Reserve space for the effect GUI #if defined(__WXMAC__) + // Reserve space for the effect GUI mContainer = hs->Add(rect->right - rect->left, rect->bottom - rect->top); #elif defined(__WXMSW__) + // Add the effect host window to the layout mContainer = hs->Add(w, 1, wxCENTER | wxEXPAND); mContainer->SetMinSize(rect->right - rect->left, rect->bottom - rect->top); #else + // Add the effect host window to the layout + mContainer = hs->Add(w, 1, wxCENTER | wxEXPAND); + mContainer->SetMinSize(rect->right - rect->left, rect->bottom - rect->top); + #endif vs->Add(hs, 0, wxCENTER); // Add the standard button bar at the bottom - vs->Add(CreateStdButtonSizer(this, ePreviewButton|eCancelButton|eOkButton), 0, wxEXPAND); +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + vs->Add(CreateStdButtonSizer(this, eApplyButton | eDefaultsButton), 0, wxEXPAND); +#else + vs->Add(CreateStdButtonSizer(this, ePreviewButton | eDefaultsButton |eCancelButton | eOkButton), 0, wxEXPAND); +#endif SetSizerAndFit(vs); +#if defined(__WXMAC__) + // Found out where the reserved space wound up wxPoint pos = mContainer->GetPosition(); -#if defined(__WXMAC__) // Reposition the subview into the reserved space HIViewPlaceInSuperviewAt(subview, pos.x, pos.y); @@ -1524,6 +1533,8 @@ void VSTEffectDialog::BuildFancy() #elif defined(__WXMSW__) #else #endif + + mEffect->NeedEditIdle(true); } void VSTEffectDialog::BuildPlain() @@ -1549,8 +1560,12 @@ void VSTEffectDialog::BuildPlain() sw->SetScrollRate(0, 20); vSizer->Add(sw, 1, wxEXPAND | wxALL, 5); - // Preview, OK, & Cancel buttons - vSizer->Add(CreateStdButtonSizer(this, ePreviewButton|eCancelButton|eOkButton), 0, wxEXPAND); + // Add the standard button bar at the bottom +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + vSizer->Add(CreateStdButtonSizer(this, eApplyButton | eDefaultsButton), 0, wxEXPAND); +#else + vSizer->Add(CreateStdButtonSizer(this, ePreviewButton|eDefaultsButton|eCancelButton|eOkButton), 0, wxEXPAND); +#endif SetSizer(vSizer); @@ -1563,20 +1578,24 @@ void VSTEffectDialog::BuildPlain() int namew = 0; int w; int h; - for (int i = 0; i < mAEffect->numParams; i++) { + for (int i = 0; i < mAEffect->numParams; i++) + { wxString text = mEffect->GetString(effGetParamName, i); - if (text.Right(1) != wxT(':')) { + if (text.Right(1) != wxT(':')) + { text += wxT(':'); } GetTextExtent(text, &w, &h); - if (w > namew) { + if (w > namew) + { namew = w; } } GetTextExtent(wxT("HHHHHHHH"), &w, &h); - for (int i = 0; i < mAEffect->numParams; i++) { + for (int i = 0; i < mAEffect->numParams; i++) + { mNames[i] = new wxStaticText(sw, wxID_ANY, wxEmptyString, @@ -1629,11 +1648,13 @@ wxSizer *VSTEffectDialog::BuildProgramBar() // Some plugins, like Guitar Rig 5, only report 128 programs while they have hundreds. While // I was able to come up with a hack in the Guitar Rig case to gather all of the program names, // it would not let me set a program outside of the first 128. - for (int i = 0; i < mAEffect->numPrograms; i++) { + for (int i = 0; i < mAEffect->numPrograms; i++) + { progs.Add(mEffect->GetString(effGetProgramNameIndexed, i)); } - if (progs.GetCount() == 0) { + if (progs.GetCount() == 0) + { progs.Add(_("None")); } @@ -1641,7 +1662,8 @@ wxSizer *VSTEffectDialog::BuildProgramBar() int progn = mEffect->callDispatcher(effGetProgram, 0, 0, NULL, 0.0); // An unset program is perfectly valid, do not force a default. - if (progn >= 0) { + if (progn >= 0 && progn < progs.GetCount()) + { val = progs[progn]; } @@ -1675,12 +1697,17 @@ wxSizer *VSTEffectDialog::BuildProgramBar() void VSTEffectDialog::RefreshParameters(int skip) { - if (!mGui) { - for (int i = 0; i < mAEffect->numParams; i++) { - wxString text = mEffect->GetString(effGetParamName, i).Trim(true).Trim(false); + if (!mGui) + { + for (int i = 0; i < mAEffect->numParams; i++) + { + wxString text = mEffect->GetString(effGetParamName, i); + text = text.Trim(true).Trim(false); + wxString name = text; - if (text.Right(1) != wxT(':')) { + if (text.Right(1) != wxT(':')) + { text += wxT(':'); } mNames[i]->SetLabel(text); @@ -1689,20 +1716,23 @@ void VSTEffectDialog::RefreshParameters(int skip) // a side effect that causes it to only move when the parameter changes // from off to on. However, this prevents changing the value using the // keyboard, so we skip the active slider if any. - if (i != skip) { + if (i != skip) + { mSliders[i]->SetValue(mEffect->callGetParameter(i) * 1000); } name = text; text = mEffect->GetString(effGetParamDisplay, i); - if (text.IsEmpty()) { + if (text.IsEmpty()) + { text.Printf(wxT("%.5g"),mEffect->callGetParameter(i)); } mDisplays[i]->SetLabel(wxString::Format(wxT("%8s"), text.c_str())); name += wxT(' ') + text; text = mEffect->GetString(effGetParamDisplay, i); - if (!text.IsEmpty()) { + if (!text.IsEmpty()) + { text.Printf(wxT("%-8s"), mEffect->GetString(effGetParamLabel, i).c_str()); mLabels[i]->SetLabel(wxString::Format(wxT("%8s"), text.c_str())); name += wxT(' ') + text; @@ -1722,14 +1752,16 @@ void VSTEffectDialog::OnUpdateDisplay(wxCommandEvent & evt) // Refresh the program list since some effects change the available programs based // on the users activity. mProgram->Clear(); - for (i = 0; i < mAEffect->numPrograms; i++) { + for (i = 0; i < mAEffect->numPrograms; i++) + { mProgram->Append(mEffect->GetString(effGetProgramNameIndexed, i)); } // The new list may not have the previously selected program or the user may have // changed it i = mEffect->callDispatcher(effGetProgram, 0, 0, NULL, 0.0); - if (i >= 0) { + if (i >= 0) + { mProgram->SetSelection(i); } @@ -1738,7 +1770,8 @@ void VSTEffectDialog::OnUpdateDisplay(wxCommandEvent & evt) void VSTEffectDialog::OnSizeWindow(wxCommandEvent & evt) { - if (!mContainer) { + if (!mContainer) + { return; } @@ -1763,12 +1796,13 @@ void VSTEffectDialog::OnProgram(wxCommandEvent & evt) RefreshParameters(); } -void VSTEffectDialog::OnProgramText(wxCommandEvent & WXUNUSED(event)) +void VSTEffectDialog::OnProgramText(wxCommandEvent & WXUNUSED(evt)) { int i = mEffect->callDispatcher(effGetProgram, 0, 0, NULL, 0.0); // Bail if nothing is selected - if (i < 0) { + if (i < 0) + { return; } @@ -1776,8 +1810,9 @@ void VSTEffectDialog::OnProgramText(wxCommandEvent & WXUNUSED(event)) int ip = mProgram->GetInsertionPoint(); // Limit the length of the string, max 24 + 1 for null terminator - if (name.Length() > 24) { - name = name.Left(24); + if (name.length() > 24) + { + name = name.substr(0, 24); } mEffect->SetString(effSetProgramName, name, i); @@ -1793,135 +1828,72 @@ void VSTEffectDialog::OnProgramText(wxCommandEvent & WXUNUSED(event)) mProgram->SetStringSelection(name); // Which also means we have to reposition the caret. - if (ip >= 0) { + if (ip >= 0) + { mProgram->SetInsertionPoint(ip); } RefreshParameters(); } -void VSTEffectDialog::OnLoad(wxCommandEvent & WXUNUSED(event)) +// +// Load an "fxb", "fxp" or Audacuty "xml" file +// +// Based on work by Sven Giermann +// +void VSTEffectDialog::OnLoad(wxCommandEvent & WXUNUSED(evt)) { - wxString fn; + wxString path; // Ask the user for the real name - fn = FileSelector(_("Load VST Preset:"), + path = FileSelector(_("Load VST Preset:"), FileNames::DataDir(), wxEmptyString, wxT("xml"), - wxT("VST preset files (*.fxp; *.xml)|*.fxp;*.xml"), + wxT("VST preset files (*.fxb; *.fxp; *.xml)|*.fxb;*.fxp;*.xml"), wxFD_OPEN | wxRESIZE_BORDER, this); // User canceled... - if (fn.IsEmpty()) { + if (path.IsEmpty()) + { return; } - size_t len = fn.Len(); - if (len > 4 && wxStricmp(fn.Mid(len - 4), wxT(".fxp")) == 0) { - // - // FXP specification from VST SDK 2.4 (vstfxstore.h) - // - int i; - wxInt32 buffer[8]; - char *buf = NULL; - bool error = false; - - // read VST program file (FXP) - wxFFile fxpFile(fn, wxT("rb")); - if (!fxpFile.IsOpened()) { - wxMessageBox(wxString::Format(_("Could not open file: \"%s\""), fn.c_str()), - _("Error Loading VST Presets"), - wxOK | wxCENTRE, - this); - return; - } - if (!error) error = !fread(buffer, 28, 1, fxpFile.fp()); - - // VST always uses Big Endian, convert first - for (i = 0; i < 7; i++) - buffer[i] = wxINT32_SWAP_ON_LE(buffer[i]); - - if (!error) error = (buffer[0] != CCONST('C', 'c', 'n', 'K')); ///< 'CcnK' - //VstInt32 byteSize; ///< size of this chunk, excl. magic + byteSize - if (!error) { - if (mAEffect->flags & effFlagsProgramChunks) - error = (buffer[2] != CCONST('F', 'P', 'C', 'h')); ///< 'FxCk' (regular) or 'FPCh' (opaque chunk) - else - error = (buffer[2] != CCONST('F', 'x', 'C', 'k')); - } - if (!error) error = (buffer[3] != 1); ///< format version (currently 1) - if (!error) error = (buffer[4] != mAEffect->uniqueID); ///< fx unique ID (could try to load instead, as XML does) - //if (!error) error = (buffer[5] != ///< fx version (currently ignored) - // mEffect->callDispatcher(effGetVendorVersion, 0, 0, NULL, 0.0)); - if (!error) error = (buffer[6] != mAEffect->numParams); ///< number of parameters - - buffer[7] = 0; // ensure trailing NUL - if (!error) error = !fread(buffer, 28, 1, fxpFile.fp()); ///< program name (null-terminated ASCII string) - if (!error) fn = wxConvLocal.cMB2WC((char*)buffer, 29, &len); - - if (mAEffect->flags & effFlagsProgramChunks) { - if (!error) error = !fread(buffer, 4, 1, fxpFile.fp()); - i = wxINT32_SWAP_ON_LE(buffer[0]); - if (!error) error = (i < 1); - - if (!error) { - buf = new char[i]; - error = !buf; - } - if (!error) error = !fread(buf, i, 1, fxpFile.fp()); - if (!error) mEffect->callDispatcher(effSetChunk, 1, i, buf, 0.0); - - delete [] buf; - } - else { - float val; - - if (!error) { - buf = new char[mAEffect->numParams << 2]; - error = !buf; - } - if (!error) error = !fread(buf, mAEffect->numParams << 2, 1, fxpFile.fp()); - - i = -1; - while (!error && (++i < mAEffect->numParams)) { - *((wxInt32*)&val) = wxINT32_SWAP_ON_LE(((wxInt32*)buf)[i]); - if (!error) error = (val < 0.0 || val > 1.0); - if (!error) mEffect->callSetParameter(i, val); - } - - delete [] buf; - } - - // set program name - if (!error && !fn.IsEmpty()) { - i = mProgram->GetCurrentSelection(); - if (i < 0) i = 0; // default to first program - mProgram->SetString(i, fn); - mProgram->SetValue(fn); - mEffect->SetString(effSetProgramName, fn, i); - } - - if (error) { - wxMessageBox(_("Could not load file or incompatible content."), - _("Error Loading VST Presets"), - wxOK | wxCENTRE, - this); - } - fxpFile.Close(); + wxFileName fn(path); + wxString ext = fn.GetExt(); + bool success = false; + if (ext.CmpNoCase(wxT("fxb")) == 0) + { + success = LoadFXB(fn); } - else { - // default to read as XML file - // Load the program - XMLFileReader reader; - if (!reader.Parse(this, fn)) { - // Inform user of load failure - wxMessageBox(reader.GetErrorStr(), + else if (ext.CmpNoCase(wxT("fxp")) == 0) + { + success = LoadFXP(fn); + } + else if (ext.CmpNoCase(wxT("xml")) == 0) + { + success = LoadXML(fn); + } + else + { + // This shouldn't happen, but complain anyway + wxMessageBox(_("Unrecognized file extension."), _("Error Loading VST Presets"), wxOK | wxCENTRE, this); - } + + return; + } + + if (!success) + { + wxMessageBox(_("Unable to load presets file."), + _("Error Loading VST Presets"), + wxOK | wxCENTRE, + this); + + return; } RefreshParameters(); @@ -1929,164 +1901,707 @@ void VSTEffectDialog::OnLoad(wxCommandEvent & WXUNUSED(event)) return; } -void VSTEffectDialog::OnSave(wxCommandEvent & WXUNUSED(event)) +bool VSTEffectDialog::LoadFXB(const wxFileName & fn) +{ + bool ret = false; + + // Try to open the file...will be closed automatically when method returns + wxFFile f(fn.GetFullPath(), wxT("rb")); + if (!f.IsOpened()) + { + return false; + } + + // Allocate memory for the contents + unsigned char *data = new unsigned char[f.Length()]; + if (!data) + { + wxMessageBox(_("Unable to allocate memory when loading presets file."), + _("Error Loading VST Presets"), + wxOK | wxCENTRE, + this); + return false; + } + unsigned char *bptr = data; + + do + { + // Read in the whole file + ssize_t len = f.Read((void *) bptr, f.Length()); + if (f.Error()) + { + wxMessageBox(_("Unable to read presets file."), + _("Error Loading VST Presets"), + wxOK | wxCENTRE, + this); + break; + } + + // Most references to the data are via an "int" array + int32_t *iptr = (int32_t *) bptr; + + // Verify that we have at least enough the header + if (len < 156) + { + break; + } + + // Verify that we probably have a FX file + if (wxINT32_SWAP_ON_LE(iptr[0]) != CCONST('C', 'c', 'n', 'K')) + { + break; + } + + // Ignore the size...sometimes it's there, other times it's zero + + // Get the version and verify + int version = wxINT32_SWAP_ON_LE(iptr[3]); + if (version != 1 && version != 2) + { + break; + } + + // Ensure this program looks to belong to the current plugin + if (wxINT32_SWAP_ON_LE(iptr[4]) != mAEffect->uniqueID) + { + break; + } + + // Get the number of programs + int numProgs = wxINT32_SWAP_ON_LE(iptr[6]); + if (numProgs != mAEffect->numPrograms) + { + break; + } + + // Get the current program index + int curProg = 0; + if (version == 2) + { + curProg = wxINT32_SWAP_ON_LE(iptr[7]); + if (curProg < 0 || curProg >= numProgs) + { + break; + } + } + + // Is it a bank of programs? + if (wxINT32_SWAP_ON_LE(iptr[2]) == CCONST('F', 'x', 'B', 'k')) + { + // Drop the header + bptr += 156; + len -= 156; + + unsigned char *tempPtr = bptr; + ssize_t tempLen = len; + + // Validate all of the programs + for (int i = 0; i < numProgs; i++) + { + if (!LoadFXProgram(&tempPtr, tempLen, i, true)) + { + break; + } + } + + // They look okay, time to start changing things + for (int i = 0; i < numProgs; i++) + { + ret = LoadFXProgram(&bptr, len, i, false); + } + } + // Or maybe a bank chunk? + else if (wxINT32_SWAP_ON_LE(iptr[2]) == CCONST('F', 'B', 'C', 'h')) + { + // Can't load programs chunks if the plugin doesn't support it + if (!(mAEffect->flags & effFlagsProgramChunks)) + { + break; + } + + // Verify that we have enough to grab the chunk size + if (len < 160) + { + break; + } + + // Get the chunk size + int size = wxINT32_SWAP_ON_LE(iptr[39]); + + // We finally know the full length of the program + int proglen = 160 + size; + + // Verify that we have enough for the entire program + if (len < proglen) + { + break; + } + + // Set the entire bank in one shot + mEffect->callDispatcher(effSetChunk, 0, size, &iptr[40], 0.0); + + // Success + ret = true; + } + // Unrecognizable type + else + { + break; + } + + // Set the active program + if (ret && version == 2) + { + mEffect->callDispatcher(effSetProgram, 0, curProg, NULL, 0.0); + mProgram->SetSelection(curProg); + } + } while (false); + + // Get rid of the data + delete [] data; + + return ret; +} + +bool VSTEffectDialog::LoadFXP(const wxFileName & fn) +{ + bool ret = false; + + // Try to open the file...will be closed automatically when method returns + wxFFile f(fn.GetFullPath(), wxT("rb")); + if (!f.IsOpened()) + { + return false; + } + + // Allocate memory for the contents + unsigned char *data = new unsigned char[f.Length()]; + if (!data) + { + wxMessageBox(_("Unable to allocate memory when loading presets file."), + _("Error Loading VST Presets"), + wxOK | wxCENTRE, + this); + return false; + } + unsigned char *bptr = data; + + do + { + // Read in the whole file + ssize_t len = f.Read((void *) bptr, f.Length()); + if (f.Error()) + { + wxMessageBox(_("Unable to read presets file."), + _("Error Loading VST Presets"), + wxOK | wxCENTRE, + this); + break; + } + + // Get (or default) currently selected program + int i = mProgram->GetCurrentSelection(); + if (i < 0) + { + i = 0; // default to first program + } + + // Go verify and set the program + ret = LoadFXProgram(&bptr, len, i, false); + } while (false); + + // Get rid of the data + delete [] data; + + return ret; +} + +bool VSTEffectDialog::LoadFXProgram(unsigned char **bptr, ssize_t & len, int index, bool dryrun) +{ + // Most references to the data are via an "int" array + int32_t *iptr = (int32_t *) *bptr; + + // Verify that we have at least enough for a program without parameters + if (len < 28) + { + return false; + } + + // Verify that we probably have an FX file + if (wxINT32_SWAP_ON_LE(iptr[0]) != CCONST('C', 'c', 'n', 'K')) + { + return false; + } + + // Ignore the size...sometimes it's there, other times it's zero + + // Get the version and verify +#if defined(IS_THIS_AND_FXP_ARTIFICAL_LIMITATION) + int version = wxINT32_SWAP_ON_LE(iptr[3]); + if (version != 1) + { + return false; + } +#endif + + // Ensure this program looks to belong to the current plugin + if (wxINT32_SWAP_ON_LE(iptr[4]) != mAEffect->uniqueID) + { + return false; + } + + // Get the number of parameters + int numParams = wxINT32_SWAP_ON_LE(iptr[6]); + if (numParams != mAEffect->numParams) + { + return false; + } + + // At this point, we have to have enough to include the program name as well + if (len < 56) + { + return false; + } + + // Get the program name + wxString progName(wxString::From8BitData((char *)&iptr[7])); + + // Might be a regular program + if (wxINT32_SWAP_ON_LE(iptr[2]) == CCONST('F', 'x', 'C', 'k')) + { + // We finally know the full length of the program + int proglen = 56 + (numParams * sizeof(float)); + + // Verify that we have enough for all of the parameter values + if (len < proglen) + { + return false; + } + + // Validate all of the parameter values + for (int i = 0; i < numParams; i++) + { + uint32_t ival = wxUINT32_SWAP_ON_LE(iptr[14 + i]); + float val = *((float *) &ival); + if (val < 0.0 || val > 1.0) + { + return false; + } + } + + // They look okay...time to start changing things + if (!dryrun) + { + for (int i = 0; i < numParams; i++) + { + wxUint32 val = wxUINT32_SWAP_ON_LE(iptr[14 + i]); + mEffect->callSetParameter(i, *((float *) &val)); + } + } + + // Update in case we're loading an "FxBk" format bank file + *bptr += proglen; + len -= proglen; + } + // Maybe we have a program chunk + else if (wxINT32_SWAP_ON_LE(iptr[2]) == CCONST('F', 'P', 'C', 'h')) + { + // Can't load programs chunks if the plugin doesn't support it + if (!(mAEffect->flags & effFlagsProgramChunks)) + { + return false; + } + + // Verify that we have enough to grab the chunk size + if (len < 60) + { + return false; + } + + // Get the chunk size + int size = wxINT32_SWAP_ON_LE(iptr[14]); + + // We finally know the full length of the program + int proglen = 60 + size; + + // Verify that we have enough for the entire program + if (len < proglen) + { + return false; + } + + // Set the entire program in one shot + if (!dryrun) + { + mEffect->callDispatcher(effSetChunk, 1, size, &iptr[15], 0.0); + } + + // Update in case we're loading an "FxBk" format bank file + *bptr += proglen; + len -= proglen; + } + else + { + // Unknown type + return false; + } + + if (!dryrun) + { + mProgram->SetString(index, progName); + mProgram->SetValue(progName); + mEffect->SetString(effSetProgramName, wxString(progName), index); + } + + return true; +} + +bool VSTEffectDialog::LoadXML(const wxFileName & fn) +{ + // default to read as XML file + // Load the program + XMLFileReader reader; + if (!reader.Parse(this, fn.GetFullPath())) + { + // Inform user of load failure + wxMessageBox(reader.GetErrorStr(), + _("Error Loading VST Presets"), + wxOK | wxCENTRE, + this); + return false; + } + + return true; +} + +void VSTEffectDialog::OnSave(wxCommandEvent & WXUNUSED(evt)) { int i = mProgram->GetCurrentSelection(); - wxString fn; + wxString path; // Ask the user for the real name - FileDialog fd(this, - _("Save VST Preset As:"), - FileNames::DataDir(), - mProgram->GetValue(), - wxT("Standard VST preset file (*.fxp)|*.fxp|Audacity VST preset file (*.xml)|*.xml"), - wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER); + // + // Passing a valid parent will cause some effects dialogs to malfunction + // upon returning from the FileSelector(). + path = FileSelector(_("Save VST Preset As:"), + FileNames::DataDir(), + mProgram->GetValue(), + wxT("xml"), + wxT("Standard VST bank file (*.fxb)|*.fxb|Standard VST program file (*.fxp)|*.fxp|Audacity VST preset file (*.xml)|*.xml"), + wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER, + NULL); // User canceled... - if (fd.ShowModal() == wxID_CANCEL) { + if (path.IsEmpty()) + { return; } - fn = fd.GetPath(); - if (fd.GetFilterIndex() == 0) { - // - // FXP specification from VST SDK 2.4 (vstfxstore.h) - // - int i; - wxInt32 buffer[8], chunkSize; - char *buf = NULL; - bool error = false; - - // Create/Open the file - wxFFile fxpFile(fn, wxT("wb")); - if (!fxpFile.IsOpened()) { - wxMessageBox(wxString::Format(_("Could not open file: \"%s\""), fn.c_str()), - _("Error Saving VST Presets"), - wxOK | wxCENTRE, - this); - return; - } - - buffer[0] = CCONST('C', 'c', 'n', 'K'); // VstInt32 chunkMagic; ///< 'CcnK' - buffer[1] = 48; // VstInt32 byteSize; ///< size of this chunk, excl. magic + byteSize - if (mAEffect->flags & effFlagsProgramChunks) { ///< 'FxCk' (regular) or 'FPCh' (opaque chunk) - buffer[2] = CCONST('F', 'P', 'C', 'h'); - chunkSize = mEffect->callDispatcher(effGetChunk, 1, 0, &buf, 0.0); - buffer[1] += 4; - buffer[1] += chunkSize; - } - else { - buffer[2] = CCONST('F', 'x', 'C', 'k'); - buffer[1] += (mAEffect->numParams << 2); - } - buffer[3] = 1; ///< format version (currently 1) - buffer[4] = mAEffect->uniqueID; ///< fx unique ID - buffer[5] = mEffect->callDispatcher(effGetVendorVersion, 0, 0, NULL, 0.0); ///< fx version - buffer[6] = mAEffect->numParams; - - // VST always uses Big Endian, convert first - for (i = 0; i < 7; i++) - buffer[i] = wxINT32_SWAP_ON_LE(buffer[i]); - - if (!error) error = !fwrite(buffer, 28, 1, fxpFile.fp()); - memset(buffer, 0, 28); - wxConvLocal.FromWChar((char*)buffer, 27, mProgram->GetValue()); - if (!error) error = (fwrite(buffer, 1, 28, fxpFile.fp()) < 28); ///< program name (null-terminated ASCII string) - - if (mAEffect->flags & effFlagsProgramChunks) { - buffer[0] = wxINT32_SWAP_ON_LE(chunkSize); - if (!error) error = !fwrite(buffer, 4, 1, fxpFile.fp()); - if (!error) error = !fwrite(buf, chunkSize, 1, fxpFile.fp()); - } - else { - float val; - if (!error) { - buf = new char[mAEffect->numParams << 2]; - error = !buf; - } - for (i = 0; i < mAEffect->numParams; i++) { - val = mEffect->callGetParameter(i); - ((wxInt32*)buf)[i] = wxINT32_SWAP_ON_LE(*((wxInt32*)&val)); - } - if (!error) error = !fwrite(buf, (mAEffect->numParams << 2), 1, fxpFile.fp()); - delete [] buf; - } - - fxpFile.Close(); + wxFileName fn(path); + wxString ext = fn.GetExt(); + if (ext.CmpNoCase(wxT("fxb")) == 0) + { + SaveFXB(fn); } - else { - XMLFileWriter xmlFile; - - // Create/Open the file - xmlFile.Open(fn, wxT("wb")); - - xmlFile.StartTag(wxT("vstprogrampersistence")); - xmlFile.WriteAttr(wxT("version"), wxT("1")); - - i = mEffect->callDispatcher(effGetVendorVersion, 0, 0, NULL, 0.0); - xmlFile.StartTag(wxT("effect")); - xmlFile.WriteAttr(wxT("name"), mEffect->GetEffectIdentifier()); - xmlFile.WriteAttr(wxT("version"), i); - - xmlFile.StartTag(wxT("program")); - xmlFile.WriteAttr(wxT("name"), mProgram->GetValue()); - - int clen = 0; - if (mAEffect->flags & effFlagsProgramChunks) { - void *chunk = NULL; - - clen = (int) mEffect->callDispatcher(effGetChunk, 1, 0, &chunk, 0.0); - if (clen != 0) { - xmlFile.StartTag(wxT("chunk")); - xmlFile.WriteSubTree(b64encode(chunk, clen) + wxT('\n')); - xmlFile.EndTag(wxT("chunk")); - } - } - - if (clen == 0) { - for (i = 0; i < mAEffect->numParams; i++) { - xmlFile.StartTag(wxT("param")); - - xmlFile.WriteAttr(wxT("index"), i); - xmlFile.WriteAttr(wxT("name"), - mEffect->GetString(effGetParamName, i)); - xmlFile.WriteAttr(wxT("value"), - wxString::Format(wxT("%f"), - mEffect->callGetParameter(i))); - - xmlFile.EndTag(wxT("param")); - } - } - - xmlFile.EndTag(wxT("program")); - - xmlFile.EndTag(wxT("effect")); - - xmlFile.EndTag(wxT("vstprogrampersistence")); - - // Close the file - xmlFile.Close(); + else if (ext.CmpNoCase(wxT("fxp")) == 0) + { + SaveFXP(fn); + } + else if (ext.CmpNoCase(wxT("xml")) == 0) + { + SaveXML(fn); + } + else + { + // This shouldn't happen, but complain anyway + wxMessageBox(_("Unrecognized file extension."), + _("Error Saving VST Presets"), + wxOK | wxCENTRE, + this); + return; } } -void VSTEffectDialog::OnSettings(wxCommandEvent & WXUNUSED(event)) +void VSTEffectDialog::SaveFXB(const wxFileName & fn) { - VSTEffectSettingsDialog dlg(this); - dlg.ShowModal(); + // Create/Open the file + wxFFile f(fn.GetFullPath(), wxT("wb")); + if (!f.IsOpened()) + { + wxMessageBox(wxString::Format(_("Could not open file: \"%s\""), fn.GetFullPath().c_str()), + _("Error Saving VST Presets"), + wxOK | wxCENTRE, + this); + return; + } + + wxMemoryBuffer buf; + wxInt32 subType; + void *chunkPtr; + int chunkSize; + int dataSize = 148; + wxInt32 tab[8]; + int curProg = mProgram->GetCurrentSelection(); + + if (mAEffect->flags & effFlagsProgramChunks) + { + subType = CCONST('F', 'B', 'C', 'h'); + + chunkSize = mEffect->callDispatcher(effGetChunk, 0, 0, &chunkPtr, 0.0); + dataSize += 4 + chunkSize; + } + else + { + subType = CCONST('F', 'x', 'B', 'k'); + + for (int i = 0; i < mAEffect->numPrograms; i++) + { + SaveFXProgram(buf, i); + } + + dataSize += buf.GetDataLen(); + } + + tab[0] = wxINT32_SWAP_ON_LE(CCONST('C', 'c', 'n', 'K')); + tab[1] = wxINT32_SWAP_ON_LE(dataSize); + tab[2] = wxINT32_SWAP_ON_LE(subType); + tab[3] = wxINT32_SWAP_ON_LE(curProg >= 0 ? 2 : 1); + tab[4] = wxINT32_SWAP_ON_LE(mAEffect->uniqueID); + tab[5] = wxINT32_SWAP_ON_LE(mAEffect->version); + tab[6] = wxINT32_SWAP_ON_LE(mAEffect->numPrograms); + tab[7] = wxINT32_SWAP_ON_LE(curProg >= 0 ? curProg : 0); + + f.Write(tab, sizeof(tab)); + if (!f.Error()) + { + char padding[124]; + memset(padding, 0, sizeof(padding)); + f.Write(padding, sizeof(padding)); + + if (!f.Error()) + { + if (mAEffect->flags & effFlagsProgramChunks) + { + wxInt32 size = wxINT32_SWAP_ON_LE(chunkSize); + f.Write(&size, sizeof(size)); + f.Write(chunkPtr, chunkSize); + } + else + { + f.Write(buf.GetData(), buf.GetDataLen()); + } + } + } + + if (f.Error()) + { + wxMessageBox(wxString::Format(_("Error writing to file: \"%s\""), fn.GetFullPath().c_str()), + _("Error Saving VST Presets"), + wxOK | wxCENTRE, + this); + } + + f.Close(); + + return; } -void VSTEffectDialog::OnClose(wxCloseEvent & WXUNUSED(event)) +void VSTEffectDialog::SaveFXP(const wxFileName & fn) { + // Create/Open the file + wxFFile f(fn.GetFullPath(), wxT("wb")); + if (!f.IsOpened()) + { + wxMessageBox(wxString::Format(_("Could not open file: \"%s\""), fn.GetFullPath().c_str()), + _("Error Saving VST Presets"), + wxOK | wxCENTRE, + this); + return; + } + + wxMemoryBuffer buf; + + int ndx = mEffect->callDispatcher(effGetProgram, 0, 0, NULL, 0.0); + SaveFXProgram(buf, ndx); + + f.Write(buf.GetData(), buf.GetDataLen()); + if (f.Error()) + { + wxMessageBox(wxString::Format(_("Error writing to file: \"%s\""), fn.GetFullPath().c_str()), + _("Error Saving VST Presets"), + wxOK | wxCENTRE, + this); + } + + f.Close(); + + return; +} + +void VSTEffectDialog::SaveFXProgram(wxMemoryBuffer & buf, int index) +{ + wxInt32 subType; + void *chunkPtr; + int chunkSize; + int dataSize = 48; + char progName[28]; + wxInt32 tab[7]; + + mEffect->callDispatcher(effGetProgramNameIndexed, index, 0, &progName, 0.0); + progName[27] = '\0'; + chunkSize = strlen(progName); + memset(&progName[chunkSize], 0, sizeof(progName) - chunkSize); + + if (mAEffect->flags & effFlagsProgramChunks) + { + subType = CCONST('F', 'P', 'C', 'h'); + + chunkSize = mEffect->callDispatcher(effGetChunk, 1, 0, &chunkPtr, 0.0); + dataSize += 4 + chunkSize; + } + else + { + subType = CCONST('F', 'x', 'C', 'k'); + + dataSize += (mAEffect->numParams << 2); + } + + tab[0] = wxINT32_SWAP_ON_LE(CCONST('C', 'c', 'n', 'K')); + tab[1] = wxINT32_SWAP_ON_LE(dataSize); + tab[2] = wxINT32_SWAP_ON_LE(subType); + tab[3] = wxINT32_SWAP_ON_LE(1); + tab[4] = wxINT32_SWAP_ON_LE(mAEffect->uniqueID); + tab[5] = wxINT32_SWAP_ON_LE(mAEffect->version); + tab[6] = wxINT32_SWAP_ON_LE(mAEffect->numParams); + + buf.AppendData(tab, sizeof(tab)); + buf.AppendData(progName, sizeof(progName)); + + if (mAEffect->flags & effFlagsProgramChunks) + { + wxInt32 size = wxINT32_SWAP_ON_LE(chunkSize); + buf.AppendData(&size, sizeof(size)); + buf.AppendData(chunkPtr, chunkSize); + } + else + { + for (int i = 0; i < mAEffect->numParams; i++) + { + float val = mEffect->callGetParameter(i); + wxUint32 ival = wxUINT16_SWAP_ON_LE(*((wxUint32 *) &val)); + buf.AppendData(&ival, sizeof(ival)); + } + } + + return; +} + +void VSTEffectDialog::SaveXML(const wxFileName & fn) +{ + XMLFileWriter xmlFile; + + // Create/Open the file + xmlFile.Open(fn.GetFullPath(), wxT("wb")); + + xmlFile.StartTag(wxT("vstprogrampersistence")); + xmlFile.WriteAttr(wxT("version"), wxT("1")); + + xmlFile.StartTag(wxT("effect")); + xmlFile.WriteAttr(wxT("name"), mEffect->GetName()); + xmlFile.WriteAttr(wxT("version"), mEffect->callDispatcher(effGetVendorVersion, 0, 0, NULL, 0.0)); + + xmlFile.StartTag(wxT("program")); + xmlFile.WriteAttr(wxT("name"), mProgram->GetValue()); + + int clen = 0; + if (mAEffect->flags & effFlagsProgramChunks) + { + void *chunk = NULL; + + clen = (int) mEffect->callDispatcher(effGetChunk, 1, 0, &chunk, 0.0); + if (clen != 0) + { + xmlFile.StartTag(wxT("chunk")); + xmlFile.WriteSubTree(VSTEffect::b64encode(chunk, clen) + wxT('\n')); + xmlFile.EndTag(wxT("chunk")); + } + } + + if (clen == 0) + { + for (int i = 0; i < mAEffect->numParams; i++) + { + xmlFile.StartTag(wxT("param")); + + xmlFile.WriteAttr(wxT("index"), i); + xmlFile.WriteAttr(wxT("name"), + mEffect->GetString(effGetParamName, i)); + xmlFile.WriteAttr(wxT("value"), + wxString::Format(wxT("%f"), + mEffect->callGetParameter(i))); + + xmlFile.EndTag(wxT("param")); + } + } + + xmlFile.EndTag(wxT("program")); + + xmlFile.EndTag(wxT("effect")); + + xmlFile.EndTag(wxT("vstprogrampersistence")); + + // Close the file + xmlFile.Close(); + + return; +} + + +void VSTEffectDialog::OnSettings(wxCommandEvent & WXUNUSED(evt)) +{ + VSTEffectSettingsDialog dlg(this, mEffect->mHost); + if (dlg.ShowModal()) + { + // Call Startup() to reinitialize configuration settings + mEffect->Startup(); + } +} + +void VSTEffectDialog::OnClose(wxCloseEvent & evt) +{ +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + +#if defined(__WXMAC__) + Destroy(); +#else + Show(false); + evt.Veto(); +#endif + +#else EndModal(false); +#endif } -void VSTEffectDialog::OnPreview(wxCommandEvent & WXUNUSED(event)) +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) +void VSTEffectDialog::OnApply(wxCommandEvent & WXUNUSED(evt)) { - mEffect->Preview(); +#if defined(__WXMAC__) + Close(); +#else + Show(false); +#endif + + mEffect->mHost->Apply(); +} +#else +void VSTEffectDialog::OnPreview(wxCommandEvent & WXUNUSED(evt)) +{ + mEffect->mHost->Preview(); } -void VSTEffectDialog::OnOk(wxCommandEvent & WXUNUSED(event)) +void VSTEffectDialog::OnOk(wxCommandEvent & WXUNUSED(evt)) { // In wxGTK, Show(false) calls EndModal, which produces an assertion in debug builds #if !defined(__WXGTK__) @@ -2094,14 +2609,17 @@ void VSTEffectDialog::OnOk(wxCommandEvent & WXUNUSED(event)) Show(false); #endif - if (mGui) { - mEffect->callDispatcher(effEditClose, 0, 0, NULL, 0.0); + if (mGui) + { +// mEffect->PowerOff(); +// mEffect->NeedEditIdle(false); +// mEffect->callDispatcher(effEditClose, 0, 0, NULL, 0.0); } EndModal(true); } -void VSTEffectDialog::OnCancel(wxCommandEvent & WXUNUSED(event)) +void VSTEffectDialog::OnCancel(wxCommandEvent & WXUNUSED(evt)) { // In wxGTK, Show(false) calls EndModal, which produces an assertion in debug builds #if !defined(__WXGTK__) @@ -2109,33 +2627,49 @@ void VSTEffectDialog::OnCancel(wxCommandEvent & WXUNUSED(event)) Show(false); #endif - if (mGui) { - mEffect->callDispatcher(effEditClose, 0, 0, NULL, 0.0); + if (mGui) + { +// mEffect->PowerOff(); +// mEffect->NeedEditIdle(false); +// mEffect->callDispatcher(effEditClose, 0, 0, NULL, 0.0); } EndModal(false); } +#endif + +void VSTEffectDialog::OnDefaults(wxCommandEvent & WXUNUSED(evt)) +{ + mEffect->LoadParameters(wxT("Default")); + RefreshParameters(); +} bool VSTEffectDialog::HandleXMLTag(const wxChar *tag, const wxChar **attrs) { - if (wxStrcmp(tag, wxT("vstprogrampersistence")) == 0) { - while (*attrs) { + if (wxStrcmp(tag, wxT("vstprogrampersistence")) == 0) + { + while (*attrs) + { const wxChar *attr = *attrs++; const wxChar *value = *attrs++; - if (!value) { + if (!value) + { break; } const wxString strValue = value; - if (wxStrcmp(attr, wxT("version")) == 0) { - if (!XMLValueChecker::IsGoodInt(strValue)) { + if (wxStrcmp(attr, wxT("version")) == 0) + { + if (!XMLValueChecker::IsGoodInt(strValue)) + { return false; } // Nothing to do with it for now } - else { + else + { return false; } } @@ -2143,38 +2677,48 @@ bool VSTEffectDialog::HandleXMLTag(const wxChar *tag, const wxChar **attrs) return true; } - if (wxStrcmp(tag, wxT("effect")) == 0) { - while (*attrs) { + if (wxStrcmp(tag, wxT("effect")) == 0) + { + while (*attrs) + { const wxChar *attr = *attrs++; const wxChar *value = *attrs++; - if (!value) { + if (!value) + { break; } const wxString strValue = value; - if (wxStrcmp(attr, wxT("name")) == 0) { - if (!XMLValueChecker::IsGoodString(strValue)) { + if (wxStrcmp(attr, wxT("name")) == 0) + { + if (!XMLValueChecker::IsGoodString(strValue)) + { return false; } - if (value != mEffect->GetEffectIdentifier()) { + if (value != mEffect->GetName()) + { wxString msg; msg.Printf(_("This parameter file was saved from %s. Continue?"), value); int result = wxMessageBox(msg, wxT("Confirm"), wxYES_NO, this); - if (result == wxNO) { + if (result == wxNO) + { return false; } } } - else if (wxStrcmp(attr, wxT("version")) == 0) { - if (!XMLValueChecker::IsGoodInt(strValue)) { + else if (wxStrcmp(attr, wxT("version")) == 0) + { + if (!XMLValueChecker::IsGoodInt(strValue)) + { return false; } // Nothing to do with it for now } - else { + else + { return false; } } @@ -2182,23 +2726,29 @@ bool VSTEffectDialog::HandleXMLTag(const wxChar *tag, const wxChar **attrs) return true; } - if (wxStrcmp(tag, wxT("program")) == 0) { - while (*attrs) { + if (wxStrcmp(tag, wxT("program")) == 0) + { + while (*attrs) + { const wxChar *attr = *attrs++; const wxChar *value = *attrs++; - if (!value) { + if (!value) + { break; } const wxString strValue = value; - if (wxStrcmp(attr, wxT("name")) == 0) { - if (!XMLValueChecker::IsGoodString(strValue)) { + if (wxStrcmp(attr, wxT("name")) == 0) + { + if (!XMLValueChecker::IsGoodString(strValue)) + { return false; } - if (strValue.Length() > 24) { + if (strValue.length() > 24) + { return false; } @@ -2213,7 +2763,8 @@ bool VSTEffectDialog::HandleXMLTag(const wxChar *tag, const wxChar **attrs) mEffect->SetString(effSetProgramName, strValue, ndx); } - else { + else + { return false; } } @@ -2223,49 +2774,61 @@ bool VSTEffectDialog::HandleXMLTag(const wxChar *tag, const wxChar **attrs) return true; } - if (wxStrcmp(tag, wxT("param")) == 0) { + if (wxStrcmp(tag, wxT("param")) == 0) + { long ndx = -1; double val = -1.0; - while (*attrs) { + while (*attrs) + { const wxChar *attr = *attrs++; const wxChar *value = *attrs++; - if (!value) { + if (!value) + { break; } const wxString strValue = value; - if (wxStrcmp(attr, wxT("index")) == 0) { - if (!XMLValueChecker::IsGoodInt(strValue) || !strValue.ToLong(&ndx)) { + if (wxStrcmp(attr, wxT("index")) == 0) + { + if (!XMLValueChecker::IsGoodInt(strValue) || !strValue.ToLong(&ndx)) + { return false; } - if (ndx < 0 || ndx >= mAEffect->numParams) { + if (ndx < 0 || ndx >= mAEffect->numParams) + { // Could be a different version of the effect...probably should // tell the user return false; } } - else if (wxStrcmp(attr, wxT("name")) == 0) { - if (!XMLValueChecker::IsGoodString(strValue)) { + else if (wxStrcmp(attr, wxT("name")) == 0) + { + if (!XMLValueChecker::IsGoodString(strValue)) + { return false; } // Nothing to do with it for now } - else if (wxStrcmp(attr, wxT("value")) == 0) { + else if (wxStrcmp(attr, wxT("value")) == 0) + { if (!XMLValueChecker::IsGoodInt(strValue) || - !Internat::CompatibleToDouble(strValue, &val)) { + !Internat::CompatibleToDouble(strValue, &val)) + { return false; } - if (val < 0.0 || val > 1.0) { + if (val < 0.0 || val > 1.0) + { return false; } } } - if (ndx == -1 || val == -1.0) { + if (ndx == -1 || val == -1.0) + { return false; } @@ -2274,7 +2837,8 @@ bool VSTEffectDialog::HandleXMLTag(const wxChar *tag, const wxChar **attrs) return true; } - if (wxStrcmp(tag, wxT("chunk")) == 0) { + if (wxStrcmp(tag, wxT("chunk")) == 0) + { mInChunk = true; return true; } @@ -2284,17 +2848,20 @@ bool VSTEffectDialog::HandleXMLTag(const wxChar *tag, const wxChar **attrs) void VSTEffectDialog::HandleXMLEndTag(const wxChar *tag) { - if (wxStrcmp(tag, wxT("chunk")) == 0) { - if (mChunk.Length()) { - char *buf = new char[mChunk.Length() / 4 * 3]; + if (wxStrcmp(tag, wxT("chunk")) == 0) + { + if (mChunk.length()) + { + char *buf = new char[mChunk.length() / 4 * 3]; - int len = b64decode(mChunk, buf); - if (len) { + int len = VSTEffect::b64decode(mChunk, buf); + if (len) + { mEffect->callDispatcher(effSetChunk, 1, len, buf, 0.0); } delete [] buf; - mChunk.Clear(); + mChunk.clear(); } mInChunk = false; } @@ -2302,153 +2869,69 @@ void VSTEffectDialog::HandleXMLEndTag(const wxChar *tag) void VSTEffectDialog::HandleXMLContent(const wxString & content) { - if (mInChunk) { + if (mInChunk) + { mChunk += wxString(content).Trim(true).Trim(false); } } XMLTagHandler *VSTEffectDialog::HandleXMLChild(const wxChar *tag) { - if (wxStrcmp(tag, wxT("vstprogrampersistence")) == 0) { + if (wxStrcmp(tag, wxT("vstprogrampersistence")) == 0) + { return this; } - if (wxStrcmp(tag, wxT("effect")) == 0) { + if (wxStrcmp(tag, wxT("effect")) == 0) + { return this; } - if (wxStrcmp(tag, wxT("program")) == 0) { + if (wxStrcmp(tag, wxT("program")) == 0) + { return this; } - if (wxStrcmp(tag, wxT("param")) == 0) { + if (wxStrcmp(tag, wxT("param")) == 0) + { return this; } - if (wxStrcmp(tag, wxT("chunk")) == 0) { + if (wxStrcmp(tag, wxT("chunk")) == 0) + { return this; } return NULL; } -//////////////////////////////////////////////////////////////////////////////// -// Base64 en/decoding +/////////////////////////////////////////////////////////////////////////////// // -// Original routines marked as public domain and found at: +// VSTEffectTimer // -// http://en.wikibooks.org/wiki/Algorithm_implementation/Miscellaneous/Base64 -// -//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// -// Lookup table for encoding -const static wxChar cset[] = wxT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); -const static char padc = wxT('='); - -wxString VSTEffectDialog::b64encode(const void *in, int len) +class VSTEffectTimer : public wxTimer { - unsigned char *p = (unsigned char *) in; - wxString out; - - unsigned long temp; - for (int i = 0; i < len / 3; i++) { - temp = (*p++) << 16; //Convert to big endian - temp += (*p++) << 8; - temp += (*p++); - out += cset[(temp & 0x00FC0000) >> 18]; - out += cset[(temp & 0x0003F000) >> 12]; - out += cset[(temp & 0x00000FC0) >> 6]; - out += cset[(temp & 0x0000003F)]; - } - - switch (len % 3) +public: + VSTEffectTimer(VSTEffect *effect) + : wxTimer(), + mEffect(effect) { - case 1: - temp = (*p++) << 16; //Convert to big endian - out += cset[(temp & 0x00FC0000) >> 18]; - out += cset[(temp & 0x0003F000) >> 12]; - out += padc; - out += padc; - break; - - case 2: - temp = (*p++) << 16; //Convert to big endian - temp += (*p++) << 8; - out += cset[(temp & 0x00FC0000) >> 18]; - out += cset[(temp & 0x0003F000) >> 12]; - out += cset[(temp & 0x00000FC0) >> 6]; - out += padc; - break; } - return out; -} - -int VSTEffectDialog::b64decode(wxString in, void *out) -{ - int len = in.Length(); - unsigned char *p = (unsigned char *) out; - - if (len % 4) { //Sanity check - return 0; + ~VSTEffectTimer() + { } - int padding = 0; - if (len) { - if (in[len - 1] == padc) { - padding++; - } - - if (in[len - 2] == padc) { - padding++; - } + void Notify() + { + mEffect->OnTimer(); } - //const char *a = in.mb_str(); - //Setup a vector to hold the result - unsigned long temp = 0; //Holds decoded quanta - int i = 0; - while (i < len) { - for (int quantumPosition = 0; quantumPosition < 4; quantumPosition++) { - unsigned char c = in[i]; - temp <<= 6; - - if (c >= 0x41 && c <= 0x5A) { - temp |= c - 0x41; - } - else if (c >= 0x61 && c <= 0x7A) { - temp |= c - 0x47; - } - else if (c >= 0x30 && c <= 0x39) { - temp |= c + 0x04; - } - else if (c == 0x2B) { - temp |= 0x3E; - } - else if (c == 0x2F) { - temp |= 0x3F; - } - else if (c == padc) { - switch (len - i) - { - case 1: //One pad character - *p++ = (temp >> 16) & 0x000000FF; - *p++ = (temp >> 8) & 0x000000FF; - return p - (unsigned char *) out; - case 2: //Two pad characters - *p++ = (temp >> 10) & 0x000000FF; - return p - (unsigned char *) out; - } - } - i++; - } - *p++ = (temp >> 16) & 0x000000FF; - *p++ = (temp >> 8) & 0x000000FF; - *p++ = temp & 0x000000FF; - } - - return p - (unsigned char *) out; -} +private: + VSTEffect *mEffect; +}; /////////////////////////////////////////////////////////////////////////////// // @@ -2458,13 +2941,14 @@ int VSTEffectDialog::b64decode(wxString in, void *out) typedef AEffect *(*vstPluginMain)(audioMasterCallback audioMaster); -static intptr_t audioMaster(AEffect * effect, +intptr_t VSTEffect::AudioMaster(AEffect * effect, int32_t opcode, int32_t index, intptr_t value, void * ptr, float opt) { + VSTEffect *vst = (effect ? (VSTEffect *) effect->user : NULL); // Handles operations during initialization...before VSTEffect has had a @@ -2491,19 +2975,14 @@ static intptr_t audioMaster(AEffect * effect, AUDACITY_REVISION << 8 | AUDACITY_MODLEVEL); - // Let the effect know if a pin (channel in our case) is connected - case audioMasterPinConnected: - if (vst) { - return (intptr_t) (index < vst->GetChannels() ? 0 : 1); - } - return 0; - // Some (older) effects depend on an effIdle call when requested. An // example is the Antress Modern plugins which uses the call to update // the editors display when the program (preset) changes. case audioMasterNeedIdle: - if (vst) { - return vst->NeedIdle(); + if (vst) + { + vst->NeedIdle(); + return 1; } return 0; @@ -2512,7 +2991,8 @@ static intptr_t audioMaster(AEffect * effect, // Since we don't do anything with the parameters while the editor is displayed, // there's no need for us to do anything. case audioMasterUpdateDisplay: - if (vst) { + if (vst) + { vst->UpdateDisplay(); return 1; } @@ -2520,21 +3000,24 @@ static intptr_t audioMaster(AEffect * effect, // Return the current time info. case audioMasterGetTime: - if (vst) { + if (vst) + { return (intptr_t) vst->GetTimeInfo(); } return 0; // Inputs, outputs, or initial delay has changed...all we care about is initial delay. case audioMasterIOChanged: - if (vst) { + if (vst) + { vst->SetBufferDelay(effect->initialDelay); return 1; } return 0; case audioMasterGetSampleRate: - if (vst) { + if (vst) + { return (intptr_t) vst->GetSampleRate(); } return 0; @@ -2544,7 +3027,8 @@ static intptr_t audioMaster(AEffect * effect, return 1; case audioMasterGetCurrentProcessLevel: - if (vst) { + if (vst) + { return vst->GetProcessLevel(); } return 0; @@ -2558,27 +3042,22 @@ static intptr_t audioMaster(AEffect * effect, // Resize the window to accommodate the effect size case audioMasterSizeWindow: - if (vst) { + if (vst) + { vst->SizeWindow(index, value); } return 1; case audioMasterCanDo: { -#if defined(__WXDEBUG__) -#if defined(__WXMSW__) - wxLogDebug(wxT("VST canDo: %s"), wxString::FromAscii((char *)ptr).c_str()); -#else - wxPrintf(wxT("VST canDo: %s\n"), wxString::FromAscii((char *)ptr).c_str()); -#endif -#endif char *s = (char *) ptr; if (strcmp(s, "acceptIOChanges") == 0 || - strcmp(s, "sizeWindow") == 0) { + strcmp(s, "sizeWindow") == 0) + { return 1; } -#if defined(__WXDEBUG__) +#if defined(VST_DEBUG) #if defined(__WXMSW__) wxLogDebug(wxT("VST canDo: %s"), wxString::FromAscii((char *)ptr).c_str()); #else @@ -2595,6 +3074,9 @@ static intptr_t audioMaster(AEffect * effect, case audioMasterEndEdit: case audioMasterAutomate: + // We're always connected (sort of) + case audioMasterPinConnected: + // We don't do MIDI yet case audioMasterWantMidi: case audioMasterProcessEvents: @@ -2603,7 +3085,7 @@ static intptr_t audioMaster(AEffect * effect, return 0; } -#if defined(__WXDEBUG__) +#if defined(VST_DEBUG) #if defined(__WXMSW__) wxLogDebug(wxT("vst: %p opcode: %d index: %d value: %d ptr: %p opt: %f user: %p"), effect, opcode, index, value, ptr, opt, vst); @@ -2616,46 +3098,31 @@ static intptr_t audioMaster(AEffect * effect, return 0; } -class VSTEffectTimer : public wxTimer -{ -public: - VSTEffectTimer(VSTEffect *effect) - : wxTimer(), - mEffect(effect) - { - } - - ~VSTEffectTimer() - { - } - - void Notify() - { - // Call the effect - if (!mEffect->callDispatcher(effIdle, 0, 0, NULL, 0.0)) { - // No more idle calls - Stop(); - } - } - -private: - VSTEffect *mEffect; -}; - VSTEffect::VSTEffect(const wxString & path) -: mPath(path) +: mHost(NULL), + mPath(path) { mModule = NULL; mAEffect = NULL; - mInBuffer = NULL; - mOutBuffer = NULL; mDlg = NULL; - mTimer = NULL; - mInputs = 0; - mOutputs = 0; - mChannels = 0; + mTimer = new VSTEffectTimer(this); + mTimerGuard = 0; + + mInteractive = false; + mAudioIns = 0; + mAudioOuts = 0; + mMidiIns = 0; + mMidiOuts = 0; mBlockSize = 0; + mBufferDelay = 0; mProcessLevel = 1; // in GUI thread + mHasPower = false; + mWantsIdle = false; + mWantsEditIdle = false; + mUserBlockSize = 8192; + mBlockSize = mUserBlockSize; + mUseBufferDelay = true; + mReady = false; memset(&mTimeInfo, 0, sizeof(mTimeInfo)); mTimeInfo.samplePos = 0.0; @@ -2665,44 +3132,6 @@ VSTEffect::VSTEffect(const wxString & path) mTimeInfo.timeSigNumerator = 4; mTimeInfo.timeSigDenominator = 4; mTimeInfo.flags = kVstTempoValid | kVstNanosValid; - - PluginManager & pm = PluginManager::Get(); - - if (pm.IsRegistered(VSTPLUGINTYPE, mPath)) { - mName = pm.Read(wxT("Name"), wxEmptyString); - mVendor = pm.Read(wxT("Vendor"), wxEmptyString); - mInputs = pm.Read(wxT("Inputs"), 0L); - mOutputs = pm.Read(wxT("Outputs"), 0L); - } - else if (Load()) { - pm.RegisterPlugin(VSTPLUGINTYPE, mPath); - pm.Write(wxT("Name"), mName); - pm.Write(wxT("Vendor"), mVendor); - pm.Write(wxT("Inputs"), mInputs); - pm.Write(wxT("Outputs"), mOutputs); - } - - if (mVendor.IsEmpty()) { - mVendor = VSTPLUGINTYPE; - } - - if (mName.IsEmpty()) { - wxFileName fn(mPath); - mName = fn.GetName(); - } - - int flags = PLUGIN_EFFECT; - if (mInputs == 0) { - flags |= INSERT_EFFECT; - } - else if (mOutputs == 0) { - flags |= ANALYZE_EFFECT; - } - else { - flags |= PROCESS_EFFECT; - } - - SetEffectFlags(flags); } VSTEffect::~VSTEffect() @@ -2710,74 +3139,287 @@ VSTEffect::~VSTEffect() Unload(); } -wxString VSTEffect::GetEffectName() +// +// EffectClientInterface Implementation +// +void VSTEffect::SetHost(EffectHostInterface *host) { - if (mVendor.IsEmpty()) { - return mName + wxT("..."); - } - - return mVendor + wxT(": ") + mName + wxT("..."); + mHost = host; + Startup(); } -wxString VSTEffect::GetEffectIdentifier() +bool VSTEffect::Startup() +{ + if (!mAEffect) + { + Load(); + } + + if (!mAEffect) + { + return false; + } + + // mHost will be null when running in the subprocess + if (mHost) + { + mHost->GetSharedConfig(wxT("Settings"), wxT("BufferSize"), mUserBlockSize, 8192); + mHost->GetSharedConfig(wxT("Settings"), wxT("UseBufferDelay"), mUseBufferDelay, true); + + mBlockSize = mUserBlockSize; + + bool haveDefaults; + mHost->GetPrivateConfig(wxT("Default"), wxT("Initialized"), haveDefaults, false); + if (!haveDefaults) + { + SaveParameters(wxT("Default")); + mHost->SetPrivateConfig(wxT("Default"), wxT("Initialized"), true); + } + + LoadParameters(wxT("Current")); + } + + return true; +} + +bool VSTEffect::Shutdown() +{ + SaveParameters(wxT("Current")); + + return true; +} + +EffectType VSTEffect::GetType() +{ + if (mAudioIns == 0 && mMidiIns == 0) + { + return EffectTypeGenerate; + } + + if (mAudioOuts == 0 && mMidiOuts == 0) + { + return EffectTypeAnalyze; + } + + return EffectTypeProcess; +} + +wxString VSTEffect::GetID() +{ + return wxString(wxT("VST_") + GetVendor() + wxT("_") + GetName() + wxT("_") + GetVersion()); +} + +wxString VSTEffect::GetPath() +{ + return mPath; +} + +wxString VSTEffect::GetName() { return mName; } -std::set VSTEffect::GetEffectCategories() +wxString VSTEffect::GetVendor() { - return std::set(); + return mVendor; } -wxString VSTEffect::GetEffectAction() +wxString VSTEffect::GetVersion() { - return _("Performing Effect: ") + mName; -} + wxString version; -bool VSTEffect::Init() -{ - if (!mAEffect) { - Load(); - } - - if (!mAEffect) { - return false; - } - - mBlockSize = 0; - - TrackListIterator iter(mOutputTracks); - WaveTrack *left = (WaveTrack *) iter.First(); - while (left) { - sampleCount lstart; - sampleCount llen; - - GetSamples(left, &lstart, &llen); - - if (left->GetLinked()) { - WaveTrack *right = (WaveTrack *) iter.Next(); - sampleCount rstart; - sampleCount rlen; - - GetSamples(right, &rstart, &rlen); - - if (left->GetRate() != right->GetRate()) { - wxMessageBox(_("Both channels of a stereo track must be the same sample rate.")); - return false; - } - - if (llen != rlen) { - wxMessageBox(_("Both channels of a stereo track must be the same length.")); - return false; - } + bool skipping = true; + for (int i = 0, s = 0; i < 4; i++, s += 8) + { + int dig = (mVersion >> s) & 0xff; + if (dig != 0 || !skipping) + { + version += !skipping ? wxT(".") : wxT(""); + version += wxString::Format(wxT("%d"), dig); + skipping = false; } - - left = (WaveTrack *) iter.Next(); } + return version; +} + +wxString VSTEffect::GetDescription() +{ + // VST does have a product string opcode and sum effects return a short + // description, but most do not or they just return the name again. So, + // try to provide some sort of useful information. + mDescription = _("Audio In: ") + + wxString::Format(wxT("%d"), mAudioIns), + _(", Audio Out: ") + + wxString::Format(wxT("%d"), mAudioOuts); + + return mDescription; +} + +wxString VSTEffect::GetFamily() +{ + return VSTPLUGINTYPE; +} + +bool VSTEffect::IsInteractive() + { + return mInteractive; +} + +bool VSTEffect::IsDefault() +{ + return false; +} + +bool VSTEffect::IsLegacy() +{ + return false; +} + +bool VSTEffect::IsRealtimeCapable() +{ + return true; +} + +int VSTEffect::GetAudioInCount() +{ + return mAudioIns; +} + +int VSTEffect::GetAudioOutCount() +{ + return mAudioOuts; +} + +int VSTEffect::GetMidiInCount() +{ + return mMidiIns; +} + +int VSTEffect::GetMidiOutCount() +{ + return mMidiOuts; +} + +sampleCount VSTEffect::GetBlockSize(sampleCount maxBlockSize) +{ + sampleCount prevSize = mBlockSize; + + if (mUserBlockSize > maxBlockSize) + { + mBlockSize = maxBlockSize; + } + else + { + mBlockSize = mUserBlockSize; + } + + return mBlockSize; +} + +void VSTEffect::SetSampleRate(sampleCount rate) +{ + mSampleRate = (float) rate; +} + +sampleCount VSTEffect::GetLatency() +{ + if (mUseBufferDelay) + { + // ??? Threading issue ??? + sampleCount delay = mBufferDelay; + mBufferDelay = 0; + return delay; + } + + return 0; +} + +sampleCount VSTEffect::GetTailSize() +{ + return 0; +} + +bool VSTEffect::IsReady() +{ + return mReady; +} + +bool VSTEffect::ProcessInitialize() +{ + // Initialize time info + memset(&mTimeInfo, 0, sizeof(mTimeInfo)); + mTimeInfo.sampleRate = mSampleRate; + mTimeInfo.nanoSeconds = wxGetLocalTimeMillis().ToDouble(); + mTimeInfo.tempo = 120.0; + mTimeInfo.timeSigNumerator = 4; + mTimeInfo.timeSigDenominator = 4; + mTimeInfo.flags = kVstTempoValid | kVstNanosValid | kVstTransportPlaying; + + // Set processing parameters...power must be off for this + callDispatcher(effSetSampleRate, 0, 0, NULL, mSampleRate); + callDispatcher(effSetBlockSize, 0, mBlockSize, NULL, 0.0); + + // Turn on the power + PowerOn(); + + // Set the initial buffer delay + SetBufferDelay(mAEffect->initialDelay); + + mReady = true; + return true; } +bool VSTEffect::ProcessFinalize() +{ + mReady = false; + + PowerOff(); + + return true; +} + +sampleCount VSTEffect::ProcessBlock(float **inbuf, float **outbuf, sampleCount size) +{ + // Go let the plugin moleste the samples + callProcessReplacing(inbuf, outbuf, size); + mTimeInfo.samplePos += ((double) size / mTimeInfo.sampleRate); + + return size; +} + +bool VSTEffect::RealtimeInitialize(int numChannels, float sampleRate) +{ + SetSampleRate(sampleRate); + + return ProcessInitialize(); +} + +bool VSTEffect::RealtimeFinalize() +{ + return ProcessFinalize(); +} + +bool VSTEffect::RealtimeSuspend() +{ + PowerOff(); + + return true; +} + +bool VSTEffect::RealtimeResume() +{ + PowerOn(); + + return true; +} + +sampleCount VSTEffect::RealtimeProcess(float **inbuf, float **outbuf, sampleCount size) +{ + return ProcessBlock(inbuf, outbuf, size); +} + // // Some history... // @@ -2802,11 +3444,20 @@ bool VSTEffect::Init() // And at the same time I added buffer delay compensation, which allows Audacity // to account for latency introduced by some effects. This is based on information // provided by the effect, so it will not work with all effects since they don't -// allow provide the information (kn0ck0ut is one). +// all provide the information (kn0ck0ut is one). // -bool VSTEffect::PromptUser() +bool VSTEffect::ShowInterface(void *parent) { - mProcessLevel = 1; // in GUI thread +// mProcessLevel = 1; // in GUI thread + + // Set some defaults since some VSTs need them...these will be reset when + // normal or realtime processing begins + if (!IsReady()) + { + mSampleRate = 44100; + mBlockSize = 8192; + ProcessInitialize(); + } // I can't believe we haven't run into this before, but a terrible assumption has // been made all along...effects do NOT have to provide textual parameters. Examples @@ -2824,342 +3475,29 @@ bool VSTEffect::PromptUser() #endif } - mDlg = new VSTEffectDialog(mParent, mName, this, mAEffect); - mDlg->CentreOnParent(); + if (!mDlg) + { + mDlg = new VSTEffectDialog((wxWindow *) parent, mName, this, mAEffect); + mDlg->CentreOnParent(); + } + +#if defined(EXPERIMENTAL_REALTIME_EFFECTS) + mDlg->Show(!mDlg->IsShown()); + + return true; +#else mDlg->ShowModal(); - bool ret = mDlg->GetReturnCode() != 0; - mDlg->Destroy(); + mDlg = NULL; + return ret; +#endif } -bool VSTEffect::Process() -{ - mProcessLevel = 2; // in (simulated) audio thread - - CopyInputTracks(); - bool bGoodResult = true; - - // Some VST effects (Antress Modern is an example), do not like - // overly large block sizes. Unfortunately, I have not found a - // way to determine if the effect has a maximum it will support, - // so just limit to small value for now. This will increase - // processing time and, it's a shame, because most plugins seem - // to be able to handle much larger sizes. - // - // NOTE: This no longer seems to apply to more recent versions - // of Antress plugins, but leaving comment and 8192 default - // just in case. - gPrefs->Read(wxT("/VST/BufferSize"), &mBufferSize, 8192); - - gPrefs->Read(wxT("/VST/UseBufferDelay"), &mUseBufferDelay, true); - mBufferDelay = 0; - - mInBuffer = NULL; - mOutBuffer = NULL; - - TrackListIterator iter(mOutputTracks); - int count = 0; - bool clear = false; - WaveTrack *left = (WaveTrack *) iter.First(); - while (left) { - WaveTrack *right; - sampleCount len; - sampleCount lstart; - sampleCount rstart; - - GetSamples(left, &lstart, &len); - - mChannels = 1; - - right = NULL; - rstart = 0; - if (left->GetLinked() && mInputs > 1) { - right = (WaveTrack *) iter.Next(); - GetSamples(right, &rstart, &len); - clear = false; - mChannels = 2; - } - - if (mBlockSize == 0) { - mBlockSize = mWTBlockSize = left->GetMaxBlockSize() * 2; - - // Limit the buffer size to the user specified value since they may - // have wanted a smaller value for a reason. - if (mBlockSize > mBufferSize) { - mBlockSize = mBufferSize; - } - - mInBuffer = new float *[mInputs]; - for (int i = 0; i < mInputs; i++) { - mInBuffer[i] = new float[mBlockSize]; - } - - //Process 2 audacity blockfiles per WaveTrack::Set independently of mBlockSize - //because it is extremely slow to do multiple Set()s per blockfile. - mOutBuffer = new float *[mOutputs]; - for (int i = 0; i < mOutputs; i++) { - mOutBuffer[i] = new float[mWTBlockSize + mBlockSize]; - } - - // Turn the power off - callDispatcher(effMainsChanged, 0, 0, NULL, 0.0); - - // Set processing parameters - callDispatcher(effSetSampleRate, 0, 0, NULL, left->GetRate()); - callDispatcher(effSetBlockSize, 0, mBlockSize, NULL, 0.0); - } - - // Clear unused input buffers - if (!right && !clear) { - for (int i = 1; i < mInputs; i++) { - for (int j = 0; j < mBlockSize; j++) { - mInBuffer[i][j] = 0.0; - } - } - clear = true; - } - - bGoodResult = ProcessStereo(count, left, right, lstart, rstart, len); - if (!bGoodResult) { - break; - } - - left = (WaveTrack *) iter.Next(); - count++; - } - - if (mOutBuffer) { - for (int i = 0; i < mOutputs; i++) { - delete mOutBuffer[i]; - } - delete [] mOutBuffer; - mOutBuffer = NULL; - } - - if (mInBuffer) { - for (int i = 0; i < mInputs; i++) { - delete mInBuffer[i]; - } - delete [] mInBuffer; - mInBuffer = NULL; - } - - ReplaceProcessedTracks(bGoodResult); - return bGoodResult; -} - -bool VSTEffect::ProcessStereo(int count, - WaveTrack *left, WaveTrack *right, - sampleCount lstart, sampleCount rstart, - sampleCount len) -{ - bool rc = true; - //sampleCount amountLeft = 0; - - // Initialize time info - mTimeInfo.samplePos = 0.0; - mTimeInfo.sampleRate = left->GetRate(); - mTimeInfo.flags |= kVstTransportPlaying; - - // Turn the power on - callDispatcher(effMainsChanged, 0, 1, NULL, 0.0); - - // Tell effect we're starting to process - callDispatcher(effStartProcess, 0, 0, NULL, 0.0); - - // Get the initial latency - SetBufferDelay(mAEffect->initialDelay); - - // LLL: - // - // Some explanation to what this mess is all about. - // (see history above) - // - // For each input block of samples, we pass it to the VST effect along with a - // variable output location. This output location is simply a pointer into a - // much larger buffer. This reduces the number of calls required to add the - // samples to the output track which was Michael's speed up mentioned above. - // - // The buffer delay compensation adds even more complexitity... - // - // Upon return from the effect, the output samples are "moved to the left" by - // the number of samples in the current delay setting, effectively removing the - // delay introduced by the effect. - // - // At the same time the total number of delayed samples are gathered and when the - // there is no further input data to process, the loop continues to call the - // effect with an empty input buffer until the effect has had a chance to - // return all of the remaining delayed samples. - // - // Please note, that this process has next to no documetation on how it should - // work, so a lot of this was from trial and error. It appears to be correct - // though since it has worked with every plugin I've found that adds latency, - // with the exception of kn0ck0ut. I'm sure there are other effects out there - // that add latency but do not provide the delay information, so be wary. :-) - sampleCount originalLen = len; - sampleCount ls = lstart; - sampleCount rs = rstart; - sampleCount outls = lstart; - sampleCount outrs = rstart; - sampleCount outBufferCursor = 0; - float **outBufSegment = new float *[mOutputs]; - sampleCount delay = 0; - sampleCount delayed = 0; - bool cleared = false; - - // Call the effect until we run out of input or delayed samples - while (len || delayed) { - sampleCount block = mBlockSize; - - // As long as we have input samples, use those - if (len) { - // At the end if we don't have enough left for a whole block - if (block > len) { - block = len; - } - - // Get the samples into our buffer - left->Get((samplePtr)mInBuffer[0], floatSample, ls, block); - if (right) { - right->Get((samplePtr)mInBuffer[1], floatSample, rs, block); - } - } - // We've reached the end of the input samples, so start processing - // delayed ones if there are any - else if (delayed) { - // At the end if we don't have enough left for a whole block - if (block > delayed) { - block = delayed; - } - - // Clear the input buffer so that we only pass zeros to the effect. - if (!cleared) { - for (int i = 1; i < mInputs; i++) { - for (int j = 0; j < mBlockSize; j++) { - mInBuffer[i][j] = 0.0; - } - } - cleared = true; - } - } - - // Set current output pointer - for (int i = 0; i < mOutputs; i++) { - outBufSegment[i] = mOutBuffer[i] + outBufferCursor; - } - - // Go let the effect moleste the samples - callProcessReplacing(mInBuffer, outBufSegment, block); - - // Get the current number of delayed samples and accumulate - delay += mBufferDelay; - delayed += mBufferDelay; - - // Reset...the effect will set this again if it has a further - // need to delay samples...some effects only set the value once - // at the start of processing. - mBufferDelay = 0; - - // If the effect has delayed the output by more samples than our - // current block size, then we leave the output pointers where they - // are. This will effectively remove those delayed samples from the - // output buffer. - if (delay >= block) { - delay -= block; - } - // We have some delayed samples, at the beginning of the output samples, - // so overlay them by shifting the remaining output samples. - else if (delay > 0) { - sampleCount oblock = block - delay; - for (int i = 0; i < mOutputs; i++) { - memmove(outBufSegment[i], outBufSegment[i] + delay, SAMPLE_SIZE(floatSample) * oblock); - } - delay = 0; - outBufferCursor += oblock; - } - // no delay, just bump to the new output location - else { - outBufferCursor += block; - } - - // Process 2 audacity blockfiles per WaveTrack::Set independently of mBlockSize - // because it is extremely slow to do multiple Set()s per blockfile due to Undo History - // If we do more optimization we should probably align the Sets to blockfile boundries. - if (outBufferCursor >= mWTBlockSize) { - left->Set((samplePtr)mOutBuffer[0], floatSample, outls, mWTBlockSize); - if (right) { - right->Set((samplePtr)mOutBuffer[1], floatSample, outrs, mWTBlockSize); - } - if (outBufferCursor >= mWTBlockSize) { - //snake the buffer down - memmove(mOutBuffer[0], mOutBuffer[0] + mWTBlockSize, SAMPLE_SIZE(floatSample) * (outBufferCursor - mWTBlockSize)); - memmove(mOutBuffer[1], mOutBuffer[1] + mWTBlockSize, SAMPLE_SIZE(floatSample) * (outBufferCursor - mWTBlockSize)); - } - outBufferCursor -= mWTBlockSize; - outls += mWTBlockSize; - outrs += mWTBlockSize; - } - - // Still processing input samples - if (len) { - len -= block; - } - // Or maybe we're working on delayed samples - else if (delayed) { - delayed -= block; - } - - // "ls" and "rs" serve as the input sample index for the left and - // right channels when processing the input samples. If we flip - // over to processing delayed samples, the simply become counters - // for the progress display. - ls += block; - rs += block; - mTimeInfo.samplePos += ((double) block / mTimeInfo.sampleRate); - - if (mInputs > 1) { - if (TrackGroupProgress(count, (ls - lstart) / (double)originalLen)) { - rc = false; - break; - } - } - else { - if (TrackProgress(count, (ls - lstart) / (double)originalLen)) { - rc = false; - break; - } - } - } - - // Finish taking the remainder - if (outBufferCursor) { - left->Set((samplePtr)mOutBuffer[0], floatSample, outls, outBufferCursor); - if (right) { - right->Set((samplePtr)mOutBuffer[1], floatSample, outrs, outBufferCursor); - } - } - - // Tell effect we're done - callDispatcher(effStopProcess, 0, 0, NULL, 0.0); - - // Turn the power off - callDispatcher(effMainsChanged, 0, 0, NULL, 0.0); - - // No longer playing - mTimeInfo.samplePos = 0.0; - mTimeInfo.sampleRate = 44100.0; - mTimeInfo.tempo = 120.0; - mTimeInfo.timeSigNumerator = 4; - mTimeInfo.timeSigDenominator = 4; - mTimeInfo.flags = kVstTempoValid | kVstNanosValid; - - return rc; -} - -void VSTEffect::End() +void VSTEffect::InterfaceClosed() { + mDlg = NULL; } bool VSTEffect::Load() @@ -3186,7 +3524,8 @@ bool VSTEffect::Load() path, kCFURLPOSIXPathStyle, true); - if (urlRef == NULL) { + if (urlRef == NULL) + { return false; } @@ -3197,13 +3536,15 @@ bool VSTEffect::Load() CFRelease(urlRef); // Bail if the bundle wasn't created - if (bundleRef == NULL) { + if (bundleRef == NULL) + { return false; } // Retrieve a reference to the executable CFURLRef exeRef = CFBundleCopyExecutableURL(bundleRef); - if (exeRef == NULL) { + if (exeRef == NULL) + { CFRelease(bundleRef); return false; } @@ -3216,14 +3557,16 @@ bool VSTEffect::Load() CFRelease(exeRef); // Bail if we couldn't resolve the executable path - if (good == FALSE) { + if (good == FALSE) + { CFRelease(bundleRef); return false; } // Attempt to open it mModule = dlopen((char *) exePath, RTLD_NOW | RTLD_LOCAL); - if (mModule == NULL) { + if (mModule == NULL) + { CFRelease(bundleRef); return false; } @@ -3232,12 +3575,14 @@ bool VSTEffect::Load() pluginMain = (vstPluginMain) dlsym(mModule, "VSTPluginMain"); // If not found, try finding the old entry point - if (pluginMain == NULL) { + if (pluginMain == NULL) + { pluginMain = (vstPluginMain) dlsym(mModule, "main_macho"); } // Must not be a VST plugin - if (pluginMain == NULL) { + if (pluginMain == NULL) + { dlclose(mModule); mModule = NULL; CFRelease(bundleRef); @@ -3251,28 +3596,32 @@ bool VSTEffect::Load() // Open the resource map ... some plugins (like GRM Tools) need this. mResource = (int) CFBundleOpenBundleResourceMap(bundleRef); -#else +#elif defined(__WXMSW__) { wxLogNull nolog; // Try to load the library wxDynamicLibrary *lib = new wxDynamicLibrary(mPath); - if (!lib) { + if (!lib) + { return false; } // Bail if it wasn't successful - if (!lib->IsLoaded()) { + if (!lib->IsLoaded()) + { delete lib; return false; } // Try to find the entry point, while suppressing error messages pluginMain = (vstPluginMain) lib->GetSymbol(wxT("VSTPluginMain")); - if (pluginMain == NULL) { + if (pluginMain == NULL) + { pluginMain = (vstPluginMain) lib->GetSymbol(wxT("main")); - if (pluginMain == NULL) { + if (pluginMain == NULL) + { delete lib; return false; } @@ -3282,37 +3631,123 @@ bool VSTEffect::Load() mModule = lib; } +#else + + // Attempt to load it + // + // Spent a few days trying to figure out why some VSTs where running okay and + // others were hit or miss. The cause was that we export all of Audacity's + // symbols and some of the loaded libraries were picking up Audacity's and + // not their own. + // + // So far, I've only seen this issue on Linux, but we might just be getting + // lucky on the Mac and Windows. The sooner we stop exporting everything + // the better. + // + // To get around the problem, I just added the RTLD_DEEPBIND flag to the load + // and that "basically" puts Audacity last when the loader needs to resolve + // symbols. + // + // Once we define a proper external API, the flags can be removed. + void *lib = dlopen((const char *)wxString(mPath).ToUTF8(), RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND); + if (!lib) + { + return false; + } + + // Try to find the entry point, while suppressing error messages + pluginMain = (vstPluginMain) dlsym(lib, "VSTPluginMain"); + if (pluginMain == NULL) + { + pluginMain = (vstPluginMain) dlsym(lib, "main"); + if (pluginMain == NULL) + { + dlclose(lib); + return false; + } + } + + // Save the library reference + mModule = lib; + #endif // Initialize the plugin - mAEffect = pluginMain(audioMaster); + try + { + mAEffect = pluginMain(VSTEffect::AudioMaster); + } + catch (...) + { + wxLogMessage(_("VST plugin initialization failed\n")); + mAEffect = NULL; + } // Was it successful? - if (mAEffect) { + if (mAEffect) + { + // Save a reference to ourselves // + // Note: Some hosts use "user" and some use "ptr2/resvd2". It might + // be worthwhile to check if user is NULL before using it and + // then falling back to "ptr2/resvd2". mAEffect->user = this; - // + // Give the plugin an initial sample rate and blocksize + callDispatcher(effSetSampleRate, 0, 0, NULL, 48000.0); + callDispatcher(effSetBlockSize, 0, 512, NULL, 0); + + // Ask the plugin to identify itself...might be needed for older plugins + callDispatcher(effIdentify, 0, 0, NULL, 0); + + // Open the plugin callDispatcher(effOpen, 0, 0, NULL, 0.0); + // Set it again in case plugin ignored it before the effOpen + callDispatcher(effSetSampleRate, 0, 0, NULL, 48000.0); + callDispatcher(effSetBlockSize, 0, 512, NULL, 0); + // Ensure that it looks like a plugin and can deal with ProcessReplacing // calls. Also exclude synths for now. if (mAEffect->magic == kEffectMagic && !(mAEffect->flags & effFlagsIsSynth) && - mAEffect->flags & effFlagsCanReplacing) { - - mVendor = GetString(effGetVendorString); + mAEffect->flags & effFlagsCanReplacing) + { mName = GetString(effGetEffectName); - mInputs = mAEffect->numInputs; - mOutputs = mAEffect->numOutputs; + if (mName.length() == 0) + { + mName = GetString(effGetProductString); + if (mName.length() == 0) + { + wxFileName f(mPath); + mName = f.GetName(); + } + } + mVendor = GetString(effGetVendorString); + mVersion = wxINT32_SWAP_ON_LE(callDispatcher(effGetVendorVersion, 0, 0, NULL, 0)); + if (mVersion == 0) + { + mVersion = wxINT32_SWAP_ON_LE(mAEffect->version); + } - // We could even go so far as to run a small test here. + if (mAEffect->flags & effFlagsHasEditor || mAEffect->numParams != 0) + { + mInteractive = true; + } + mAudioIns = mAEffect->numInputs; + mAudioOuts = mAEffect->numOutputs; + + mMidiIns = 0; + mMidiOuts = 0; + + // Pretty confident that we're good to go success = true; } } - if (!success) { + if (!success) + { Unload(); } @@ -3321,25 +3756,48 @@ bool VSTEffect::Load() void VSTEffect::Unload() { - if (mAEffect) { + if (mTimer) + { + mTimer->Stop(); + delete mTimer; + mTimer = NULL; + } + + if (mAEffect) + { + // Turn the power off + PowerOff(); + + // Finally, close the plugin callDispatcher(effClose, 0, 0, NULL, 0.0); } - if (mModule) { + if (mModule) + { #if defined(__WXMAC__) - if (mResource != -1) { + + if (mResource != -1) + { CFBundleCloseBundleResourceMap((CFBundleRef) mBundleRef, mResource); mResource = -1; } - if (mBundleRef != NULL) { + if (mBundleRef != NULL) + { CFRelease((CFBundleRef) mBundleRef); mBundleRef = NULL; } dlclose(mModule); -#else + +#elif defined(__WXMSW__) + delete (wxDynamicLibrary *) mModule; + +#else + + dlclose(mModule); + #endif mModule = NULL; @@ -3347,213 +3805,98 @@ void VSTEffect::Unload() } } -void VSTEffect::ScanOnePlugin( const wxString & file ) +void VSTEffect::LoadParameters(const wxString & group) { - const wxChar * argv[4]; - argv[0] = PlatformCompatibility::GetExecutablePath().c_str(); - argv[1] = VSTCMDKEY; - argv[2] = file.c_str(); - argv[3] = NULL; - // ToDo: do we need a try--catch around this in case a bad plug-in - // fails? (JKC Nov09) - wxExecute((wxChar **) argv, wxEXEC_SYNC | wxEXEC_NODISABLE, NULL); -} + wxString value; -int VSTEffect::ShowPluginListDialog( const wxArrayString & files ) -{ - PluginRegistrationDialog d( wxGetApp().GetTopWindow(), files ); - return d.ShowModal(); -} + if (mHost->GetPrivateConfig(group, wxT("Chunk"), value, wxEmptyString)) + { + char *buf = new char[value.length() / 4 * 3]; -void VSTEffect::ShowProgressDialog( const wxString & longest, const wxArrayString & files ) -{ - ProgressDialog *progress = new ProgressDialog(_("Scanning VST Plugins"), - longest, - pdlgHideStopButton); -// progress->SetSize(wxSize(500, -1)); - progress->CenterOnScreen(); - - size_t cnt = files.GetCount(); - for (size_t i = 0; i < cnt; i++) { - wxString file = files[i]; - int status = progress->Update(wxLongLong(i), - wxLongLong(cnt), - wxString::Format(_("Checking %s"), file.c_str())); - if (status != eProgressSuccess) { - break; + int len = VSTEffect::b64decode(value, buf); + if (len) + { + callDispatcher(effSetChunk, 1, len, buf, 0.0); } - ScanOnePlugin( file ); + + delete [] buf; + + return; } - delete progress; -} + if (mHost->GetPrivateConfig(group, wxT("Value"), value, wxEmptyString)) + { + wxStringTokenizer st(value, wxT(',')); + for (int i = 0; st.HasMoreTokens(); i++) + { + double val = 0.0; + st.GetNextToken().ToDouble(&val); -/* static */ -int VSTEffect::Scan() -{ - wxArrayString audacityPathList = wxGetApp().audacityPathList; - wxArrayString pathList; - wxArrayString files; - - // Check for the VST_PATH environment variable - wxString vstpath = wxGetenv(wxT("VST_PATH")); - if (!vstpath.IsEmpty()) { - wxGetApp().AddUniquePathToPathList(vstpath, pathList); - } - - // Add Audacity specific paths - for (size_t i = 0; i < audacityPathList.GetCount(); i++) { - wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH; - wxGetApp().AddUniquePathToPathList(prefix + VSTPLUGINTYPE, - pathList); - wxGetApp().AddUniquePathToPathList(prefix + wxT("plugins"), - pathList); - wxGetApp().AddUniquePathToPathList(prefix + wxT("plug-ins"), - pathList); - } - -#if defined(__WXMAC__) -#define VSTPATH wxT("/Library/Audio/Plug-Ins/VST") - - // Look in /Library/Audio/Plug-Ins/VST and $HOME/Library/Audio/Plug-Ins/VST - wxGetApp().AddUniquePathToPathList(VSTPATH, pathList); - wxGetApp().AddUniquePathToPathList(wxString(wxGetenv(wxT("HOME"))) + VSTPATH, - pathList); - - // Recursively search all paths for Info.plist files. This will identify all - // bundles. - wxGetApp().FindFilesInPathList(wxT("Info.plist"), pathList, files, wxDIR_DEFAULT); - - // Remove the 'Contents/Info.plist' portion of the names - for (size_t i = 0; i < files.GetCount(); i++) { - files[i] = wxPathOnly(wxPathOnly(files[i])); - if (!files[i].EndsWith(wxT(".vst"))) { - files.RemoveAt(i--); + if (val >= -1.0 && val <= 1.0) + { + callSetParameter(i, val); + } } } - -#elif defined(__WXMSW__) - - TCHAR dpath[MAX_PATH]; - TCHAR tpath[MAX_PATH]; - DWORD len; - - // Try HKEY_CURRENT_USER registry key first - len = sizeof(tpath) / sizeof(TCHAR); - if (SHRegGetUSValue(wxT("Software\\VST"), - wxT("VSTPluginsPath"), - NULL, - tpath, - &len, - FALSE, - NULL, - 0) == ERROR_SUCCESS) { - tpath[len] = 0; - dpath[0] = 0; - ExpandEnvironmentStrings(tpath, dpath, WXSIZEOF(dpath)); - wxGetApp().AddUniquePathToPathList(LAT1CTOWX(dpath), pathList); - } - - // Then try HKEY_LOCAL_MACHINE registry key - len = sizeof(tpath) / sizeof(TCHAR); - if (SHRegGetUSValue(wxT("Software\\VST"), - wxT("VSTPluginsPath"), - NULL, - tpath, - &len, - TRUE, - NULL, - 0) == ERROR_SUCCESS) { - tpath[len] = 0; - dpath[0] = 0; - ExpandEnvironmentStrings(tpath, dpath, WXSIZEOF(dpath)); - wxGetApp().AddUniquePathToPathList(LAT1CTOWX(dpath), pathList); - } - - // Add the default path last - dpath[0] = 0; - ExpandEnvironmentStrings(wxT("%ProgramFiles%\\Steinberg\\VSTPlugins"), - dpath, - WXSIZEOF(dpath)); - wxGetApp().AddUniquePathToPathList(LAT1CTOWX(dpath), pathList); - - // Recursively scan for all DLLs - wxGetApp().FindFilesInPathList(wxT("*.dll"), pathList, files, wxDIR_DEFAULT); - -#else - - // Recursively scan for all shared objects - wxGetApp().FindFilesInPathList(wxT("*.so"), pathList, files); - -#endif - - files.Sort(); - - // This is a hack to allow for long paths in the progress dialog. The - // progress dialog should really truncate the message if it's too wide - // for the dialog. - size_t cnt = files.GetCount(); - wxString longest; - - // JKC: Let's not show the progress dialog if there are no - // files to test. - if( cnt <= 0 ) - return wxID_OK; - - for (size_t i = 0; i < cnt; i++) { - if (files[i].Length() > longest.Length()) { - longest = files[i]; - } - } - //Choose the first for the original version which scans them all - //The second to selectively scan. - //ShowProgressDialog( longest, files ); - return ShowPluginListDialog( files ); -} - -/* static */ -void VSTEffect::Check(const wxChar *fname) -{ - PluginManager & pm = PluginManager::Get(); - - pm.Open(); - - VSTEffect *e = new VSTEffect(fname); - - pm.Close(); - - if (e) { - delete e; - } } -int VSTEffect::NeedIdle() +void VSTEffect::SaveParameters(const wxString & group) { - int ret = callDispatcher(effIdle, 0, 0, NULL, 0.0); - - // Effect wants continuous idle calls - if (ret) { - if (!mTimer) { - mTimer = new VSTEffectTimer(this); - } - if (mTimer) { - mTimer->Start(100); - } - } - else { - if (mTimer) { - mTimer->Stop(); - delete mTimer; - mTimer = NULL; + if (mAEffect->flags & effFlagsProgramChunks) + { + void *chunk = NULL; + int clen = (int) callDispatcher(effGetChunk, 1, 0, &chunk, 0.0); + if (clen > 0) + { + mHost->SetPrivateConfig(group, wxT("Chunk"), VSTEffect::b64encode(chunk, clen)); + return; } } - return ret; + wxString parms; + for (int i = 0; i < mAEffect->numParams; i++) + { + parms += wxString::Format(wxT(",%f"), callGetParameter(i)); + } + + mHost->SetPrivateConfig(group, wxT("Value"), parms.Mid(1)); } -int VSTEffect::GetChannels() +void VSTEffect::OnTimer() { - return mChannels; + wxRecursionGuard guard(mTimerGuard); + + // Ignore it if we're recursing + if (guard.IsInside()) + { + return; + } + + if (mWantsIdle) + { + int ret = callDispatcher(effIdle, 0, 0, NULL, 0.0); + if (!ret) + { + mWantsIdle = false; + } + } + + if (mWantsEditIdle) + { + callDispatcher(effEditIdle, 0, 0, NULL, 0.0); + } +} + +void VSTEffect::NeedIdle() +{ + mWantsIdle = true; + mTimer->Start(100); +} + +void VSTEffect::NeedEditIdle(bool state) +{ + mWantsEditIdle = state; + mTimer->Start(100); } VstTimeInfo *VSTEffect::GetTimeInfo() @@ -3572,10 +3915,41 @@ int VSTEffect::GetProcessLevel() return mProcessLevel; } +void VSTEffect::PowerOn() +{ + if (!mHasPower) + { + // Turn the power on + callDispatcher(effMainsChanged, 0, 1, NULL, 0.0); + + // Tell the effect we're going to start processing + callDispatcher(effStartProcess, 0, 0, NULL, 0.0); + + // Set state + mHasPower = true; + } +} + +void VSTEffect::PowerOff() +{ + if (mHasPower) + { + // Tell the effect we're going to stop processing + callDispatcher(effStopProcess, 0, 0, NULL, 0.0); + + // Turn the power off + callDispatcher(effMainsChanged, 0, 0, NULL, 0.0); + + // Set state + mHasPower = false; + } +} + void VSTEffect::SizeWindow(int w, int h) { // Queue the event to make the resizes smoother - if (mDlg) { + if (mDlg) + { wxCommandEvent sw(EVT_SIZEWINDOW); sw.SetInt(w); sw.SetExtraLong(h); @@ -3588,18 +3962,24 @@ void VSTEffect::SizeWindow(int w, int h) void VSTEffect::UpdateDisplay() { // Tell the dialog to refresh effect information - if (mDlg) { + if (mDlg) + { wxCommandEvent ud(EVT_UPDATEDISPLAY); mDlg->GetEventHandler()->AddPendingEvent(ud); } + + return; } void VSTEffect::SetBufferDelay(int samples) { // We do not support negative delay - if (samples >= 0 && mUseBufferDelay) { + if (samples >= 0 && mUseBufferDelay) + { mBufferDelay = samples; } + + return; } int VSTEffect::GetString(wxString & outstr, int opcode, int index) @@ -3610,7 +3990,7 @@ int VSTEffect::GetString(wxString & outstr, int opcode, int index) callDispatcher(opcode, index, 0, buf, 0.0); - outstr = LAT1CTOWX(buf); + outstr = wxString::FromUTF8(buf); return 0; } @@ -3627,8 +4007,7 @@ wxString VSTEffect::GetString(int opcode, int index) void VSTEffect::SetString(int opcode, const wxString & str, int index) { char buf[256]; - - strcpy(buf, str.Left(255).mb_str()); + strcpy(buf, str.Left(255).ToUTF8()); callDispatcher(opcode, index, 0, buf, 0.0); } @@ -3636,14 +4015,11 @@ void VSTEffect::SetString(int opcode, const wxString & str, int index) intptr_t VSTEffect::callDispatcher(int opcode, int index, intptr_t value, void *ptr, float opt) { + // Needed since we might be in the dispatcher when the timer pops + wxCRIT_SECT_LOCKER(locker, mDispatcherLock); return mAEffect->dispatcher(mAEffect, opcode, index, value, ptr, opt); } -void VSTEffect::callProcess(float **inputs, float **outputs, int sampleframes) -{ - mAEffect->process(mAEffect, inputs, outputs, sampleframes); -} - void VSTEffect::callProcessReplacing(float **inputs, float **outputs, int sampleframes) { @@ -3660,4 +4036,135 @@ float VSTEffect::callGetParameter(int index) return mAEffect->getParameter(mAEffect, index); } +//////////////////////////////////////////////////////////////////////////////// +// Base64 en/decoding +// +// Original routines marked as public domain and found at: +// +// http://en.wikibooks.org/wiki/Algorithm_implementation/Miscellaneous/Base64 +// +//////////////////////////////////////////////////////////////////////////////// + +// Lookup table for encoding +const static wxChar cset[] = wxT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); +const static char padc = wxT('='); + +wxString VSTEffect::b64encode(const void *in, int len) +{ + unsigned char *p = (unsigned char *) in; + wxString out; + + unsigned long temp; + for (int i = 0; i < len / 3; i++) + { + temp = (*p++) << 16; //Convert to big endian + temp += (*p++) << 8; + temp += (*p++); + out += cset[(temp & 0x00FC0000) >> 18]; + out += cset[(temp & 0x0003F000) >> 12]; + out += cset[(temp & 0x00000FC0) >> 6]; + out += cset[(temp & 0x0000003F)]; + } + + switch (len % 3) + { + case 1: + temp = (*p++) << 16; //Convert to big endian + out += cset[(temp & 0x00FC0000) >> 18]; + out += cset[(temp & 0x0003F000) >> 12]; + out += padc; + out += padc; + break; + + case 2: + temp = (*p++) << 16; //Convert to big endian + temp += (*p++) << 8; + out += cset[(temp & 0x00FC0000) >> 18]; + out += cset[(temp & 0x0003F000) >> 12]; + out += cset[(temp & 0x00000FC0) >> 6]; + out += padc; + break; + } + + return out; +} + +int VSTEffect::b64decode(wxString in, void *out) +{ + int len = in.length(); + unsigned char *p = (unsigned char *) out; + + if (len % 4) //Sanity check + { + return 0; + } + + int padding = 0; + if (len) + { + if (in[len - 1] == padc) + { + padding++; + } + + if (in[len - 2] == padc) + { + padding++; + } + } + + //const char *a = in.mb_str(); + //Setup a vector to hold the result + unsigned long temp = 0; //Holds decoded quanta + int i = 0; + while (i < len) + { + for (int quantumPosition = 0; quantumPosition < 4; quantumPosition++) + { + unsigned char c = in[i]; + temp <<= 6; + + if (c >= 0x41 && c <= 0x5A) + { + temp |= c - 0x41; + } + else if (c >= 0x61 && c <= 0x7A) + { + temp |= c - 0x47; + } + else if (c >= 0x30 && c <= 0x39) + { + temp |= c + 0x04; + } + else if (c == 0x2B) + { + temp |= 0x3E; + } + else if (c == 0x2F) + { + temp |= 0x3F; + } + else if (c == padc) + { + switch (len - i) + { + case 1: //One pad character + *p++ = (temp >> 16) & 0x000000FF; + *p++ = (temp >> 8) & 0x000000FF; + return p - (unsigned char *) out; + case 2: //Two pad characters + *p++ = (temp >> 10) & 0x000000FF; + return p - (unsigned char *) out; + } + } + i++; + } + *p++ = (temp >> 16) & 0x000000FF; + *p++ = (temp >> 8) & 0x000000FF; + *p++ = temp & 0x000000FF; + } + + return p - (unsigned char *) out; +} + #endif // USE_VST diff --git a/src/effects/VST/VSTEffect.h b/src/effects/VST/VSTEffect.h index 97b5ed2e3..4657deb19 100644 --- a/src/effects/VST/VSTEffect.h +++ b/src/effects/VST/VSTEffect.h @@ -8,83 +8,133 @@ **********************************************************************/ -#include "../../Audacity.h" - #if USE_VST -#include "../Effect.h" +#include "audacity/EffectInterface.h" +#include "audacity/ModuleInterface.h" +#include "audacity/PluginInterface.h" #include "aeffectx.h" -#define VSTCMDKEY wxT("-checkvst") -#define VSTPLUGINTYPE wxT("VST") +#define VSTCMDKEY L"-checkvst" +#define VSTPLUGINTYPE L"VST" #define audacityVSTID CCONST('a', 'u', 'D', 'y'); -typedef intptr_t (*dispatcherFn)(AEffect * effect, int opCode, - int index, intptr_t value, void *ptr, +typedef intptr_t (*dispatcherFn)(AEffect * effect, + int opCode, + int index, + intptr_t value, + void *ptr, float opt); -typedef void (*processFn)(AEffect * effect, float **inputs, - float **outputs, int sampleframes); +typedef void (*processFn)(AEffect * effect, + float **inputs, + float **outputs, + int sampleframes); -typedef void (*setParameterFn)(AEffect * effect, int index, +typedef void (*setParameterFn)(AEffect * effect, + int index, float parameter); -typedef float (*getParameterFn)(AEffect * effect, int index); +typedef float (*getParameterFn)(AEffect * effect, + int index); typedef AEffect *(*vstPluginMain)(audioMasterCallback audioMaster); class VSTEffectTimer; class VSTEffectDialog; -class VSTEffect:public Effect +class VSTEffect : public EffectClientInterface { public: - VSTEffect(const wxString & path); virtual ~VSTEffect(); - virtual wxString GetEffectName(); + // IdentInterface implementation + virtual PluginID GetID(); + virtual wxString GetPath(); + virtual wxString GetName(); + virtual wxString GetVendor(); + virtual wxString GetVersion(); + virtual wxString GetDescription(); - virtual wxString GetEffectIdentifier(); + // EffectIdentInterface implementation + virtual EffectType GetType(); + virtual wxString GetFamily(); + virtual bool IsInteractive(); + virtual bool IsDefault(); + virtual bool IsLegacy(); + virtual bool IsRealtimeCapable(); - virtual std::set GetEffectCategories(); + // EffectClientInterface implementation + virtual void SetHost(EffectHostInterface *host); + virtual bool Startup(); + virtual bool Shutdown(); - virtual wxString GetEffectAction(); + virtual int GetAudioInCount(); + virtual int GetAudioOutCount(); - virtual bool Init(); + virtual int GetMidiInCount(); + virtual int GetMidiOutCount(); - virtual bool PromptUser(); + virtual sampleCount GetLatency(); + virtual sampleCount GetTailSize(); - virtual bool Process(); + virtual void SetSampleRate(sampleCount rate); + virtual sampleCount GetBlockSize(sampleCount maxBlockSize); - virtual void End(); + virtual bool IsReady(); + virtual bool ProcessInitialize(); + virtual bool ProcessFinalize(); + virtual sampleCount ProcessBlock(float **inbuf, float **outbuf, sampleCount size); + virtual bool RealtimeInitialize(int numChannels, float sampleRate); + virtual bool RealtimeFinalize(); + virtual bool RealtimeSuspend(); + virtual bool RealtimeResume(); + virtual sampleCount RealtimeProcess(float **inbuf, float **outbuf, sampleCount size); + + virtual bool ShowInterface(void *parent); + + // VSTEffect implementation + + // VST plugin -> host callback + static intptr_t AudioMaster(AEffect *effect, + int32_t opcode, + int32_t index, + intptr_t value, + void * ptr, + float opt); + + void OnTimer(); + +private: // Plugin loading and unloading - bool Load(); void Unload(); - // Plugin probing + // Parameter loading and saving + void LoadParameters(const wxString & group); + void SaveParameters(const wxString & group); - static int Scan(); - static void Check(const wxChar *fname); - - static void ScanOnePlugin( const wxString & file ); - static int ShowPluginListDialog( const wxArrayString & files ); - static void ShowProgressDialog( const wxString & longest, const wxArrayString & files ); + // Base64 encoding and decoding + static wxString b64encode(const void *in, int len); + static int b64decode(wxString in, void *out); // Utility methods - int GetChannels(); VstTimeInfo *GetTimeInfo(); float GetSampleRate(); int GetProcessLevel(); void SetBufferDelay(int samples); - int NeedIdle(); + void NeedIdle(); + void NeedEditIdle(bool state); void UpdateDisplay(); void SizeWindow(int w, int h); + void PowerOn(); + void PowerOff(); + void InterfaceClosed(); int GetString(wxString & outstr, int opcode, int index = 0); wxString GetString(int opcode, int index = 0); @@ -93,54 +143,93 @@ class VSTEffect:public Effect // VST methods intptr_t callDispatcher(int opcode, int index, intptr_t value, void *ptr, float opt); - void callProcess(float **inputs, float **outputs, int sampleframes); void callProcessReplacing(float **inputs, float **outputs, int sampleframes); void callSetParameter(int index, float parameter); float callGetParameter(int index); - private: - bool ProcessStereo(int count, - WaveTrack *left, - WaveTrack *right, - sampleCount lstart, - sampleCount rstart, - sampleCount len); - + EffectHostInterface *mHost; + PluginID mID; wxString mPath; + int mAudioIns; + int mAudioOuts; + int mMidiIns; + int mMidiOuts; + float mSampleRate; + sampleCount mUserBlockSize; + wxString mName; + wxString mVendor; + wxString mDescription; + int mVersion; + bool mInteractive; + + bool mReady; + #if defined(__WXMAC__) - // Cheating a little ... type is really CFBundle - void *mBundleRef; - // Cheating a little ... type is really CFBundleRefNum - int mResource; + void *mBundleRef; // Cheating a little ... type is really CFBundle + int mResource; // Cheating a little ... type is really CFBundle #endif void *mModule; AEffect *mAEffect; VSTEffectDialog *mDlg; - wxString mVendor; - wxString mName; - VstTimeInfo mTimeInfo; bool mUseBufferDelay; int mBufferDelay; - int mBufferSize; - sampleCount mBlockSize; - sampleCount mWTBlockSize; - float **mInBuffer; - float **mOutBuffer; - int mInputs; - int mOutputs; - int mChannels; + int mProcessLevel; + bool mHasPower; + bool mWantsIdle; + bool mWantsEditIdle; + + wxCRIT_SECT_DECLARE_MEMBER(mDispatcherLock); VSTEffectTimer *mTimer; + int mTimerGuard; + + friend class VSTEffectDialog; + friend class VSTEffectsModule; }; void RegisterVSTEffects(); +class VSTEffectsModule : public ModuleInterface +{ +public: + VSTEffectsModule(ModuleManagerInterface *moduleManager, const wxString *path); + virtual ~VSTEffectsModule(); + + // IdentInterface implementatino + + virtual wxString GetID(); + virtual wxString GetPath(); + virtual wxString GetName(); + virtual wxString GetVendor(); + virtual wxString GetVersion(); + virtual wxString GetDescription(); + + // ModuleInterface implementation + + virtual bool Initialize(); + virtual void Terminate(); + + virtual bool AutoRegisterPlugins(PluginManagerInterface & pm); + virtual wxArrayString FindPlugins(PluginManagerInterface & pm); + virtual bool RegisterPlugin(PluginManagerInterface & pm, const wxString & path); + + virtual void *CreateInstance(const PluginID & ID, const wxString & path); + + // VSTEffectModule implementation + + static void Check(const wxChar *path); + +private: + ModuleManagerInterface *mModMan; + wxString mPath; +}; + #endif // USE_VST diff --git a/src/effects/VST/aeffectx.h b/src/effects/VST/aeffectx.h index 3cd578ca3..ae498f3b1 100644 --- a/src/effects/VST/aeffectx.h +++ b/src/effects/VST/aeffectx.h @@ -107,6 +107,7 @@ const int effEditOpen = 14; const int effEditClose = 15; const int effEditIdle = 19; const int effEditTop = 20; +const int effIdentify = 22; // from http://www.asseca.org/vst-24-specs/efIdentify.html const int effGetChunk = 23; // from Ardour const int effSetChunk = 24; // from Ardour const int effProcessEvents = 25; @@ -277,8 +278,7 @@ public: void *user; // Id 48-4b int32_t uniqueID; - // Don't know 4c-4f - char unknown1[4]; + int32_t version; // processReplacing 50-53 void (* processReplacing)( AEffect * , float * * , float * * , int ); diff --git a/src/effects/audiounits/AudioUnitEffect.cpp b/src/effects/audiounits/AudioUnitEffect.cpp index 84289a737..f707bd784 100644 --- a/src/effects/audiounits/AudioUnitEffect.cpp +++ b/src/effects/audiounits/AudioUnitEffect.cpp @@ -113,7 +113,7 @@ AudioUnitEffect::~AudioUnitEffect() wxString AudioUnitEffect::GetEffectName() { - return mName; + return mName + wxT("..."); } std::set AudioUnitEffect::GetEffectCategories() diff --git a/src/import/Import.cpp b/src/import/Import.cpp index f4c31dee9..60a767be5 100644 --- a/src/import/Import.cpp +++ b/src/import/Import.cpp @@ -66,7 +66,33 @@ WX_DEFINE_LIST(UnusableImportPluginList); WX_DEFINE_LIST(FormatList); WX_DEFINE_OBJARRAY(ExtImportItems); +// ============================================================================ +// +// Return reference to singleton +// +// (Thread-safe...no active threading during construction or after destruction) +// ============================================================================ +Importer Importer::mInstance; +Importer & Importer::Get() +{ + return mInstance; +} + Importer::Importer() +{ + mExtImportItems = NULL; +} + +Importer::~Importer() +{ + if (mExtImportItems != NULL) + { + delete mExtImportItems; + mExtImportItems = NULL; + } +} + +bool Importer::Initialize() { mImportPluginList = new ImportPluginList; mUnusableImportPluginList = new UnusableImportPluginList; @@ -92,17 +118,19 @@ Importer::Importer() #endif ReadImportItems(); + + return true; } -Importer::~Importer() +bool Importer::Terminate() { WriteImportItems(); mImportPluginList->DeleteContents(true); delete mImportPluginList; mUnusableImportPluginList->DeleteContents(true);//JKC delete mUnusableImportPluginList; - if (this->mExtImportItems != NULL) - delete this->mExtImportItems; + + return true; } void Importer::GetSupportedImportFormats(FormatList *formatList) diff --git a/src/import/Import.h b/src/import/Import.h index 108fbe319..72c2b82e7 100644 --- a/src/import/Import.h +++ b/src/import/Import.h @@ -92,6 +92,17 @@ public: Importer(); ~Importer(); + /** + * Return instance reference + */ + static Importer & Get(); + + /** + * Initialization/Termination + */ + bool Initialize(); + bool Terminate(); + /** * Fills @formatList with a list of supported import formats */ @@ -136,6 +147,7 @@ public: wxString &errorMessage); private: + static Importer mInstance; ExtImportItems *mExtImportItems; ImportPluginList *mImportPluginList; diff --git a/src/prefs/EffectsPrefs.cpp b/src/prefs/EffectsPrefs.cpp index 5bfa03198..974444a6d 100644 --- a/src/prefs/EffectsPrefs.cpp +++ b/src/prefs/EffectsPrefs.cpp @@ -23,6 +23,7 @@ #include "../AudacityApp.h" #include "../Languages.h" +#include "../PluginManager.h" #include "../Prefs.h" #include "../ShuttleGui.h" @@ -133,7 +134,19 @@ void EffectsPrefs::PopulateOrExchange(ShuttleGui & S) } S.EndStatic(); #endif +} +void EffectsPrefs::SetState(const wxString & family, const wxString & key) +{ + PluginManager & pm = PluginManager::Get(); + bool state = gPrefs->Read(wxT("/Nyquist/Enable"), true); + + const PluginDescriptor *plug = pm.GetFirstPluginForEffectFamily(family); + while (plug) + { + pm.EnablePlugin(plug->GetID(), state); + plug = pm.GetNextPluginForEffectFamily(family); + } } bool EffectsPrefs::Apply() @@ -141,5 +154,25 @@ bool EffectsPrefs::Apply() ShuttleGui S(this, eIsSavingToPrefs); PopulateOrExchange(S); +#ifdef USE_NYQUIST + SetState(wxT("Nyquist"), wxT("/Nyquist/Enable")); +#endif + +#ifdef USE_LADSPA + SetState(wxT("Ladspa"), wxT("/Ladspa/Enable")); +#endif + +#ifdef USE_LV2 + SetState(wxT("LV2"), wxT("/LV2/Enable")); +#endif + +#ifdef USE_AUDIO_UNITS + SetState(wxT("AudioUnit"), wxT("/AudioUnits/Enable")); +#endif + +#ifdef USE_VAMP + SetState(wxT("VAMP"), wxT("/VAMP/Enable")); +#endif + return true; } diff --git a/src/prefs/EffectsPrefs.h b/src/prefs/EffectsPrefs.h index 845e101cb..73f048fc9 100644 --- a/src/prefs/EffectsPrefs.h +++ b/src/prefs/EffectsPrefs.h @@ -32,6 +32,7 @@ class EffectsPrefs:public PrefsPanel private: void Populate(); void PopulateOrExchange(ShuttleGui & S); + void SetState(const wxString & family, const wxString & key); }; #endif diff --git a/src/prefs/ExtImportPrefs.cpp b/src/prefs/ExtImportPrefs.cpp index ff1992fcc..9e6550cb7 100644 --- a/src/prefs/ExtImportPrefs.cpp +++ b/src/prefs/ExtImportPrefs.cpp @@ -134,7 +134,7 @@ void ExtImportPrefs::PopulateOrExchange(ShuttleGui & S) PluginList->InsertColumn (0, _("Importer order")); PluginList->SetDropTarget (dragtarget2); - ExtImportItems *items = wxGetApp().mImporter->GetImportItems(); + ExtImportItems *items = Importer::Get().GetImportItems(); for (unsigned int i = 0; i < items->Count(); i++) AddItemToTable (i, &(*items)[i]); if (items->Count() > 0) @@ -200,7 +200,7 @@ void ExtImportPrefs::SwapPluginRows (int row1, int row2) long d, d2; ImportPlugin *ip1, *ip2; - ExtImportItems *items = wxGetApp().mImporter->GetImportItems(); + ExtImportItems *items = Importer::Get().GetImportItems(); ExtImportItem *item = &(*items)[last_selected]; t = PluginList->GetItemText (row1); @@ -249,7 +249,7 @@ bool ExtImportPrefs::DoOnPluginKeyDown (int code) if (last_selected == -1) return false; - ExtImportItems *items = wxGetApp().mImporter->GetImportItems(); + ExtImportItems *items = Importer::Get().GetImportItems(); ExtImportItem *item = &(*items)[last_selected]; if (code == WXK_UP && itemIndex == 0) @@ -296,7 +296,7 @@ void ExtImportPrefs::SwapRows (int row1, int row2) row1 = row2; row2 = t; } - ExtImportItems *items = wxGetApp().mImporter->GetImportItems(); + ExtImportItems *items = Importer::Get().GetImportItems(); t1 = items->Detach(row1); t2 = items->Detach(row1); items->Insert (t1, row1); @@ -399,7 +399,7 @@ void ExtImportPrefs::OnRuleTableSelectRange (wxGridRangeSelectEvent& event) void ExtImportPrefs::DoOnRuleTableSelect (int toprow) { - ExtImportItems *items = wxGetApp().mImporter->GetImportItems(); + ExtImportItems *items = Importer::Get().GetImportItems(); if (toprow < 0 || toprow > (int)items->GetCount()) { @@ -451,7 +451,7 @@ void ExtImportPrefs::OnRuleTableEdit (wxGridEvent& event) { int row = event.GetRow(); int col = event.GetCol(); - ExtImportItems *items = wxGetApp().mImporter->GetImportItems(); + ExtImportItems *items = Importer::Get().GetImportItems(); ExtImportItem *item = &(*items)[row]; RuleTable->SaveEditControlValue(); @@ -460,7 +460,7 @@ void ExtImportPrefs::OnRuleTableEdit (wxGridEvent& event) bool askedAboutSpaces = false; wxArrayString vals; wxString delims(wxT(":")); - wxGetApp().mImporter->StringToList (val, delims, vals); + Importer::Get().StringToList (val, delims, vals); switch (col) { case 0: @@ -554,8 +554,8 @@ void ExtImportPrefs::AddItemToTable (int index, ExtImportItem *item) void ExtImportPrefs::OnAddRule(wxCommandEvent& WXUNUSED(event)) { - ExtImportItems *items = wxGetApp().mImporter->GetImportItems(); - ExtImportItem *item = wxGetApp().mImporter->CreateDefaultImportItem(); + ExtImportItems *items = Importer::Get().GetImportItems(); + ExtImportItem *item = Importer::Get().CreateDefaultImportItem(); items->Add (item); AddItemToTable (RuleTable->GetNumberRows (), item); @@ -568,7 +568,7 @@ void ExtImportPrefs::OnDelRule(wxCommandEvent& WXUNUSED(event)) { if (last_selected < 0) return; - ExtImportItems *items = wxGetApp().mImporter->GetImportItems(); + ExtImportItems *items = Importer::Get().GetImportItems(); int msgres = wxMessageBox (_("Do you really want to delete selected rule?"), _("Rule deletion confirmation"), wxYES_NO, RuleTable); diff --git a/src/toolbars/EditToolBar.cpp b/src/toolbars/EditToolBar.cpp index c81c51b18..b314388d9 100644 --- a/src/toolbars/EditToolBar.cpp +++ b/src/toolbars/EditToolBar.cpp @@ -175,6 +175,12 @@ void EditToolBar::Populate() mButtons[ETBSyncLockID]->PushDown(); #endif +#if defined(EXPERIMENTAL_EFFECTS_RACK) + AddSeparator(); + AddButton(bmpEditEffects, bmpEditEffects, bmpEditEffects, ETBEffectsID, + _("Show Effects Rack"), true); +#endif + RegenerateTooltips(); } @@ -206,6 +212,10 @@ void EditToolBar::RegenerateTooltips() mButtons[ETBZoomOutID]->SetToolTip(_("Zoom Out")); mButtons[ETBZoomSelID]->SetToolTip(_("Fit Selection")); mButtons[ETBZoomFitID]->SetToolTip(_("Fit Project")); + +#if defined(EXPERIMENTAL_EFFECTS_RACK) + mButtons[ETBEffectsID]->SetToolTip(_("Open Effects Rack")); +#endif #endif } @@ -263,6 +273,11 @@ void EditToolBar::OnButton(wxCommandEvent &event) case ETBZoomFitID: p->OnZoomFit(); break; +#if defined(EXPERIMENTAL_EFFECTS_RACK) + case ETBEffectsID: + EffectManager::Get().ShowRack(); + break; +#endif } SetButton(false, mButtons[id]); diff --git a/src/toolbars/EditToolBar.h b/src/toolbars/EditToolBar.h index 33989493d..c0ed3f638 100644 --- a/src/toolbars/EditToolBar.h +++ b/src/toolbars/EditToolBar.h @@ -51,6 +51,10 @@ enum { ETBZoomSelID, ETBZoomFitID, +#if defined(EXPERIMENTAL_EFFECTS_RACK) + ETBEffectsID, +#endif + ETBNumButtons }; diff --git a/src/widgets/AButton.cpp b/src/widgets/AButton.cpp index 1320aacd5..e216ddb06 100644 --- a/src/widgets/AButton.cpp +++ b/src/widgets/AButton.cpp @@ -409,7 +409,7 @@ void AButton::Click() { wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetId()); event.SetEventObject(this); - GetEventHandler()->ProcessEvent(event); + GetEventHandler()->AddPendingEvent(event); } void AButton::SetShift(bool shift) diff --git a/src/widgets/ProgressDialog.cpp b/src/widgets/ProgressDialog.cpp index 59f1b9908..3b27dfdc8 100644 --- a/src/widgets/ProgressDialog.cpp +++ b/src/widgets/ProgressDialog.cpp @@ -1030,7 +1030,7 @@ ProgressDialog::ProgressDialog(const wxString & title, const wxString & message, #if defined(__WXGTK__) // Under GTK, when applying any effect that prompts the user, it's more than - // like that FindFocus() will return NULL. So, make sure something has focus. + // likely that FindFocus() will return NULL. So, make sure something has focus. if (GetParent()) { GetParent()->SetFocus(); } @@ -1245,11 +1245,34 @@ ProgressDialog::~ProgressDialog() } #endif - if (mHadFocus) { + // Restore saved focus, but only if the window still exists. + // + // It is possible that it was a deferred deletion and it was deleted since + // we captured the focused window. So, we need to verify that the window + // still exists by searching all of the wxWidgets windows. It's the only + // sure way. + if (mHadFocus && SearchForWindow(wxTopLevelWindows, mHadFocus)) { mHadFocus->SetFocus(); } } +// +// Recursivaly search the window list for the given window. +// +bool ProgressDialog::SearchForWindow(const wxWindowList & list, const wxWindow *searchfor) +{ + wxWindowList::compatibility_iterator node = list.GetFirst(); + while (node) { + wxWindow *win = node->GetData(); + if (win == searchfor || SearchForWindow(win->GetChildren(), searchfor)) { + return true; + } + node = node->GetNext(); + } + + return false; +} + // // Show/Hide the dialog // diff --git a/src/widgets/ProgressDialog.h b/src/widgets/ProgressDialog.h index 28b3b9315..857109d51 100644 --- a/src/widgets/ProgressDialog.h +++ b/src/widgets/ProgressDialog.h @@ -83,6 +83,8 @@ class AUDACITY_DLL_API ProgressDialog:public wxDialog bool mStop; private: + bool SearchForWindow(const wxWindowList & list, const wxWindow *searchfor); + wxWindow *mHadFocus; wxStaticText *mMessage; wxWindowDisabler *mDisable; diff --git a/win/Projects/Audacity/Audacity.vcxproj b/win/Projects/Audacity/Audacity.vcxproj index ec79a28e3..674fb937a 100755 --- a/win/Projects/Audacity/Audacity.vcxproj +++ b/win/Projects/Audacity/Audacity.vcxproj @@ -92,7 +92,7 @@ MaxSpeed - $(WXWIN)\lib\vc_dll\mswu;$(WXWIN)\include;..\..;..\..\..\lib-src\expat\lib;..\..\..\lib-src\FileDialog;..\..\..\lib-src\FileDialog\win;..\..\..\lib-src\ffmpeg\win32;..\..\..\lib-src\ffmpeg;..\..\..\lib-src\lib-widget-extra;..\..\..\lib-src\libflac\include;..\..\..\lib-src\libid3tag;..\..\..\lib-src\libmad\msvc++;..\..\..\lib-src\libmad;..\..\..\lib-src\libnyquist;..\..\..\lib-src\libogg\include;..\..\..\lib-src\libresample\include;..\..\..\lib-src\libsamplerate\src;..\..\..\lib-src\libscorealign;..\libsndfile;..\..\..\lib-src\libsoxr\src;..\..\..\lib-src\libvamp;..\..\..\lib-src\libvorbis\include;..\..\..\lib-src\portaudio-v19\include;..\..\..\lib-src\portmixer\include;..\..\..\lib-src\portsmf;..\..\..\lib-src\sbsms\include;..\..\..\lib-src\soundtouch\include;..\..\..\lib-src\twolame\libtwolame;..\..\..\lib-src\portmidi\pm_common;..\..\..\lib-src\portmidi\pm_win;..\..\..\lib-src\portmidi\porttime;..\..\..\lib-src\lv2\lilv;..\..\..\lib-src\lv2\lv2;..\..\..\lib-src\lame;$(GSTREAMER_SDK)\include\gstreamer-1.0;$(GSTREAMER_SDK)\include\glib-2.0;$(GSTREAMER_SDK)\lib\glib-2.0\include;%(AdditionalIncludeDirectories) + $(WXWIN)\lib\vc_dll\mswu;$(WXWIN)\include;..\..;..\..\..\include;..\..\..\lib-src\expat\lib;..\..\..\lib-src\FileDialog;..\..\..\lib-src\FileDialog\win;..\..\..\lib-src\ffmpeg\win32;..\..\..\lib-src\ffmpeg;..\..\..\lib-src\lib-widget-extra;..\..\..\lib-src\libflac\include;..\..\..\lib-src\libid3tag;..\..\..\lib-src\libmad\msvc++;..\..\..\lib-src\libmad;..\..\..\lib-src\libnyquist;..\..\..\lib-src\libogg\include;..\..\..\lib-src\libresample\include;..\..\..\lib-src\libsamplerate\src;..\..\..\lib-src\libscorealign;..\libsndfile;..\..\..\lib-src\libsoxr\src;..\..\..\lib-src\libvamp;..\..\..\lib-src\libvorbis\include;..\..\..\lib-src\portaudio-v19\include;..\..\..\lib-src\portmixer\include;..\..\..\lib-src\portsmf;..\..\..\lib-src\sbsms\include;..\..\..\lib-src\soundtouch\include;..\..\..\lib-src\twolame\libtwolame;..\..\..\lib-src\portmidi\pm_common;..\..\..\lib-src\portmidi\pm_win;..\..\..\lib-src\portmidi\porttime;..\..\..\lib-src\lv2\lilv;..\..\..\lib-src\lv2\lv2;..\..\..\lib-src\lame;$(GSTREAMER_SDK)\include\gstreamer-1.0;$(GSTREAMER_SDK)\include\glib-2.0;$(GSTREAMER_SDK)\lib\glib-2.0\include;%(AdditionalIncludeDirectories) BUILDING_AUDACITY;FLAC__NO_DLL;XML_STATIC;__STDC_CONSTANT_MACROS;WXUSINGDLL;__WXMSW__;NDEBUG;WIN32;STRICT;%(PreprocessorDefinitions) true MultiThreadedDLL @@ -123,7 +123,7 @@ MaxSpeed - $(WXWIN3)\lib\vc_dll\mswu;$(WXWIN3)\include;..\..;..\..\..\lib-src\expat\lib;..\..\..\lib-src\FileDialog;..\..\..\lib-src\FileDialog\win;..\..\..\lib-src\ffmpeg\win32;..\..\..\lib-src\ffmpeg;..\..\..\lib-src\lib-widget-extra;..\..\..\lib-src\libflac\include;..\..\..\lib-src\libid3tag;..\..\..\lib-src\libmad\msvc++;..\..\..\lib-src\libmad;..\..\..\lib-src\libnyquist;..\..\..\lib-src\libogg\include;..\..\..\lib-src\libresample\include;..\..\..\lib-src\libsamplerate\src;..\..\..\lib-src\libscorealign;..\libsndfile;..\..\..\lib-src\libsoxr\src;..\..\..\lib-src\libvamp;..\..\..\lib-src\libvorbis\include;..\..\..\lib-src\portaudio-v19\include;..\..\..\lib-src\portmixer\include;..\..\..\lib-src\portsmf;..\..\..\lib-src\sbsms\include;..\..\..\lib-src\soundtouch\include;..\..\..\lib-src\twolame\libtwolame;..\..\..\lib-src\portmidi\pm_common;..\..\..\lib-src\portmidi\pm_win;..\..\..\lib-src\portmidi\porttime;..\..\..\lib-src\lv2\lilv;..\..\..\lib-src\lv2\lv2;..\..\..\lib-src\lame;$(GSTREAMER_SDK)\include\gstreamer-1.0;$(GSTREAMER_SDK)\include\glib-2.0;$(GSTREAMER_SDK)\lib\glib-2.0\include;%(AdditionalIncludeDirectories) + $(WXWIN3)\lib\vc_dll\mswu;$(WXWIN3)\include;..\..;..\..\..\include;..\..\..\lib-src\expat\lib;..\..\..\lib-src\FileDialog;..\..\..\lib-src\FileDialog\win;..\..\..\lib-src\ffmpeg\win32;..\..\..\lib-src\ffmpeg;..\..\..\lib-src\lib-widget-extra;..\..\..\lib-src\libflac\include;..\..\..\lib-src\libid3tag;..\..\..\lib-src\libmad\msvc++;..\..\..\lib-src\libmad;..\..\..\lib-src\libnyquist;..\..\..\lib-src\libogg\include;..\..\..\lib-src\libresample\include;..\..\..\lib-src\libsamplerate\src;..\..\..\lib-src\libscorealign;..\libsndfile;..\..\..\lib-src\libsoxr\src;..\..\..\lib-src\libvamp;..\..\..\lib-src\libvorbis\include;..\..\..\lib-src\portaudio-v19\include;..\..\..\lib-src\portmixer\include;..\..\..\lib-src\portsmf;..\..\..\lib-src\sbsms\include;..\..\..\lib-src\soundtouch\include;..\..\..\lib-src\twolame\libtwolame;..\..\..\lib-src\portmidi\pm_common;..\..\..\lib-src\portmidi\pm_win;..\..\..\lib-src\portmidi\porttime;..\..\..\lib-src\lv2\lilv;..\..\..\lib-src\lv2\lv2;..\..\..\lib-src\lame;$(GSTREAMER_SDK)\include\gstreamer-1.0;$(GSTREAMER_SDK)\include\glib-2.0;$(GSTREAMER_SDK)\lib\glib-2.0\include;%(AdditionalIncludeDirectories) BUILDING_AUDACITY;FLAC__NO_DLL;XML_STATIC;__STDC_CONSTANT_MACROS;WXUSINGDLL;__WXMSW__;NDEBUG;WIN32;STRICT;%(PreprocessorDefinitions) true MultiThreadedDLL @@ -155,7 +155,7 @@ Disabled - $(WXWIN)\lib\vc_dll\mswud;$(WXWIN)\include;..\..;..\..\..\lib-src\expat\lib;..\..\..\lib-src\FileDialog;..\..\..\lib-src\FileDialog\win;..\..\..\lib-src\lib-widget-extra;..\..\..\lib-src\libflac\include;..\..\..\lib-src\libid3tag;..\..\..\lib-src\libmad\msvc++;..\..\..\lib-src\libmad;..\..\..\lib-src\libnyquist;..\..\..\lib-src\libogg\include;..\..\..\lib-src\libresample\include;..\..\..\lib-src\libsamplerate\src;..\..\..\lib-src\libscorealign;..\libsndfile;..\..\..\lib-src\libsoxr\src;..\..\..\lib-src\libvamp;..\..\..\lib-src\libvorbis\include;..\..\..\lib-src\portaudio-v19\include;..\..\..\lib-src\portmixer\include;..\..\..\lib-src\portsmf;..\..\..\lib-src\sbsms\include;..\..\..\lib-src\soundtouch\include;..\..\..\lib-src\twolame\libtwolame;..\..\..\lib-src\portmidi\pm_common;..\..\..\lib-src\portmidi\pm_win;..\..\..\lib-src\portmidi\porttime;..\..\..\lib-src\ffmpeg\win32;..\..\..\lib-src\ffmpeg;..\..\..\lib-src\lv2\lilv;..\..\..\lib-src\lv2\lv2;..\..\..\lib-src\lame;&quot;$(GSTREAMER_SDK)\include\gstreamer-1.0;$(GSTREAMER_SDK)\include\glib-2.0;$(GSTREAMER_SDK)\lib\glib-2.0\include;%(AdditionalIncludeDirectories) + $(WXWIN)\lib\vc_dll\mswud;$(WXWIN)\include;..\..;..\..\..\include;..\..\..\lib-src\expat\lib;..\..\..\lib-src\FileDialog;..\..\..\lib-src\FileDialog\win;..\..\..\lib-src\lib-widget-extra;..\..\..\lib-src\libflac\include;..\..\..\lib-src\libid3tag;..\..\..\lib-src\libmad\msvc++;..\..\..\lib-src\libmad;..\..\..\lib-src\libnyquist;..\..\..\lib-src\libogg\include;..\..\..\lib-src\libresample\include;..\..\..\lib-src\libsamplerate\src;..\..\..\lib-src\libscorealign;..\libsndfile;..\..\..\lib-src\libsoxr\src;..\..\..\lib-src\libvamp;..\..\..\lib-src\libvorbis\include;..\..\..\lib-src\portaudio-v19\include;..\..\..\lib-src\portmixer\include;..\..\..\lib-src\portsmf;..\..\..\lib-src\sbsms\include;..\..\..\lib-src\soundtouch\include;..\..\..\lib-src\twolame\libtwolame;..\..\..\lib-src\portmidi\pm_common;..\..\..\lib-src\portmidi\pm_win;..\..\..\lib-src\portmidi\porttime;..\..\..\lib-src\ffmpeg\win32;..\..\..\lib-src\ffmpeg;..\..\..\lib-src\lv2\lilv;..\..\..\lib-src\lv2\lv2;..\..\..\lib-src\lame;&quot;$(GSTREAMER_SDK)\include\gstreamer-1.0;$(GSTREAMER_SDK)\include\glib-2.0;$(GSTREAMER_SDK)\lib\glib-2.0\include;%(AdditionalIncludeDirectories) BUILDING_AUDACITY;FLAC__NO_DLL;XML_STATIC;__STDC_CONSTANT_MACROS;WXUSINGDLL;__WXMSW__;__WXDEBUG__;_DEBUG;WIN32;STRICT;%(PreprocessorDefinitions) true EnableFastChecks @@ -191,7 +191,7 @@ Disabled - $(WXWIN3)\lib\vc_dll\mswud;$(WXWIN3)\include;..\..;..\..\..\lib-src\expat\lib;..\..\..\lib-src\FileDialog;..\..\..\lib-src\FileDialog\win;..\..\..\lib-src\lib-widget-extra;..\..\..\lib-src\libflac\include;..\..\..\lib-src\libid3tag;..\..\..\lib-src\libmad\msvc++;..\..\..\lib-src\libmad;..\..\..\lib-src\libnyquist;..\..\..\lib-src\libogg\include;..\..\..\lib-src\libresample\include;..\..\..\lib-src\libsamplerate\src;..\..\..\lib-src\libscorealign;..\libsndfile;..\..\..\lib-src\libsoxr\src;..\..\..\lib-src\libvamp;..\..\..\lib-src\libvorbis\include;..\..\..\lib-src\portaudio-v19\include;..\..\..\lib-src\portmixer\include;..\..\..\lib-src\portsmf;..\..\..\lib-src\sbsms\include;..\..\..\lib-src\soundtouch\include;..\..\..\lib-src\twolame\libtwolame;..\..\..\lib-src\portmidi\pm_common;..\..\..\lib-src\portmidi\pm_win;..\..\..\lib-src\portmidi\porttime;..\..\..\lib-src\ffmpeg\win32;..\..\..\lib-src\ffmpeg;..\..\..\lib-src\lv2\lilv;..\..\..\lib-src\lv2\lv2;..\..\..\lib-src\lame;&quot;$(GSTREAMER_SDK)\include\gstreamer-1.0;$(GSTREAMER_SDK)\include\glib-2.0;$(GSTREAMER_SDK)\lib\glib-2.0\include;%(AdditionalIncludeDirectories) + $(WXWIN3)\lib\vc_dll\mswud;$(WXWIN3)\include;..\..;..\..\..\include;..\..\..\lib-src\expat\lib;..\..\..\lib-src\FileDialog;..\..\..\lib-src\FileDialog\win;..\..\..\lib-src\lib-widget-extra;..\..\..\lib-src\libflac\include;..\..\..\lib-src\libid3tag;..\..\..\lib-src\libmad\msvc++;..\..\..\lib-src\libmad;..\..\..\lib-src\libnyquist;..\..\..\lib-src\libogg\include;..\..\..\lib-src\libresample\include;..\..\..\lib-src\libsamplerate\src;..\..\..\lib-src\libscorealign;..\libsndfile;..\..\..\lib-src\libsoxr\src;..\..\..\lib-src\libvamp;..\..\..\lib-src\libvorbis\include;..\..\..\lib-src\portaudio-v19\include;..\..\..\lib-src\portmixer\include;..\..\..\lib-src\portsmf;..\..\..\lib-src\sbsms\include;..\..\..\lib-src\soundtouch\include;..\..\..\lib-src\twolame\libtwolame;..\..\..\lib-src\portmidi\pm_common;..\..\..\lib-src\portmidi\pm_win;..\..\..\lib-src\portmidi\porttime;..\..\..\lib-src\ffmpeg\win32;..\..\..\lib-src\ffmpeg;..\..\..\lib-src\lv2\lilv;..\..\..\lib-src\lv2\lv2;..\..\..\lib-src\lame;&quot;$(GSTREAMER_SDK)\include\gstreamer-1.0;$(GSTREAMER_SDK)\include\glib-2.0;$(GSTREAMER_SDK)\lib\glib-2.0\include;%(AdditionalIncludeDirectories) BUILDING_AUDACITY;FLAC__NO_DLL;XML_STATIC;__STDC_CONSTANT_MACROS;WXUSINGDLL;__WXMSW__;__WXDEBUG__;_DEBUG;WIN32;STRICT;%(PreprocessorDefinitions) true EnableFastChecks @@ -247,6 +247,7 @@ + @@ -268,7 +269,6 @@ - @@ -276,6 +276,7 @@ + @@ -493,6 +494,13 @@ + + + + + + + @@ -508,10 +516,12 @@ + + @@ -537,7 +547,6 @@ - diff --git a/win/Projects/Audacity/Audacity.vcxproj.filters b/win/Projects/Audacity/Audacity.vcxproj.filters index bfac87a1b..d0a3c9642 100755 --- a/win/Projects/Audacity/Audacity.vcxproj.filters +++ b/win/Projects/Audacity/Audacity.vcxproj.filters @@ -61,6 +61,12 @@ {cfbc5496-9828-4c04-8e02-35a5e81cf092} + + {ce332b42-4385-473c-ad9c-f385ea2e6c73} + + + {2bfa6793-371a-4d2e-b3f4-fb033a0c5729} + @@ -165,9 +171,6 @@ src - - src - src @@ -822,6 +825,12 @@ src/import + + src + + + src/effects + @@ -935,9 +944,6 @@ src - - src - src @@ -1616,6 +1622,33 @@ src/import + + includes\audacity + + + includes\audacity + + + includes\audacity + + + includes\audacity + + + includes\audacity + + + includes\audacity + + + includes\audacity + + + src + + + src/effects +